• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 
19 /*********************************************************************************/
20 /*     -------------------------------------------------------------------       */
21 /*                            MPEG-4 Mpeg4File Class                             */
22 /*     -------------------------------------------------------------------       */
23 /*********************************************************************************/
24 /*
25     The Mpeg4File Class is the class that will construct and maintain all the
26     mecessary data structures to be able to render a valid MP4 file to disk.
27     Format.
28 */
29 
30 
31 #define IMPLEMENT_Mpeg4File
32 
33 #include "oscl_int64_utils.h"
34 
35 #ifndef MPEG4FILE_H_INCLUDED
36 #include "mpeg4file.h"
37 #endif
38 
39 #include "atomdefs.h"
40 #include "atomutils.h"
41 #include "filetypeatom.h"
42 #include "oscl_utf8conv.h"
43 #include "oscl_string.h"
44 #include "oscl_snprintf.h"
45 #include "amrdecoderspecificinfo.h"
46 #include "h263decoderspecificinfo.h"
47 #include "media_clock_converter.h"
48 
49 typedef Oscl_Vector<TrackAtom*, OsclMemAllocator> trackAtomVecType;
50 typedef Oscl_Vector<MovieFragmentAtom*, OsclMemAllocator> movieFragmentAtomVecType;
51 typedef Oscl_Vector<uint32, OsclMemAllocator> movieFragmentOffsetVecType;
52 typedef Oscl_Vector<TrackDurationInfo*, OsclMemAllocator> trackDurationInfoVecType;
53 typedef Oscl_Vector<MovieFragmentRandomAccessAtom*, OsclMemAllocator> movieFragmentRandomAccessAtomVecType;
54 
55 // Stream-in Constructor
Mpeg4File(MP4_FF_FILE * fp,OSCL_wString & filename,uint32 parsingMode)56 Mpeg4File::Mpeg4File(MP4_FF_FILE *fp,
57                      OSCL_wString& filename,
58                      uint32 parsingMode)
59 {
60 
61     _pmovieAtom = NULL;
62     _puserDataAtom = NULL;
63     _pFileTypeAtom = NULL;
64     _pMovieFragmentAtom = NULL;
65     _mp4ErrorCode = EVERYTHING_FINE;
66     _isMovieFragmentsPresent = false;
67     _pointerMovieAtomEnd = 0;
68     _movieFragmentFilePtr = NULL;
69     _pMovieFragmentAtomVec = NULL;
70     _pMfraOffsetAtom = NULL;
71     _pMovieFragmentRandomAccessAtomVec = NULL;
72     _pTrackExtendsAtomVec = NULL;
73     _pMoofOffsetVec = NULL;
74     _ptrMoofEnds = 0;
75     _parsing_mode = parsingMode;
76     _pTrackDurationContainer = NULL;
77     oMfraFound = false;
78     _oVideoTrackPresent = false;
79     parseMoofCompletely = true;
80     isResetPlayBackCalled = false;
81 
82     parseMoofCompletely = true;
83     moofParsingCompleted = true;
84     moofSize = 0;
85     moofType = UNKNOWN_ATOM;
86     moofCount = 0;
87     moofPtrPos = 0;
88     currMoofNum = 0;
89     countOfTrunsParsed = 0;
90 
91     // Create miscellaneous vector of atoms
92     PV_MP4_FF_NEW(fp->auditCB, trackAtomVecType, (), _pTrackAtomVec);
93     PV_MP4_FF_NEW(fp->auditCB, movieFragmentAtomVecType, (), _pMovieFragmentAtomVec);
94     PV_MP4_FF_NEW(fp->auditCB, movieFragmentOffsetVecType, (), _pMoofOffsetVec);
95     PV_MP4_FF_NEW(fp->auditCB, movieFragmentRandomAccessAtomVecType, (), _pMovieFragmentRandomAccessAtomVec);
96     PV_MP4_FF_NEW(fp->auditCB, PVID3ParCom, (), _pID3Parser);
97 
98 
99     iLogger = PVLogger::GetLoggerObject("mp4ffparser");
100     iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
101     iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
102 
103     _success = true; // Initial state
104 
105     int32 fileSize;
106     int32 filePointer;
107     filePointer = AtomUtils::getCurrentFilePosition(fp);
108     uint32 fsize = 0;
109     AtomUtils::getCurrentFileSize(fp, fsize);
110     fileSize = (int32)fsize;
111 
112     _oPVContent = false;
113     _oPVContentDownloadable = false;
114     _commonFilePtr = NULL;
115     _fileSize = fsize;
116 
117     int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
118 
119     //top level moov, mdat, udat
120     while (count > 0)
121     {
122         // Read in atoms until reach end of file
123         //there is a case that next atom is valid, but not in top level
124         //so only check top level now
125         uint32 atomType = UNKNOWN_ATOM;
126         uint32 atomSize = 0;
127 
128         AtomUtils::getNextAtomType(fp, atomSize, atomType);
129 
130         if ((atomType == SKIP_ATOM)
131                 || (atomType == FREE_SPACE_ATOM)
132                 || (atomType == UUID_ATOM)
133                 || (atomType == UNKNOWN_ATOM)
134                 || (atomType == MEDIA_DATA_ATOM))
135         {
136             if (atomSize == 1)
137             {
138                 uint64 largeSize = 0;
139                 AtomUtils::read64(fp, largeSize);
140                 uint32 size =
141                     Oscl_Int64_Utils::get_uint64_lower32(largeSize);
142                 count -= size;
143                 size -= 8; //for large size
144                 size -= DEFAULT_ATOM_SIZE;
145                 AtomUtils::seekFromCurrPos(fp, size);
146             }
147             else
148             {
149                 if (atomSize < DEFAULT_ATOM_SIZE)
150                 {
151                     _success = false;
152                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
153                     break;
154                 }
155                 if (count < (int32)atomSize)
156                 {
157                     _success = false;
158                     _mp4ErrorCode = READ_FAILED;
159                     break;
160                 }
161                 count -= atomSize;
162                 atomSize -= DEFAULT_ATOM_SIZE;
163                 AtomUtils::seekFromCurrPos(fp, atomSize);
164             }
165         }
166         else if (atomType == USER_DATA_ATOM)
167         {
168             //"udta"
169             // Check for 'pvmm' to see if it is "our" 'udta' atom
170 
171             uint32 isPVMMAtom = AtomUtils::peekNextNthBytes(fp, 2);
172 
173             if (isPVMMAtom == PVUSER_DATA_ATOM)
174             {
175                 if (_puserDataAtom == NULL)
176                 {
177                     PV_MP4_FF_NEW(fp->auditCB, UserDataAtom, (fp, atomSize, atomType), _puserDataAtom);
178                     _oPVContent = true;
179                     uint32 contentType = getContentType();
180                     if (contentType == DEFAULT_AUTHORING_MODE)
181                     {
182                         _oPVContentDownloadable = true;
183                     }
184                     count -= _puserDataAtom->getSize();
185                 }
186                 else
187                 {
188                     _success = false;
189                     _mp4ErrorCode = READ_USER_DATA_ATOM_FAILED;
190                     break;
191                 }
192             }
193             else
194             {
195                 // Skip third party user data atom
196                 if (atomSize < DEFAULT_ATOM_SIZE)
197                 {
198                     _success = false;
199                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
200                     break;
201                 }
202                 if (count < (int32)atomSize)
203                 {
204                     _success = false;
205                     _mp4ErrorCode = READ_FAILED;
206                     break;
207                 }
208                 count -= atomSize;
209                 atomSize -= DEFAULT_ATOM_SIZE;
210                 AtomUtils::seekFromCurrPos(fp, atomSize);
211             }
212 
213 
214         }
215         else if (atomType == FILE_TYPE_ATOM)
216         {
217             if (_pFileTypeAtom == NULL)
218             {
219                 //"ftyp"
220                 PV_MP4_FF_NEW(fp->auditCB, FileTypeAtom, (fp, atomSize, atomType), _pFileTypeAtom);
221 
222                 if (!_pFileTypeAtom->MP4Success())
223                 {
224                     _success = false;
225                     _mp4ErrorCode = READ_FILE_TYPE_ATOM_FAILED;
226                     break;
227                 }
228 
229                 uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
230                 uint32  majorBrandInfo = ENoFileType;
231                 uint32  compatibleBrandInfo = ENoFileType;
232 
233 
234                 switch (majorBrand)
235                 {
236                     case WMF_BRAND:
237                         majorBrandInfo |= EWMF;
238                         break;
239 
240                     case BRAND_3GPP4:
241                         majorBrandInfo |= E3GP4;
242                         break;
243 
244                     case BRAND_3GPP5:
245                         majorBrandInfo |= E3GP5;
246                         break;
247 
248                     case MOBILE_MP4:
249                         majorBrandInfo |= EMMP4;
250                         break;
251 
252                     case BRAND_MP41:
253                         majorBrandInfo |= EMP41;
254                         break;
255 
256                     case BRAND_MP42:
257                         majorBrandInfo |= EMP42;
258                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
259                         break;
260 
261                     case BRAND_ISOM:
262                         majorBrandInfo |= EISOM;
263                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
264                         break;
265 
266                     default:
267                         majorBrandInfo |= EUNKNOWN_TYPE;
268                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
269                         break;
270                 }
271 
272                 Oscl_Vector<uint32, OsclMemAllocator> *compatibleBrandArray =
273                     _pFileTypeAtom->getCompatibleBrand();
274 
275                 if (compatibleBrandArray != NULL)
276                 {
277                     for (uint32 i = 0; i < compatibleBrandArray->size(); i++)
278                     {
279                         uint32 compatibleBrand = (*compatibleBrandArray)[i];
280 
281                         switch (compatibleBrand)
282                         {
283                             case WMF_BRAND:
284                                 compatibleBrandInfo |= EWMF;
285                                 break;
286 
287                             case BRAND_3GPP4:
288                                 compatibleBrandInfo |= E3GP4;
289                                 break;
290 
291                             case BRAND_3GPP5:
292                                 compatibleBrandInfo |= E3GP5;
293                                 break;
294 
295                             case MOBILE_MP4:
296                                 compatibleBrandInfo |= EMMP4;
297                                 break;
298 
299                             case BRAND_MP41:
300                                 compatibleBrandInfo |= EMP41;
301                                 break;
302 
303                             case BRAND_MP42:
304                                 compatibleBrandInfo |= EMP42;
305                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
306                                 break;
307 
308                             case BRAND_ISOM:
309                                 compatibleBrandInfo |= EISOM;
310                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
311                                 break;
312 
313                             default:
314                                 compatibleBrandInfo |= EUNKNOWN_TYPE;
315                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
316                                 break;
317                         }
318                     }
319                 }
320 
321                 count -= _pFileTypeAtom->getSize();
322             }
323             else
324             {
325                 //multiple "ftyp" atom not allowed.skipping
326                 count -= atomSize;
327                 atomSize -= DEFAULT_ATOM_SIZE;
328                 AtomUtils::seekFromCurrPos(fp, atomSize);
329             }
330         }
331         else if (atomType == MOVIE_ATOM)
332         {
333 
334 
335             //"moov"
336             if (_pmovieAtom == NULL)
337             {
338                 // Only 1 movie atom allowed!
339                 PV_MP4_FF_NEW(fp->auditCB, MovieAtom,
340                               (fp,
341                                filename,
342                                atomSize,
343                                atomType,
344                                _oPVContent,
345                                _oPVContentDownloadable,
346                                parsingMode
347                               ),
348                               _pmovieAtom);
349 
350                 if (!_pmovieAtom->MP4Success())
351                 {
352                     _success = false;
353                     _mp4ErrorCode = _pmovieAtom->GetMP4Error();
354                     break;
355                 }
356                 _isMovieFragmentsPresent = _pmovieAtom->IsMovieFragmentPresent();
357                 populateTrackDurationVec();
358                 _pTrackExtendsAtomVec = _pmovieAtom->getTrackExtendsAtomVec();
359 
360                 if (_isMovieFragmentsPresent)
361                 {
362                     atomSize -= DEFAULT_ATOM_SIZE;
363                     _pointerMovieAtomEnd =  AtomUtils::getCurrentFilePosition(fp);
364                     _ptrMoofEnds = _pointerMovieAtomEnd;
365                     OsclAny*ptr = oscl_malloc(sizeof(MP4_FF_FILE));
366                     if (ptr == NULL)
367                     {
368                         _success = false;
369                         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
370                         return;
371                     }
372                     _movieFragmentFilePtr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE(*fp));
373                     _movieFragmentFilePtr ->_pvfile.Copy(fp->_pvfile);
374                     _movieFragmentFilePtr ->_pvfile.SetCPM(fp->_pvfile.GetCPM());
375                 }
376                 count -= _pmovieAtom->getSize();
377                 _scalability = _pmovieAtom->getScalability();
378                 _fileType    = _pmovieAtom->getFileType();
379 
380                 if (parsingMode != 0)
381                 {
382                     if (_isMovieFragmentsPresent)
383                     {
384                         parseMFRA();
385                     }
386                     break;
387                 }
388                 if (!_isMovieFragmentsPresent)
389                 {
390                     //no moofs, exit the parsing loop since
391                     //we are done parsing the moov atom
392                     break;
393                 }
394 
395 
396             }
397             else
398             { //after the change above, we will never hit here.
399                 _success = false;
400                 _mp4ErrorCode = DUPLICATE_MOVIE_ATOMS;
401                 break;
402             }
403         }
404         else if (atomType == MOVIE_FRAGMENT_ATOM)
405         {
406             uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(fp);
407             moofStartOffset -= DEFAULT_ATOM_SIZE;
408             _pMoofOffsetVec->push_back(moofStartOffset);
409 
410             MovieFragmentAtom *pMovieFragmentAtom = NULL;
411             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentAtom, (fp, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), pMovieFragmentAtom);
412 
413             if (!pMovieFragmentAtom->MP4Success())
414             {
415                 _success = false;
416                 _mp4ErrorCode = pMovieFragmentAtom->GetMP4Error();
417                 break;
418             }
419             pMovieFragmentAtom->setParent(this);
420             count -= pMovieFragmentAtom->getSize();
421             _ptrMoofEnds = AtomUtils::getCurrentFilePosition(fp);
422             _pMovieFragmentAtomVec->push_back(pMovieFragmentAtom);
423         }
424         else if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_ATOM)
425         {
426             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = NULL;
427             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentRandomAccessAtom, (fp, atomSize, atomType), pMovieFragmentRandomAccessAtom);
428 
429             if (!pMovieFragmentRandomAccessAtom->MP4Success())
430             {
431                 _success = false;
432                 _mp4ErrorCode = pMovieFragmentRandomAccessAtom->GetMP4Error();
433                 break;
434             }
435             pMovieFragmentRandomAccessAtom->setParent(this);
436             count -= pMovieFragmentRandomAccessAtom->getSize();
437             _pMovieFragmentRandomAccessAtomVec->push_back(pMovieFragmentRandomAccessAtom);
438             oMfraFound = true;
439         }
440         else
441         {
442             if (count > 0)
443             {
444                 _mp4ErrorCode = READ_UNKNOWN_ATOM;
445                 _success = false;
446             }
447             break;
448         }
449     }
450 
451     if (_success)
452     {
453         // Check that the movie atom was in fact read in
454         if (_pmovieAtom == NULL)
455         {
456             _success = false;
457             _mp4ErrorCode = NO_MOVIE_ATOM_PRESENT;
458         }
459         else
460         {
461             // CHECK IF THERE ARE ANY VALID MEDIA TRACKS IN THE FILE
462             int32 numMediaTracks = getNumTracks();
463             if (numMediaTracks == 0)
464             {
465                 _success = false;
466                 _mp4ErrorCode = NO_META_DATA_FOR_MEDIA_TRACKS;
467             }
468             if (_success)
469             {
470                 uint32 bufferCapacity = AtomUtils::getFileBufferingCapacity(fp);
471                 if (0 != bufferCapacity)
472                 {
473                     // progressive playback
474                     int32* offsetList = (int32 *)oscl_malloc(sizeof(int32) * numMediaTracks);
475                     if (NULL == offsetList)
476                     {
477                         _success = false;
478                         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
479                     }
480                     else
481                     {
482                         // get the list of track ids
483                         uint32* idList = (uint32 *)oscl_malloc(sizeof(uint32) * numMediaTracks);
484                         _pmovieAtom->getTrackIDList(idList, numMediaTracks);
485 
486                         // get the first sample file offset of each track
487                         for (int32 i = 0; i < numMediaTracks; i++)
488                         {
489                             int32 retVal = _pmovieAtom->getOffsetByTime(idList[i], 0, &offsetList[i]);
490                             if (EVERYTHING_FINE != retVal)
491                             {
492                                 _success = false;
493                                 _mp4ErrorCode = retVal;
494                                 break;
495                             }
496                         }
497                         // check if any of the two offsets are too far apart
498                         // to coexist in the cache at the same time
499                         if (_success)
500                         {
501                             uint32 largest = 0, temp = 0;
502                             for (int i = 0; i < numMediaTracks; i++)
503                             {
504                                 for (int j = 0; j < numMediaTracks; j++)
505                                 {
506                                     // same as abs()
507                                     if (offsetList[i] > offsetList[j])
508                                     {
509                                         temp = offsetList[i] - offsetList[j];
510                                     }
511                                     else
512                                     {
513                                         temp = offsetList[j] - offsetList[i];
514                                     }
515 
516                                     if (temp > largest)
517                                     {
518                                         largest = temp;
519                                     }
520                                 }
521                             }
522 
523                             if (largest > bufferCapacity)
524                             {
525                                 // the samples are not interleaved properly
526                                 // this clip is not authored for progressive playback
527                                 _success = false;
528                                 _mp4ErrorCode = INSUFFICIENT_BUFFER_SIZE;
529                             }
530                         }
531 
532                         oscl_free(idList);
533                     }
534 
535                     oscl_free(offsetList);
536                 }
537             }
538         }
539     }
540 
541 
542     // Check for any atoms that may have read past the EOF that were not
543     // already caught by any earlier error handling
544 
545     if (filePointer > fileSize)
546     {
547         _mp4ErrorCode = READ_FAILED; // Read past EOF
548         _success = false;
549     }
550 
551     // skip ID3 tag parsing for progressive playback for now
552     uint32 bufferCapacity = AtomUtils::getFileBufferingCapacity(fp);
553     if (0 == bufferCapacity)
554     {
555         parseID3Header(fp);
556     }
557     //Populate the title vector with all the title metadata values.
558     if (!populateMetadataVectors())
559     {
560         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::populateTitleVector() Failed"));
561     }
562 
563 }
564 
565 
populateMetadataVectors()566 PVMFStatus Mpeg4File::populateMetadataVectors()
567 {
568     if ((!populateTitleVector()) || (!populateAuthorVector() ||
569                                      (!populateAlbumVector()) ||
570                                      (!populateArtistVector()) || (!populateGenreVector()) ||
571                                      (!populateYearVector()) || (!populateCopyrightVector()) ||
572                                      (!populateCommentVector()) || (!populateDescriptionVector()) ||
573                                      (!populateRatingVector()))
574        )
575     {
576         return PVMFFailure;
577     }
578 
579     return PVMFSuccess;
580 }
581 
getNumTitle()582 uint32 Mpeg4File::getNumTitle()
583 {
584     uint32 numTitle = 0;
585     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
586     numTitle = getNumAssetInfoTitleAtoms();
587     if (getPVTitle(chartype).get_size() > 0)
588     {
589         numTitle++;
590     }
591     if (getITunesTitle().get_size() > 0)
592     {
593         numTitle++;
594     }
595     PvmiKvpSharedPtrVector framevector;
596     GetID3MetaData(framevector);
597     uint32 num_frames = framevector.size();
598     for (uint32 i = 0; i < num_frames; i++)
599     {
600         if (framevector.size() > 0)
601         {
602             if (oscl_strstr(framevector[i]->key, "title") != 0)
603             {
604                 numTitle++;
605                 break;
606             }
607         }
608     }
609     return numTitle;
610 }
611 
612 //This function populates the Title Vector with values from Asset Info, Itunes, FullMusic and PV Proprietary Atoms.
populateTitleVector()613 PVMFStatus Mpeg4File::populateTitleVector()
614 {
615     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
616     int32 numTitle = getNumTitle();
617     ReserveMemoryForValuesVector(titleValues, numTitle, leavecode);
618     ReserveMemoryForLangCodeVector(iTitleLangCode, numTitle, leavecode1);
619     OSCL_TRY(leavecode2, iTitleCharType.reserve(numTitle));
620     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
621     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
622     {
623         return PVMFFailure;
624     }
625     int32 numAssetInfoTitle = getNumAssetInfoTitleAtoms();
626 
627 
628     if (numAssetInfoTitle > 0)
629     {
630         for (int32 i = 0; i < numAssetInfoTitle; i++)
631         {
632             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoTitleNotice(charType, i);
633 
634             titleValues.push_front(valuestring);
635             iTitleLangCode.push_front(getAssetInfoTitleLangCode(i));
636             iTitleCharType.push_front(charType);
637         }
638     }
639     if (getPVTitle(charType).get_size() > 0)
640     {
641         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVTitle(charType);
642         titleValues.push_front(valuestring);
643         iTitleLangCode.push_front(0);
644         iTitleCharType.push_front(charType);
645     }
646     if (getITunesTitle().get_size() > 0)
647     {
648         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesTitle();
649         titleValues.push_front(valuestring);
650         iTitleLangCode.push_front(0);
651         iTitleCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
652     }
653     PvmiKvpSharedPtrVector framevector;
654     GetID3MetaData(framevector);
655     uint32 num_frames = framevector.size();
656     for (uint32 i = 0; i < num_frames; i++)
657     {
658         if (framevector.size() > 0)
659         {
660             if (oscl_strstr(framevector[i]->key, "title") != 0)
661             {
662                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
663                 oscl_memset(_id3v1Title, 0, ID3V1_STR_MAX_SIZE);
664                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Title, len*2 + 2);
665                 titleValues.push_front(_id3v1Title);
666                 iTitleLangCode.push_front(0);
667                 iTitleCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
668                 break;
669             }
670         }
671     }
672     return PVMFSuccess;
673 }
674 
675 // This function returns the titles based on index value, to the parser node.
getTitle(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)676 PVMFStatus Mpeg4File::getTitle(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
677 {
678     if (index < titleValues.size())
679     {
680         aVal = NULL;
681         aLangCode = 0;
682         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
683         aVal = titleValues[index].get_cstr();
684         aLangCode = iTitleLangCode[index];
685         aCharEncType = iTitleCharType[index];
686         return PVMFSuccess;
687     }
688     return PVMFErrArgument;
689 }
690 
getNumAuthor()691 uint32 Mpeg4File::getNumAuthor()
692 {
693     uint32 numAuthor = 0;
694     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
695     numAuthor = getNumAssetInfoAuthorAtoms();
696 
697     if (getPVAuthor(chartype).get_size() > 0)
698     {
699         numAuthor++;
700     }
701     return numAuthor;
702 }
703 
704 //This function populates the Author Vector with values from Asset Info and PV Proprietary Atoms.
populateAuthorVector()705 PVMFStatus Mpeg4File::populateAuthorVector()
706 {
707     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
708     int32 numAuthor = getNumAuthor();
709     ReserveMemoryForValuesVector(authorValues, numAuthor, leavecode);
710     ReserveMemoryForLangCodeVector(iAuthorLangCode, numAuthor, leavecode1);
711     OSCL_TRY(leavecode2, iAuthorCharType.reserve(numAuthor));
712     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
713     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
714     {
715         return PVMFFailure;
716     }
717     int32 numAssetInfoAuthor = getNumAssetInfoAuthorAtoms();
718     if (numAssetInfoAuthor > 0)
719     {
720         for (int32 i = 0; i < numAssetInfoAuthor; i++)
721         {
722             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoAuthorNotice(charType, i);
723             authorValues.push_front(valuestring);
724             iAuthorLangCode.push_front(getAssetInfoAuthorLangCode(i));
725             iAuthorCharType.push_front(charType);
726         }
727     }
728     if (getPVAuthor(charType).get_size() > 0)
729     {
730         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVAuthor(charType);
731         authorValues.push_front(valuestring);
732         iAuthorLangCode.push_front(0);
733         iAuthorCharType.push_front(charType);
734     }
735     return PVMFSuccess;
736 }
737 
738 // This function returns the Author based on index value, to the parser node.
getAuthor(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)739 PVMFStatus Mpeg4File::getAuthor(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
740 {
741     if (index < authorValues.size())
742     {
743         aVal = NULL;
744         aLangCode = 0;
745         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
746         aVal = authorValues[index].get_cstr();
747         aLangCode = iAuthorLangCode[index];
748         aCharEncType = iAuthorCharType[index];
749         return PVMFSuccess;
750     }
751     return PVMFErrArgument;
752 }
753 
getNumAlbum()754 uint32 Mpeg4File::getNumAlbum()
755 {
756     uint32 numAlbum = 0;
757     numAlbum = getNumAssetInfoAlbumAtoms();
758     if (getITunesAlbum().get_size() > 0)
759     {
760         numAlbum++;
761     }
762     PvmiKvpSharedPtrVector framevector;
763     GetID3MetaData(framevector);
764     uint32 num_frames = framevector.size();
765     for (uint32 i = 0; i < num_frames; i++)
766     {
767         if (framevector.size() > 0)
768         {
769             if (oscl_strstr(framevector[i]->key, "album") != 0)
770             {
771                 numAlbum++;
772                 break;
773             }
774         }
775     }
776     return numAlbum;
777 }
778 
779 //This function populates the Album Vector with values from Asset Info, Itunes, FullMusic Atoms.
populateAlbumVector()780 PVMFStatus Mpeg4File::populateAlbumVector()
781 {
782     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
783     int32 numAlbum = getNumAlbum();
784     ReserveMemoryForValuesVector(albumValues, numAlbum, leavecode);
785     ReserveMemoryForLangCodeVector(iAlbumLangCode, numAlbum, leavecode1);
786     OSCL_TRY(leavecode2, iAlbumCharType.reserve(numAlbum));
787     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
788     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
789     {
790         return PVMFFailure;
791     }
792     int32 numAssetInfoAlbum = getNumAssetInfoAlbumAtoms();
793     if (numAssetInfoAlbum > 0)
794     {
795         for (int32 i = 0; i < numAssetInfoAlbum; i++)
796         {
797             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoAlbumNotice(charType, i);
798             albumValues.push_front(valuestring);
799             iAlbumLangCode.push_front(getAssetInfoAlbumLangCode(i));
800             iAlbumCharType.push_front(charType);
801         }
802     }
803     if (getITunesAlbum().get_size() > 0)
804     {
805         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesAlbum();
806         albumValues.push_front(valuestring);
807         iAlbumLangCode.push_front(0);
808         iAlbumCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
809     }
810     PvmiKvpSharedPtrVector framevector;
811     GetID3MetaData(framevector);
812     uint32 num_frames = framevector.size();
813     for (uint32 i = 0; i < num_frames; i++)
814     {
815         if (framevector.size() > 0)
816         {
817             if (oscl_strstr(framevector[i]->key, "album") != 0)
818             {
819                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
820                 oscl_memset(_id3v1Album, 0, ID3V1_STR_MAX_SIZE);
821                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Album, len*2 + 2);
822                 albumValues.push_front(_id3v1Album);
823                 iAlbumLangCode.push_front(0);
824                 iAlbumCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
825                 break;
826             }
827         }
828     }
829 
830     return PVMFSuccess;
831 }
832 
833 // This function returns the Album based on index value, to the parser node.
getAlbum(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)834 PVMFStatus Mpeg4File::getAlbum(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
835 {
836     if (index < albumValues.size())
837     {
838         aVal = NULL;
839         aLangCode = 0;
840         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
841         aVal = albumValues[index].get_cstr();
842         aLangCode = iAlbumLangCode[index];
843         aCharEncType = iAlbumCharType[index];
844         return PVMFSuccess;
845     }
846     return PVMFErrArgument;
847 }
848 
getNumArtist()849 uint32 Mpeg4File::getNumArtist()
850 {
851     uint32 numArtist = 0;
852     numArtist = getNumAssetInfoPerformerAtoms();
853 
854     if (getITunesArtist().get_size() > 0)
855     {
856         numArtist++;
857     }
858     if (getITunesAlbumArtist().get_size() > 0) //AlbumArtist
859     {
860         numArtist++;
861     }
862 
863     PvmiKvpSharedPtrVector framevector;
864     GetID3MetaData(framevector);
865     uint32 num_frames = framevector.size();
866     for (uint32 i = 0; i < num_frames; i++)
867     {
868         if (framevector.size() > 0)
869         {
870             if (oscl_strstr(framevector[i]->key, "artist") != 0)
871             {
872                 numArtist++;
873                 break;
874             }
875         }
876     }
877     return numArtist;
878 }
879 
880 
881 //This function populates the Artist Vector with values from Asset Info, Itunes, FullMusic Atoms.
populateArtistVector()882 PVMFStatus Mpeg4File::populateArtistVector()
883 {
884     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
885     int32 numArtist = getNumArtist();
886     ReserveMemoryForValuesVector(artistValues, numArtist, leavecode);
887     ReserveMemoryForLangCodeVector(iArtistLangCode, numArtist, leavecode1);
888     OSCL_TRY(leavecode2, iArtistCharType.reserve(numArtist));
889     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
890     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
891     {
892         return PVMFFailure;
893     }
894     int32 numAssetInfoPerformer = getNumAssetInfoPerformerAtoms();
895     if (numAssetInfoPerformer > 0)
896     {
897         for (int32 i = 0; i < numAssetInfoPerformer; i++)
898         {
899             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoPerformerNotice(charType, i);
900             artistValues.push_front(valuestring);
901             iArtistLangCode.push_front(getAssetInfoPerformerLangCode(i));
902             iArtistCharType.push_front(charType);
903         }
904     }
905     if (getITunesArtist().get_size() > 0)
906     {
907         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesArtist();
908         artistValues.push_front(valuestring);
909         iArtistLangCode.push_front(0);
910         iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
911     }
912     if (getITunesAlbumArtist().get_size() > 0) //AlbumArtist
913     {
914         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesAlbumArtist();
915         artistValues.push_front(valuestring);
916         iArtistLangCode.push_front(0);
917         iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
918     }
919     PvmiKvpSharedPtrVector framevector;
920     GetID3MetaData(framevector);
921     uint32 num_frames = framevector.size();
922     for (uint32 i = 0; i < num_frames; i++)
923     {
924         if (framevector.size() > 0)
925         {
926             if (oscl_strstr(framevector[i]->key, "artist") != 0)
927             {
928                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
929                 oscl_memset(_id3v1Artist, 0, ID3V1_STR_MAX_SIZE);
930                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Artist, len*2 + 2);
931                 artistValues.push_front(_id3v1Artist);
932                 iArtistLangCode.push_front(0);
933                 iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
934                 break;
935             }
936         }
937     }
938     return PVMFSuccess;
939 }
940 
941 // This function returns the Artists based on index value, to the parser node.
getArtist(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)942 PVMFStatus Mpeg4File::getArtist(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
943 {
944     if (index < artistValues.size())
945     {
946         aVal = NULL;
947         aLangCode = 0;
948         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
949         aVal = artistValues[index].get_cstr();
950         aLangCode = iArtistLangCode[index];
951         aCharEncType = iArtistCharType[index];
952         return PVMFSuccess;
953     }
954     return PVMFErrArgument;
955 }
956 
getNumGenre()957 uint32 Mpeg4File::getNumGenre()
958 {
959     uint32 numGenre = 0;
960     numGenre = getNumAssetInfoGenreAtoms();
961 
962     if (getITunesGnreString().get_size() > 0)
963     {
964         numGenre++;
965     }
966     if (getITunesGnreID() > 0)
967     {
968         numGenre++;
969     }
970     return numGenre;
971 }
972 
973 //This function populates the Genre Vector with values from Asset Info, Itunes, FullMusic Atoms.
populateGenreVector()974 PVMFStatus Mpeg4File::populateGenreVector()
975 {
976     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
977     int32 numGenre = getNumGenre();
978     ReserveMemoryForValuesVector(genreValues, numGenre, leavecode);
979     ReserveMemoryForLangCodeVector(iGenreLangCode, numGenre, leavecode1);
980     OSCL_TRY(leavecode2, iGenreCharType.reserve(numGenre));
981     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
982     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
983     {
984         return PVMFFailure;
985     }
986     int32 numAssetInfoGenre = getNumAssetInfoGenreAtoms();
987     if (numAssetInfoGenre > 0)
988     {
989         for (int32 i = 0; i < numAssetInfoGenre; i++)
990         {
991             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoGenreNotice(charType, i);
992             genreValues.push_front(valuestring);
993             iGenreLangCode.push_front(getAssetInfoGenreLangCode(i));
994             iGenreCharType.push_front(charType);
995         }
996     }
997     if (getITunesGnreString().get_size() > 0)
998     {
999         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesGnreString();
1000         genreValues.push_front(valuestring);
1001         iGenreLangCode.push_front(0);
1002         iGenreCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
1003     }
1004     return PVMFSuccess;
1005 }
1006 
1007 // This function returns the Genres based on index value, to the parser node.
getGenre(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)1008 PVMFStatus Mpeg4File::getGenre(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
1009 {
1010     if (index < genreValues.size())
1011     {
1012         aVal = NULL;
1013         aLangCode = 0;
1014         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1015         aVal = genreValues[index].get_cstr();
1016         aLangCode = iGenreLangCode[index];
1017         aCharEncType = iGenreCharType[index];
1018         return PVMFSuccess;
1019     }
1020     return PVMFErrArgument;
1021 }
1022 
1023 
getNumCopyright()1024 uint32 Mpeg4File::getNumCopyright()
1025 {
1026     uint32 numCopyright = 0;
1027     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
1028     numCopyright = getNumCopyRightAtoms();
1029     if (getPVCopyright(chartype).get_size() > 0)
1030     {
1031         numCopyright++;
1032     }
1033     if (getITunesCopyright().get_size() > 0)
1034     {
1035         numCopyright++;
1036     }
1037     return numCopyright;
1038 }
1039 
1040 
1041 //This function populates the Copyright Vector with values from Asset Info, Itunes and PV Proprietary Atoms.
populateCopyrightVector()1042 PVMFStatus Mpeg4File::populateCopyrightVector()
1043 {
1044     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
1045     int32 numCopyright = getNumCopyright();
1046     ReserveMemoryForValuesVector(copyrightValues, numCopyright, leavecode);
1047     ReserveMemoryForLangCodeVector(iCopyrightLangCode, numCopyright, leavecode1);
1048     OSCL_TRY(leavecode2, iCopyrightCharType.reserve(numCopyright));
1049     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1050     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
1051     {
1052         return PVMFFailure;
1053     }
1054     int32 numAssetInfoCopyright = getNumCopyRightAtoms();
1055     if (numAssetInfoCopyright > 0)
1056     {
1057         for (int32 i = 0; i < numAssetInfoCopyright; i++)
1058         {
1059             OSCL_wHeapString<OsclMemAllocator> valuestring = getCopyRightString(charType, i);
1060             copyrightValues.push_front(valuestring);
1061             iCopyrightLangCode.push_front(getCopyRightLanguageCode(i));
1062             iCopyrightCharType.push_front(charType);
1063         }
1064     }
1065     if (getPVCopyright(charType).get_size() > 0)
1066     {
1067         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVCopyright(charType);
1068         copyrightValues.push_front(valuestring);
1069         iCopyrightLangCode.push_front(0);
1070         iCopyrightCharType.push_front(charType);
1071     }
1072     if (getITunesCopyright().get_size() > 0)
1073     {
1074         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesCopyright();
1075         copyrightValues.push_front(valuestring);
1076         iCopyrightLangCode.push_front(0);
1077         iCopyrightCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
1078     }
1079     return PVMFSuccess;
1080 }
1081 
1082 // This function returns the Copyrights based on index value, to the parser node.
getCopyright(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)1083 PVMFStatus Mpeg4File::getCopyright(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
1084 {
1085     if (index < copyrightValues.size())
1086     {
1087         aVal = NULL;
1088         aLangCode = 0;
1089         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1090         aVal = copyrightValues[index].get_cstr();
1091         aLangCode = iCopyrightLangCode[index];
1092         aCharEncType = iCopyrightCharType[index];
1093         return PVMFSuccess;
1094     }
1095     return PVMFErrArgument;
1096 }
1097 
1098 
getNumComment()1099 uint32 Mpeg4File::getNumComment()
1100 {
1101     uint32 numComment = 0;
1102 
1103 
1104     if (getITunesComment().get_size() > 0)
1105     {
1106         numComment++;
1107     }
1108     PvmiKvpSharedPtrVector framevector;
1109     GetID3MetaData(framevector);
1110     uint32 num_frames = framevector.size();
1111     for (uint32 i = 0; i < num_frames; i++)
1112     {
1113         if (framevector.size() > 0)
1114         {
1115             if (oscl_strstr(framevector[i]->key, "comment") != 0)
1116             {
1117                 numComment++;
1118                 break;
1119             }
1120         }
1121     }
1122 
1123     return numComment;
1124 }
1125 
1126 
1127 //This function populates the Comment Vector with values from Itunes, FullMusic Atoms.
populateCommentVector()1128 PVMFStatus Mpeg4File::populateCommentVector()
1129 {
1130     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
1131     int32 numComment = getNumComment();
1132     ReserveMemoryForValuesVector(commentValues, numComment, leavecode);
1133     ReserveMemoryForLangCodeVector(iCommentLangCode, numComment, leavecode1);
1134     OSCL_TRY(leavecode2, iCommentCharType.reserve(numComment));
1135     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
1136     {
1137         return PVMFFailure;
1138     }
1139 
1140     if (getITunesComment().get_size() > 0)
1141     {
1142         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesComment();
1143         commentValues.push_front(valuestring);
1144         iCommentLangCode.push_front(0);
1145         iCommentCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
1146     }
1147     PvmiKvpSharedPtrVector framevector;
1148     GetID3MetaData(framevector);
1149     uint32 num_frames = framevector.size();
1150     for (uint32 i = 0; i < num_frames; i++)
1151     {
1152         if (framevector.size() > 0)
1153         {
1154             if (oscl_strstr(framevector[i]->key, "comment") != 0)
1155             {
1156                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
1157                 oscl_memset(_id3v1Comment, 0, ID3V1_STR_MAX_SIZE);
1158                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Comment, len*2 + 2);
1159                 commentValues.push_front(_id3v1Comment);
1160                 iCommentLangCode.push_front(0);
1161                 iCommentCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
1162                 break;
1163             }
1164         }
1165     }
1166 
1167     return PVMFSuccess;
1168 }
1169 
1170 // This function returns the Comments based on index value, to the parser node.
getComment(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)1171 PVMFStatus Mpeg4File::getComment(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
1172 {
1173     if (index < commentValues.size())
1174     {
1175         aVal = NULL;
1176         aLangCode = 0;
1177         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1178         aVal = commentValues[index].get_cstr();
1179         aLangCode = iCommentLangCode[index];
1180         aCharEncType = iCommentCharType[index];
1181         return PVMFSuccess;
1182     }
1183     return PVMFErrArgument;
1184 }
1185 
1186 
getNumDescription()1187 uint32 Mpeg4File::getNumDescription()
1188 {
1189     uint32 numDescription = 0;
1190     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
1191     numDescription = getNumAssetInfoDescAtoms();
1192     if (getPVDescription(chartype).get_size() > 0)
1193     {
1194         numDescription++;
1195     }
1196     if (getITunesDescription().get_size() > 0)
1197     {
1198         numDescription++;
1199     }
1200 
1201     return numDescription;
1202 }
1203 
1204 
1205 //This function populates the Description Vector with values from Asset Info, Itunes and PV Proprietary Atoms.
populateDescriptionVector()1206 PVMFStatus Mpeg4File::populateDescriptionVector()
1207 {
1208     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
1209     int32 numDescription = getNumDescription();
1210     ReserveMemoryForValuesVector(descriptionValues, numDescription, leavecode);
1211     ReserveMemoryForLangCodeVector(iDescriptionLangCode, numDescription, leavecode1);
1212     OSCL_TRY(leavecode2, iDescriptionCharType.reserve(numDescription));
1213     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1214     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
1215     {
1216         return PVMFFailure;
1217     }
1218     int32 numAssetInfoDescription = getNumAssetInfoDescAtoms();
1219     if (numAssetInfoDescription > 0)
1220     {
1221         for (int32 i = 0; i < numAssetInfoDescription; i++)
1222         {
1223             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoDescNotice(charType, i);
1224             descriptionValues.push_front(valuestring);
1225             iDescriptionLangCode.push_front(getAssetInfoDescLangCode(i));
1226             iDescriptionCharType.push_front(charType);
1227         }
1228     }
1229     if (getPVDescription(charType).get_size() > 0)
1230     {
1231         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVDescription(charType);
1232         descriptionValues.push_front(valuestring);
1233         iDescriptionLangCode.push_front(0);
1234         iDescriptionCharType.push_front(charType);
1235     }
1236 
1237     if (getITunesDescription().get_size() > 0)
1238     {
1239         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesDescription();
1240         descriptionValues.push_front(valuestring);
1241         iDescriptionLangCode.push_front(0);
1242         iDescriptionCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
1243     }
1244 
1245     return PVMFSuccess;
1246 }
1247 
1248 // This function returns the Descriptions based on index value, to the parser node.
getDescription(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)1249 PVMFStatus Mpeg4File::getDescription(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc&
1250                                      aCharEncType)
1251 {
1252     if (index < descriptionValues.size())
1253     {
1254         aVal = NULL;
1255         aLangCode = 0;
1256         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1257         aVal = descriptionValues[index].get_cstr();
1258         aLangCode = iDescriptionLangCode[index];
1259         aCharEncType = iDescriptionCharType[index];
1260         return PVMFSuccess;
1261     }
1262     return PVMFErrArgument;
1263 }
1264 
1265 
getNumRating()1266 uint32 Mpeg4File::getNumRating()
1267 {
1268     uint32 numRating = 0;
1269     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
1270     numRating = getNumAssetInfoRatingAtoms();
1271 
1272     if (getPVRating(chartype).get_size() > 0)
1273     {
1274         numRating++;
1275     }
1276     return numRating;
1277 }
1278 
1279 
1280 //This function populates the Rating Vector with values from Asset Info and PV Proprietary Atoms.
populateRatingVector()1281 PVMFStatus Mpeg4File::populateRatingVector()
1282 {
1283     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
1284     int32 numRating = getNumRating();
1285     ReserveMemoryForValuesVector(ratingValues, numRating, leavecode);
1286     ReserveMemoryForLangCodeVector(iRatingLangCode, numRating, leavecode1);
1287     OSCL_TRY(leavecode2, iRatingCharType.reserve(numRating));
1288     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1289     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
1290     {
1291         return PVMFFailure;
1292     }
1293     int32 numAssetInfoRating = getNumAssetInfoRatingAtoms();
1294     if (numAssetInfoRating > 0)
1295     {
1296         for (int32 i = 0; i < numAssetInfoRating; i++)
1297         {
1298             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoRatingNotice(charType, i);
1299             ratingValues.push_front(valuestring);
1300             iRatingLangCode.push_front(getAssetInfoRatingLangCode(i));
1301             iRatingCharType.push_front(charType);
1302         }
1303     }
1304     if (getPVRating(charType).get_size() > 0)
1305     {
1306         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVRating(charType);
1307         ratingValues.push_front(valuestring);
1308         iRatingLangCode.push_front(0);
1309         iRatingCharType.push_front(charType);
1310     }
1311 
1312     return PVMFSuccess;
1313 }
1314 
1315 // This function returns the Ratings based on index value, to the parser node.
getRating(uint32 index,OSCL_wString & aVal,uint16 & aLangCode,MP4FFParserOriginalCharEnc & aCharEncType)1316 PVMFStatus Mpeg4File::getRating(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc&
1317                                 aCharEncType)
1318 {
1319     if (index < ratingValues.size())
1320     {
1321         aVal = NULL;
1322         aLangCode = 0;
1323         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1324         aVal = ratingValues[index].get_cstr();
1325         aLangCode = iRatingLangCode[index];
1326         aCharEncType = iRatingCharType[index];
1327         return PVMFSuccess;
1328     }
1329     return PVMFErrArgument;
1330 }
1331 
1332 
getNumYear()1333 uint32 Mpeg4File::getNumYear()
1334 {
1335     uint32 numYear = 0;
1336     numYear = getNumAssetInfoRecordingYearAtoms();
1337     if (getITunesYear().get_size() > 0)
1338     {
1339         numYear++;
1340     }
1341 
1342     PvmiKvpSharedPtrVector framevector;
1343     GetID3MetaData(framevector);
1344     uint32 num_frames = framevector.size();
1345     for (uint32 i = 0; i < num_frames; i++)
1346     {
1347         if (framevector.size() > 0)
1348         {
1349             if (oscl_strstr(framevector[i]->key, "year") != 0)
1350             {
1351                 numYear++;
1352                 break;
1353             }
1354         }
1355     }
1356     return numYear;
1357 }
1358 
1359 
1360 //This function populates the Year Vector with values from Asset Info, Itunes, FullMusic and PV Proprietary Atoms.
populateYearVector()1361 PVMFStatus Mpeg4File::populateYearVector()
1362 {
1363     int32 leavecode = 0;
1364     int32 numYear = getNumYear();
1365     OSCL_TRY(leavecode, yearValues.reserve(numYear));
1366 
1367     if (leavecode != 0)
1368     {
1369         return PVMFFailure;
1370     }
1371     int32 numAssetInfoRecordingYear = getNumAssetInfoRecordingYearAtoms();
1372     if (numAssetInfoRecordingYear > 0)
1373     {
1374         for (int32 i = 0; i < numAssetInfoRecordingYear; i++)
1375         {
1376             uint16 valuestring = getAssetInfoRecordingYear(i);
1377             yearValues.push_front(valuestring);
1378         }
1379     }
1380     if (getITunesYear().get_size() > 0)
1381     {
1382         uint32 value, i;
1383         OSCL_wHeapString<OsclMemAllocator> values1 = getITunesYear();
1384         char valuestring[256];
1385         oscl_UnicodeToUTF8(values1.get_cstr(), values1.get_size(), valuestring, 256);
1386         i = PV_atoi(valuestring, 'd', value);
1387         yearValues.push_front(value);
1388     }
1389     PvmiKvpSharedPtrVector framevector;
1390     GetID3MetaData(framevector);
1391     uint32 num_frames = framevector.size();
1392     for (uint32 i = 0; i < num_frames; i++)
1393     {
1394         if (framevector.size() > 0)
1395         {
1396             if (oscl_strstr(framevector[i]->key, "year") != 0)
1397             {
1398                 PV_atoi(framevector[i]->value.pChar_value, 'd', _id3v1Year);
1399                 yearValues.push_front(_id3v1Year);
1400                 break;
1401             }
1402         }
1403     }
1404 
1405     return PVMFSuccess;
1406 }
1407 
1408 // This function returns the Years based on index value, to the parser node.
getYear(uint32 index,uint32 & aVal)1409 PVMFStatus Mpeg4File::getYear(uint32 index, uint32& aVal)
1410 {
1411     if (index < yearValues.size())
1412     {
1413         aVal = 0;
1414         aVal = yearValues[index];
1415 
1416         return PVMFSuccess;
1417     }
1418     return PVMFErrArgument;
1419 }
getPVTitle(MP4FFParserOriginalCharEnc & charType)1420 OSCL_wString& Mpeg4File::getPVTitle(MP4FFParserOriginalCharEnc &charType)
1421 {
1422     PVUserDataAtom *patom = NULL;
1423     if (_puserDataAtom != NULL)
1424     {
1425         patom =
1426             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1427     }
1428     else
1429     {
1430         return _emptyString;
1431     }
1432 
1433     if (patom != NULL)
1434     {
1435         return patom->getPVTitle(charType);
1436     }
1437     else
1438     {
1439         return _emptyString;
1440     }
1441 }
1442 
getPVAuthor(MP4FFParserOriginalCharEnc & charType)1443 OSCL_wString& Mpeg4File::getPVAuthor(MP4FFParserOriginalCharEnc &charType)
1444 {
1445     PVUserDataAtom *patom = NULL;
1446     if (_puserDataAtom != NULL)
1447     {
1448         patom =
1449             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1450     }
1451     else
1452     {
1453         return _emptyString;
1454     }
1455 
1456     if (patom != NULL)
1457     {
1458         return patom->getPVAuthor(charType);
1459     }
1460     else
1461     {
1462         return _emptyString;
1463     }
1464 }
1465 
getPVVersion(MP4FFParserOriginalCharEnc & charType)1466 OSCL_wString& Mpeg4File::getPVVersion(MP4FFParserOriginalCharEnc &charType)
1467 {
1468     OSCL_UNUSED_ARG(charType);
1469 
1470     PVUserDataAtom *patom = NULL;
1471     if (_puserDataAtom != NULL)
1472     {
1473         patom =
1474             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1475     }
1476     else
1477     {
1478         return _emptyString;
1479     }
1480 
1481     if (patom != NULL)
1482     {
1483         return patom->getPVVersion();
1484     }
1485     else
1486     {
1487         return _emptyString;
1488     }
1489 }
1490 
getPVCopyright(MP4FFParserOriginalCharEnc & charType)1491 OSCL_wString& Mpeg4File::getPVCopyright(MP4FFParserOriginalCharEnc &charType)
1492 {
1493     PVUserDataAtom *patom = NULL;
1494     if (_puserDataAtom != NULL)
1495     {
1496         patom =
1497             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1498     }
1499     else
1500     {
1501         return _emptyString;
1502     }
1503 
1504     if (patom != NULL)
1505     {
1506         return patom->getPVCopyright(charType);
1507     }
1508     else
1509     {
1510         return _emptyString;
1511     }
1512 }
1513 
getPVDescription(MP4FFParserOriginalCharEnc & charType)1514 OSCL_wString& Mpeg4File::getPVDescription(MP4FFParserOriginalCharEnc &charType)
1515 {
1516     PVUserDataAtom *patom = NULL;
1517     if (_puserDataAtom != NULL)
1518     {
1519         patom =
1520             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1521     }
1522     else
1523     {
1524         return _emptyString;
1525     }
1526 
1527     if (patom != NULL)
1528     {
1529         return patom->getPVDescription(charType);
1530     }
1531     else
1532     {
1533         return _emptyString;
1534     }
1535 }
1536 
getPVRating(MP4FFParserOriginalCharEnc & charType)1537 OSCL_wString& Mpeg4File::getPVRating(MP4FFParserOriginalCharEnc &charType)
1538 {
1539     PVUserDataAtom *patom = NULL;
1540     if (_puserDataAtom != NULL)
1541     {
1542         patom =
1543             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1544     }
1545     else
1546     {
1547         return _emptyString;
1548     }
1549 
1550     if (patom != NULL)
1551     {
1552         return patom->getPVRating(charType);
1553     }
1554     else
1555     {
1556         return _emptyString;
1557     }
1558 }
1559 
getCreationDate(MP4FFParserOriginalCharEnc & charType)1560 OSCL_wHeapString<OsclMemAllocator> Mpeg4File::getCreationDate(MP4FFParserOriginalCharEnc &charType)
1561 {
1562     PVUserDataAtom *patom = NULL;
1563     if (_puserDataAtom != NULL)
1564     {
1565         patom =
1566             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
1567         if (patom != NULL)
1568         {
1569             return patom->getPVCreationDate(charType);
1570         }
1571         else
1572         {
1573             return _emptyString;
1574         }
1575     }
1576     else
1577     {
1578         return (_pmovieAtom->getCreationDate());
1579     }
1580 }
1581 
1582 // Destructor
~Mpeg4File()1583 Mpeg4File::~Mpeg4File()
1584 {
1585     uint32 i;
1586     // Clean up atoms
1587     if (_pmovieAtom != NULL)
1588     {
1589         PV_MP4_FF_DELETE(NULL, MovieAtom, _pmovieAtom);
1590     }
1591 
1592     //Delete all the track atoms in the vec
1593     for (i = 0; i < _pTrackAtomVec->size(); i++)
1594     {
1595         PV_MP4_FF_DELETE(NULL, TrackAtom, (*_pTrackAtomVec)[i]);
1596     }
1597 
1598     // Delete the vectors themselves
1599     PV_MP4_FF_TEMPLATED_DELETE(NULL, trackAtomVecType, Oscl_Vector, _pTrackAtomVec);
1600 
1601 
1602     titleValues.destroy();
1603     iTitleLangCode.destroy();
1604     iTitleCharType.destroy();
1605 
1606     authorValues.destroy();
1607     iAuthorLangCode.destroy();
1608     iAuthorCharType.destroy();
1609 
1610 
1611     albumValues.destroy();
1612     iAlbumLangCode.destroy();
1613     iAlbumCharType.destroy();
1614 
1615 
1616     artistValues.destroy();
1617     iArtistLangCode.destroy();
1618     iArtistCharType.destroy();
1619 
1620 
1621     genreValues.destroy();
1622     iGenreLangCode.destroy();
1623     iGenreCharType.destroy();
1624 
1625 
1626     yearValues.destroy();
1627 
1628 
1629     copyrightValues.destroy();
1630     iCopyrightLangCode.destroy();
1631     iCopyrightCharType.destroy();
1632 
1633 
1634     commentValues.destroy();
1635     iCommentLangCode.destroy();
1636     iCommentCharType.destroy();
1637 
1638 
1639     descriptionValues.destroy();
1640     iDescriptionLangCode.destroy();
1641     iDescriptionCharType.destroy();
1642 
1643 
1644     ratingValues.destroy();
1645     iRatingLangCode.destroy();
1646     iRatingCharType.destroy()   ;
1647 
1648 
1649     //delete all movie fragments
1650     for (i = 0; i < _pMovieFragmentAtomVec->size(); i++)
1651     {
1652         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom, (*_pMovieFragmentAtomVec)[i]);
1653     }
1654     PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentAtomVecType, Oscl_Vector, _pMovieFragmentAtomVec);
1655     //delete all movie fragments randomm access box
1656     for (i = 0; i < _pMovieFragmentRandomAccessAtomVec->size(); i++)
1657     {
1658         PV_MP4_FF_DELETE(NULL, MovieFragmentRandomAccessAtom, (*_pMovieFragmentRandomAccessAtomVec)[i]);
1659     }
1660     // Delete the vectors themselves
1661     PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentRandomAccessAtomVecType, Oscl_Vector, _pMovieFragmentRandomAccessAtomVec);
1662 
1663     if (_pMoofOffsetVec != NULL)
1664         PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentOffsetVecType, Oscl_Vector, _pMoofOffsetVec);
1665 
1666 
1667     if (_pMfraOffsetAtom != NULL)
1668     {
1669         PV_MP4_FF_DELETE(NULL, MfraOffsetAtom, _pMfraOffsetAtom);
1670     }
1671 
1672     if (_pTrackDurationContainer != NULL)
1673     {
1674         for (i = 0; i < _pTrackDurationContainer->_pTrackdurationInfoVec->size(); i++)
1675         {
1676             PV_MP4_FF_DELETE(NULL, TrackDurationInfo, (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i]);
1677         }
1678         PV_MP4_FF_TEMPLATED_DELETE(NULL, trackDurationInfoVecType, Oscl_Vector, _pTrackDurationContainer->_pTrackdurationInfoVec);
1679 
1680         PV_MP4_FF_DELETE(NULL, TrackDurationContainer, _pTrackDurationContainer);
1681     }
1682 
1683     // Delete user data if present
1684     if (_puserDataAtom != NULL)
1685     {
1686         PV_MP4_FF_DELETE(NULL, UserDataAtom, _puserDataAtom);
1687     }
1688 
1689     if (_pFileTypeAtom != NULL)
1690     {
1691         PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
1692     }
1693 
1694     if (_movieFragmentFilePtr != NULL)
1695     {
1696         if (_movieFragmentFilePtr->IsOpen())
1697         {
1698             AtomUtils::CloseMP4File(_movieFragmentFilePtr);
1699         }
1700         oscl_free(_movieFragmentFilePtr);
1701     }
1702     if (_pID3Parser)
1703     {
1704         PV_MP4_FF_DELETE(null, PVID3ParCom, _pID3Parser);
1705         _pID3Parser = NULL;
1706     }
1707 }
1708 
1709 
getMovieDuration() const1710 uint64 Mpeg4File::getMovieDuration() const
1711 {
1712     uint64 overallMovieDuration = 0;
1713     uint32 id = 0;
1714     if (_isMovieFragmentsPresent)
1715     {
1716         overallMovieDuration = _pmovieAtom->getMovieFragmentDuration();
1717         if (Oscl_Int64_Utils::get_uint64_lower32(overallMovieDuration) != 0)
1718         {
1719             return overallMovieDuration;
1720         }
1721         else if (_parsing_mode == 0)
1722         {
1723             uint numTracks = _pmovieAtom->getNumTracks();
1724             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
1725             if (! trackList)
1726                 return 0;   // malloc failure
1727             _pmovieAtom->getTrackWholeIDList(trackList);
1728             uint32 prevtrackDuration = 0, trackduration = 0;
1729             for (uint32 i = 0; i < numTracks; i++)
1730             {
1731                 TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
1732                 trackduration = pTrackDurationInfo->trackDuration;
1733                 if (prevtrackDuration > trackduration)
1734                 {
1735                     trackduration = prevtrackDuration;
1736                 }
1737                 else
1738                 {
1739                     prevtrackDuration = trackduration;
1740                     id = trackList[i];
1741                 }
1742             }
1743             Oscl_Int64_Utils::set_uint64(overallMovieDuration, 0, trackduration);
1744 
1745             TrackAtom *trackAtom = NULL;
1746             uint32 mediaTimeScale = 0xFFFFFFFE;
1747 
1748             if (_pmovieAtom != NULL)
1749             {
1750                 trackAtom = _pmovieAtom->getTrackForID(id);
1751             }
1752             if (trackAtom != NULL)
1753             {
1754                 mediaTimeScale = trackAtom->getMediaTimescale();
1755                 if (mediaTimeScale == 0)
1756                 {
1757                     // unlikely : getMediaTimescale can return 0
1758                     mediaTimeScale = 0xFFFFFFFE;
1759                 }
1760             }
1761 
1762             overallMovieDuration  = (overallMovieDuration / (uint64)mediaTimeScale) * (uint64)getMovieTimescale();
1763             oscl_free(trackList);
1764             return overallMovieDuration;
1765         }
1766         else
1767         {
1768             return overallMovieDuration;
1769         }
1770     }
1771     else if (_pmovieAtom != NULL)
1772     {
1773         // Get the overall duration of the Mpeg-4 presentation
1774         return _pmovieAtom->getDuration();
1775     }
1776     return 0;
1777 }
1778 
getMovieFragmentDuration() const1779 uint64 Mpeg4File::getMovieFragmentDuration() const
1780 {
1781     if (_pmovieAtom != NULL)
1782     {
1783         return _pmovieAtom->getMovieFragmentDuration();
1784     }
1785     else
1786         return 0;
1787 }
1788 
getTimestampForSampleNumber(uint32 id,uint32 sampleNumber)1789 uint32 Mpeg4File::getTimestampForSampleNumber(uint32 id, uint32 sampleNumber)
1790 {
1791     TrackAtom *trackAtom;
1792 
1793     if (_pmovieAtom != NULL)
1794     {
1795         trackAtom =  _pmovieAtom->getTrackForID(id);
1796 
1797         if (trackAtom != NULL)
1798         {
1799             return trackAtom->getTimestampForSampleNumber(sampleNumber);
1800         }
1801         else
1802         {
1803             return 0;
1804         }
1805     }
1806     else
1807     {
1808         return 0;
1809     }
1810 }
1811 
getSampleSizeAt(uint32 id,int32 sampleNum)1812 int32 Mpeg4File::getSampleSizeAt(uint32 id, int32 sampleNum)
1813 {
1814     TrackAtom *trackAtom;
1815 
1816     if (_pmovieAtom != NULL)
1817     {
1818         trackAtom =  _pmovieAtom->getTrackForID(id);
1819 
1820         if (trackAtom != NULL)
1821         {
1822             return (trackAtom->getSampleSizeAt(sampleNum));
1823         }
1824         else
1825         {
1826             return 0;
1827         }
1828     }
1829     else
1830     {
1831         return 0;
1832     }
1833 }
1834 
getTrackMediaDurationForMovie(uint32 id)1835 uint64 Mpeg4File::getTrackMediaDurationForMovie(uint32 id)
1836 {
1837     TrackAtom *trackAtom;
1838     if (_pmovieAtom != NULL)
1839     {
1840         trackAtom = _pmovieAtom->getTrackForID(id);
1841     }
1842     else
1843     {
1844         return 0;
1845     }
1846     if (trackAtom != NULL)
1847     {
1848         return trackAtom->getTrackDuration();
1849     }
1850     else
1851     {
1852         return 0;
1853     }
1854 
1855 }
1856 // From TrackHeader
getTrackDuration(uint32 id)1857 uint64 Mpeg4File::getTrackDuration(uint32 id)
1858 {
1859     TrackAtom *trackAtom;
1860     if (_pmovieAtom != NULL)
1861     {
1862         trackAtom = _pmovieAtom->getTrackForID(id);
1863     }
1864     else
1865     {
1866         return 0;
1867     }
1868     if (_isMovieFragmentsPresent)
1869     {
1870         if (_parsing_mode)
1871             return _pmovieAtom->getMovieFragmentDuration();
1872         else
1873         {
1874             int32 numTracks = _pmovieAtom->getNumTracks();
1875             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
1876             if (!trackList)
1877                 return 0;   // malloc failed
1878             _pmovieAtom->getTrackWholeIDList(trackList);
1879             uint64 trackduration = 0;
1880             for (int32 i = 0; i < numTracks; i++)
1881             {
1882                 if (trackList[i] == id)
1883                 {
1884                     TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
1885                     oscl_free(trackList);
1886                     return trackduration = pTrackDurationInfo->trackDuration;
1887                 }
1888             }
1889             oscl_free(trackList);
1890         }
1891     }
1892     if (trackAtom != NULL)
1893     {
1894         return trackAtom->getTrackDuration();
1895     }
1896     else
1897     {
1898         return 0;
1899     }
1900 }
1901 
1902 // From TrackReference
trackDependsOn(uint32 id)1903 uint32  Mpeg4File::trackDependsOn(uint32 id)
1904 {
1905     TrackAtom *trackAtom;
1906     if (_pmovieAtom != NULL)
1907     {
1908         trackAtom = _pmovieAtom->getTrackForID(id);
1909     }
1910     else
1911     {
1912         return 0;
1913     }
1914 
1915     if (trackAtom != NULL)
1916     {
1917         return trackAtom->dependsOn();
1918     }
1919     else
1920     {
1921         return 0;
1922     }
1923 
1924 }
1925 
1926 // From MediaHeader
getTrackMediaDuration(uint32 id)1927 uint64 Mpeg4File::getTrackMediaDuration(uint32 id)
1928 {
1929     TrackAtom *trackAtom;
1930     if (_pmovieAtom != NULL)
1931     {
1932         trackAtom = _pmovieAtom->getTrackForID(id);
1933     }
1934     else
1935     {
1936         return 0;
1937     }
1938     if (_isMovieFragmentsPresent)
1939     {
1940         if (_parsing_mode)
1941             return _pmovieAtom->getMovieFragmentDuration();
1942         else
1943         {
1944             int numTracks = _pmovieAtom->getNumTracks();
1945             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
1946             if (!trackList)
1947                 return 0;   // malloc failed
1948             _pmovieAtom->getTrackWholeIDList(trackList);
1949             uint32 trackduration = 0;
1950             for (int32 i = 0; i < numTracks; i++)
1951             {
1952                 if (trackList[i] == id)
1953                 {
1954                     TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
1955                     oscl_free(trackList);
1956                     return trackduration = pTrackDurationInfo->trackDuration;
1957                 }
1958             }
1959             oscl_free(trackList);
1960         }
1961     }
1962 
1963     if (trackAtom != NULL)
1964     {
1965         return trackAtom->getMediaDuration();
1966     }
1967     else
1968     {
1969         return 0;
1970     }
1971 }
1972 
getTrackMediaTimescale(uint32 id)1973 uint32 Mpeg4File::getTrackMediaTimescale(uint32 id)
1974 {
1975     TrackAtom *trackAtom;
1976     if (_pmovieAtom != NULL)
1977     {
1978         trackAtom = _pmovieAtom->getTrackForID(id);
1979     }
1980     else
1981     {
1982         // RETURN UNDEFINED VALUE
1983         return (0xFFFFFFFF);
1984     }
1985 
1986     if (trackAtom != NULL)
1987     {
1988         return trackAtom->getMediaTimescale();
1989     }
1990     else
1991     {
1992         // RETURN UNDEFINED VALUE
1993         return (0xFFFFFFFF);
1994     }
1995 }
1996 
getTrackLangCode(uint32 id)1997 uint16 Mpeg4File::getTrackLangCode(uint32 id)
1998 {
1999 
2000     TrackAtom *trackAtom;
2001     if (_pmovieAtom != NULL)
2002     {
2003         trackAtom = _pmovieAtom->getTrackForID(id);
2004     }
2005     else
2006     {
2007         // RETURN UNDEFINED VALUE
2008         return (0xFFFF);
2009     }
2010 
2011     if (trackAtom != NULL)
2012     {
2013         return trackAtom->getLanguageCode();
2014     }
2015     else
2016     {
2017         // RETURN UNDEFINED VALUE
2018         return (0xFFFF);
2019     }
2020 }
2021 
2022 // From Handler
getTrackMediaType(uint32 id)2023 uint32 Mpeg4File::getTrackMediaType(uint32 id)
2024 {
2025     TrackAtom *trackAtom;
2026     if (_pmovieAtom != NULL)
2027     {
2028         trackAtom = _pmovieAtom->getTrackForID(id);
2029     }
2030     else
2031     {
2032         // RETURN UNDEFINED VALUE
2033         return (0xFFFFFFFF);
2034     }
2035 
2036     if (trackAtom != NULL)
2037     {
2038         return trackAtom->getMediaType();
2039     }
2040     else
2041     {
2042         // RETURN UNDEFINED VALUE
2043         return (0xFFFFFFFF);
2044     }
2045 
2046 }
2047 
2048 // From SampleDescription
getTrackNumSampleEntries(uint32 id)2049 int32 Mpeg4File::getTrackNumSampleEntries(uint32 id)
2050 {
2051     TrackAtom *trackAtom;
2052 
2053     if (_pmovieAtom != NULL)
2054     {
2055         trackAtom = _pmovieAtom->getTrackForID(id);
2056     }
2057     else
2058     {
2059         return 0;
2060     }
2061 
2062     if (trackAtom != NULL)
2063     {
2064         return trackAtom->getNumSampleEntries();
2065     }
2066     else
2067     {
2068         return 0;
2069     }
2070 }
2071 
2072 // From DecoderConfigDescriptor
getTrackDecoderSpecificInfo(uint32 id)2073 DecoderSpecificInfo *Mpeg4File::getTrackDecoderSpecificInfo(uint32 id)
2074 {
2075     TrackAtom *trackAtom;
2076     if (_pmovieAtom != NULL)
2077     {
2078         trackAtom = _pmovieAtom->getTrackForID(id);
2079     }
2080     else
2081     {
2082         return NULL;
2083     }
2084 
2085     if (trackAtom != NULL)
2086     {
2087         return trackAtom->getDecoderSpecificInfo();
2088     }
2089     else
2090     {
2091         return NULL;
2092     }
2093 
2094 }
2095 
2096 // From DecoderConfigDescriptor
2097 DecoderSpecificInfo *
getTrackDecoderSpecificInfoAtSDI(uint32 trackID,uint32 index)2098 Mpeg4File::getTrackDecoderSpecificInfoAtSDI(uint32 trackID, uint32 index)
2099 {
2100     if (_pmovieAtom != NULL)
2101     {
2102         return (_pmovieAtom->getTrackDecoderSpecificInfoAtSDI(trackID, index));
2103     }
2104     else
2105     {
2106         return NULL;
2107     }
2108 }
2109 
getTrackDecoderSpecificInfoContent(uint32 id)2110 uint8 *Mpeg4File::getTrackDecoderSpecificInfoContent(uint32 id)
2111 {
2112     DecoderSpecificInfo *decoderSpecificInfo;
2113     decoderSpecificInfo = getTrackDecoderSpecificInfo(id);
2114 
2115     if (decoderSpecificInfo != NULL)
2116     {
2117         return decoderSpecificInfo->getInfo();
2118     }
2119     else
2120     {
2121         return NULL;
2122     }
2123 }
2124 
getTrackDecoderSpecificInfoSize(uint32 id)2125 uint32 Mpeg4File::getTrackDecoderSpecificInfoSize(uint32 id)
2126 {
2127     DecoderSpecificInfo *decoderSpecificInfo;
2128     decoderSpecificInfo = getTrackDecoderSpecificInfo(id);
2129 
2130     if (decoderSpecificInfo != NULL)
2131     {
2132         return decoderSpecificInfo->getInfoSize();
2133     }
2134     else
2135     {
2136         return 0;
2137     }
2138 }
2139 
2140 
getTrackMIMEType(uint32 id,OSCL_String & aMimeType)2141 void Mpeg4File::getTrackMIMEType(uint32 id, OSCL_String& aMimeType) // Based on OTI value
2142 {
2143     TrackAtom *trackAtom = NULL;
2144 
2145     if (_pmovieAtom != NULL)
2146     {
2147         trackAtom =  _pmovieAtom->getTrackForID(id);
2148     }
2149 
2150     if (trackAtom != NULL)
2151     {
2152         trackAtom->getMIMEType(aMimeType);
2153     }
2154 }
2155 
2156 
getTrackMaxBufferSizeDB(uint32 id)2157 int32 Mpeg4File::getTrackMaxBufferSizeDB(uint32 id)
2158 {
2159     TrackAtom *trackAtom;
2160 
2161     if (_pmovieAtom != NULL)
2162     {
2163         trackAtom =  _pmovieAtom->getTrackForID(id);
2164     }
2165     else
2166     {
2167         return 0;
2168     }
2169 
2170     if (trackAtom != NULL)
2171     {
2172         return trackAtom->getMaxBufferSizeDB();
2173     }
2174     else
2175     {
2176         return 0;
2177     }
2178 }
2179 
getTrackAverageBitrate(uint32 id)2180 int32 Mpeg4File::getTrackAverageBitrate(uint32 id)
2181 {
2182     TrackAtom *trackAtom;
2183 
2184     if (_pmovieAtom != NULL)
2185     {
2186         trackAtom =  _pmovieAtom->getTrackForID(id);
2187     }
2188     else
2189     {
2190         return 0;
2191     }
2192 
2193     if (trackAtom != NULL)
2194     {
2195         return trackAtom->getAverageBitrate();
2196     }
2197     else
2198     {
2199         return 0;
2200     }
2201 }
2202 
2203 // PASP Box
2204 //Hspacing
getHspacing(uint32 id)2205 uint32 Mpeg4File::getHspacing(uint32 id)
2206 {
2207 
2208     TrackAtom *trackAtom;
2209 
2210     if (_pmovieAtom != NULL)
2211     {
2212         trackAtom =  _pmovieAtom->getTrackForID(id);
2213     }
2214     else
2215     {
2216         return 0;
2217     }
2218 
2219     if (trackAtom != NULL)
2220     {
2221         return trackAtom->getHspacing();
2222     }
2223     else
2224     {
2225         return 0;
2226     }
2227 }
2228 
2229 //Vspacing
getVspacing(uint32 id)2230 uint32 Mpeg4File::getVspacing(uint32 id)
2231 {
2232 
2233     TrackAtom *trackAtom;
2234 
2235     if (_pmovieAtom != NULL)
2236     {
2237         trackAtom =  _pmovieAtom->getTrackForID(id);
2238     }
2239     else
2240     {
2241         return 0;
2242     }
2243 
2244     if (trackAtom != NULL)
2245     {
2246         return trackAtom->getVspacing();
2247     }
2248     else
2249     {
2250         return 0;
2251     }
2252 }
2253 
2254 
2255 uint32
getMovieTimescale() const2256 Mpeg4File::getMovieTimescale() const
2257 {
2258     if (_pmovieAtom != NULL)
2259     {
2260         // Set the overall timescale of the Mpeg-4 presentation
2261         return _pmovieAtom->getTimeScale();
2262     }
2263     else
2264     {
2265         // RETURN UNDEFINED VALUE
2266         return (0xFFFFFFFF);
2267     }
2268 }
2269 
2270 /* ======================================================================== */
2271 bool
IsMobileMP4()2272 Mpeg4File::IsMobileMP4()
2273 {
2274     bool oMMP4 = false;
2275 
2276     if (_pFileTypeAtom != NULL)
2277     {
2278         uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
2279 
2280         if (majorBrand != MOBILE_MP4)
2281         {
2282             Oscl_Vector<uint32, OsclMemAllocator> *_compatibleBrand =
2283                 _pFileTypeAtom->getCompatibleBrand();
2284             if (_compatibleBrand != NULL)
2285             {
2286                 for (uint32 i = 0; i < _compatibleBrand->size(); i++)
2287                 {
2288                     uint32 brand = (*_compatibleBrand)[i];
2289 
2290                     if (brand == MOBILE_MP4)
2291                     {
2292                         oMMP4 = true;
2293                     }
2294                 }
2295             }
2296             else
2297             {
2298                 return false;
2299             }
2300         }
2301         else
2302         {
2303             oMMP4 = true;
2304         }
2305     }
2306     else
2307     {
2308         return false;
2309     }
2310 
2311     if (oMMP4 == true)
2312     {
2313         if (!(_pmovieAtom->checkMMP4()))
2314         {
2315             return false;
2316         }
2317     }
2318 
2319     return (oMMP4);
2320 }
2321 
2322 uint8
parseBufferAndGetNumAMRFrames(uint8 * buffer,uint32 size)2323 Mpeg4File::parseBufferAndGetNumAMRFrames(uint8* buffer, uint32 size)
2324 {
2325     uint32 inputBufferSize = size;
2326     uint8* inputPtr = buffer;
2327     uint8 numArmFrames = 0;
2328 
2329     if (((int32)(size) <= 0) ||
2330             (buffer == NULL))
2331     {
2332         return 0;
2333     }
2334 
2335     uint8 aFrameSizes[16] = {12, 13, 15, 17, 19, 20, 26, 31,
2336                              5,  0,  0,  0,  0,  0,  0,  0
2337                             };
2338 
2339     while (inputBufferSize > 0)
2340     {
2341         uint8 toc_byte = *(inputPtr);
2342 
2343         uint8 frame_type = (uint8)((toc_byte >> 3) & 0x0F);
2344 
2345         inputPtr        += 1;
2346         inputBufferSize -= 1;
2347 
2348         if ((frame_type > 8) && (frame_type != 15))
2349         {
2350             return 0;
2351         }
2352 
2353         numArmFrames++;
2354         inputPtr        += aFrameSizes[(uint16)frame_type];
2355         inputBufferSize -= aFrameSizes[(uint16)frame_type];
2356     }
2357     return (numArmFrames);
2358 }
2359 
2360 
getTrackLevelOMA2DRMInfoSize(uint32 trackID)2361 uint32 Mpeg4File::getTrackLevelOMA2DRMInfoSize(uint32 trackID)
2362 {
2363     TrackAtom *trackAtom;
2364 
2365     if (_pmovieAtom != NULL)
2366     {
2367         trackAtom =  _pmovieAtom->getTrackForID(trackID);
2368     }
2369     else
2370     {
2371         return 0;
2372     }
2373 
2374     if (trackAtom != NULL)
2375     {
2376         return trackAtom->getTrackLevelOMA2DRMInfoSize();
2377     }
2378     else
2379     {
2380         return 0;
2381     }
2382 }
2383 
getTrackLevelOMA2DRMInfo(uint32 trackID)2384 uint8* Mpeg4File::getTrackLevelOMA2DRMInfo(uint32 trackID)
2385 {
2386     TrackAtom *trackAtom;
2387 
2388     if (_pmovieAtom != NULL)
2389     {
2390         trackAtom =  _pmovieAtom->getTrackForID(trackID);
2391     }
2392     else
2393     {
2394         return NULL;
2395     }
2396 
2397     if (trackAtom != NULL)
2398     {
2399         return trackAtom->getTrackLevelOMA2DRMInfo();
2400     }
2401     else
2402     {
2403         return NULL;
2404     }
2405 }
2406 
2407 
2408 MP4_ERROR_CODE
RequestReadCapacityNotification(PvmiDataStreamObserver & aObserver,uint32 aFileOffset,OsclAny * aContextData)2409 Mpeg4File::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
2410         uint32 aFileOffset,
2411         OsclAny* aContextData)
2412 {
2413     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::RequestReadCapacityNotification In Offset %d", aFileOffset));
2414     uint32 capacity = 0;
2415     if (_commonFilePtr != NULL)
2416     {
2417         uint32 currPos = (uint32)(AtomUtils::getCurrentFilePosition(_commonFilePtr));
2418         if (aFileOffset > currPos)
2419         {
2420             capacity = (aFileOffset - currPos);
2421             bool retVal =
2422                 _commonFilePtr->_pvfile.RequestReadCapacityNotification(aObserver,
2423                         capacity,
2424                         aContextData);
2425             if (retVal)
2426             {
2427                 return EVERYTHING_FINE;
2428             }
2429             else
2430             {
2431                 return DEFAULT_ERROR;
2432             }
2433         }
2434         return SUFFICIENT_DATA_IN_FILE;
2435     }
2436     return DEFAULT_ERROR;
2437 }
2438 
2439 
2440 MP4_ERROR_CODE
GetCurrentFileSize(uint32 & aFileSize)2441 Mpeg4File::GetCurrentFileSize(uint32& aFileSize)
2442 {
2443     aFileSize = 0;
2444     if (AtomUtils::getCurrentFileSize(_commonFilePtr, aFileSize) == true)
2445     {
2446         return EVERYTHING_FINE;
2447     }
2448     if (_commonFilePtr == NULL && _fileSize != 0)
2449     {
2450         aFileSize = _fileSize;
2451         return EVERYTHING_FINE;
2452     }
2453     return DEFAULT_ERROR;
2454 }
2455 
getNextBundledAccessUnits(const uint32 trackID,uint32 * n,GAU * pgau)2456 int32 Mpeg4File::getNextBundledAccessUnits(const uint32 trackID,
2457         uint32 *n,
2458         GAU    *pgau)
2459 {
2460     uint32 samplesTobeRead;
2461     samplesTobeRead = *n;
2462     uint32 totalSampleRead = 0;
2463     if (getNumTracks() == 0)
2464     {
2465         return -1;
2466     }
2467 
2468     if (_pmovieAtom != NULL)
2469     {
2470         int32 ret = _pmovieAtom->getNextBundledAccessUnits(trackID, n, pgau);
2471         if (ret == END_OF_TRACK)
2472         {
2473             if (!_isMovieFragmentsPresent)
2474                 return ret;
2475 
2476             totalSampleRead += *n;
2477             bool oAllMoofExhausted = false;
2478             bool oAllMoofParsed = false;
2479 
2480             if (_parsing_mode == 0)
2481             {
2482                 if (_pMovieFragmentAtomVec != NULL && _isMovieFragmentsPresent)
2483                 {
2484                     if (samplesTobeRead >= *n)
2485                         *n = samplesTobeRead - *n;
2486                 }
2487                 else
2488                     return ret;
2489 
2490                 int32 return1 = 0;
2491                 while (_movieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
2492                 {
2493                     uint32 movieFragmentIdx = _movieFragmentIdx[trackID];
2494                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
2495                     if (pMovieFragmentAtom != NULL)
2496                     {
2497                         if ((uint32)pMovieFragmentAtom->getSequenceNumber() == _movieFragmentSeqIdx[trackID])
2498                         {
2499                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
2500                             if (trackfragment != NULL)
2501                             {
2502                                 if (trackfragment->getTrackId() == trackID)
2503                                 {
2504                                     return1 = pMovieFragmentAtom->getNextBundledAccessUnits(trackID, n, totalSampleRead, pgau);
2505                                     totalSampleRead += *n;
2506                                     if (return1 != END_OF_TRACK)
2507                                     {
2508                                         *n = totalSampleRead;
2509                                         return return1;
2510                                     }
2511                                     else
2512                                     {
2513                                         _movieFragmentSeqIdx[trackID]++;
2514                                         if (samplesTobeRead >= *n)
2515                                         {
2516                                             samplesTobeRead = samplesTobeRead - *n;
2517                                             *n = samplesTobeRead;
2518                                         }
2519                                     }
2520                                 }
2521                             }
2522                         }
2523                     }
2524                     _movieFragmentIdx[trackID]++;
2525                 }
2526                 if (return1 == END_OF_TRACK)
2527                 {
2528                     *n = totalSampleRead;
2529                     _movieFragmentIdx[trackID] = 0;
2530                     return return1;
2531                 }
2532             }
2533             else
2534             {
2535                 int32 return1 = 0;
2536                 while (!oAllMoofExhausted)
2537                 {
2538                     if (oAllMoofParsed && (_pMovieFragmentAtomVec->size() < _movieFragmentIdx[trackID]))
2539                     {
2540                         oAllMoofExhausted = true;
2541                         *n = 0;
2542                         break;
2543                     }
2544 
2545                     while (!oAllMoofParsed)
2546                     {
2547                         if (moofParsingCompleted)
2548                         {
2549                             uint32 moofIndex = 0;
2550                             bool moofToBeParsed = false;
2551                             if (_pMovieFragmentAtomVec->size() > _movieFragmentIdx[trackID])
2552                             {
2553                                 MovieFragmentAtom *pMovieFragmentAtom = NULL;
2554                                 uint32 idx = _movieFragmentIdx[trackID];
2555                                 pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[_movieFragmentIdx[trackID]];
2556                                 if (pMovieFragmentAtom == NULL)
2557                                 {
2558                                     isResetPlayBackCalled = true;
2559                                     moofToBeParsed = true;
2560                                     moofIndex = _movieFragmentIdx[trackID];
2561                                 }
2562                                 else if (isResetPlayBackCalled)
2563                                 {
2564                                     isResetPlayBackCalled = false;
2565 
2566                                     // if moofs are already parsed, so go to the end of MOOF Vector.
2567 
2568                                     uint32 currFilePos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2569                                     if (currFilePos < _ptrMoofEnds)
2570                                     {
2571                                         uint32 offset = (_ptrMoofEnds - currFilePos);
2572                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
2573                                     }
2574                                     else if (currFilePos == _ptrMoofEnds)
2575                                     {
2576                                         // no need to seek the File Pointer
2577                                     }
2578                                     else
2579                                     {
2580                                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
2581                                     }
2582 
2583                                     idx = currMoofNum - 1;
2584                                     uint32 i = idx + 1;
2585                                     while (i < _pMovieFragmentAtomVec->size())
2586                                     {
2587                                         idx++;
2588                                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
2589                                         if (pMovieFragmentAtom == NULL)
2590                                         {
2591                                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx-1];
2592                                             AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_start_offset);
2593                                             uint32 atomType = UNKNOWN_ATOM;
2594                                             uint32 atomSize = 0;
2595                                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
2596                                             if (atomType == MOVIE_FRAGMENT_ATOM)
2597                                             {
2598                                                 atomSize -= DEFAULT_ATOM_SIZE;
2599                                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
2600                                                 _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2601                                             }
2602                                             isResetPlayBackCalled = true;
2603                                             moofToBeParsed = true;
2604                                             moofIndex = idx;
2605                                             break;
2606                                         }
2607                                         pMovieFragmentAtom->resetPlayback();
2608                                         i++;
2609                                     }
2610                                     uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
2611                                     AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_start_offset);
2612                                     uint32 atomType = UNKNOWN_ATOM;
2613                                     uint32 atomSize = 0;
2614                                     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
2615                                     if (atomType == MOVIE_FRAGMENT_ATOM)
2616                                     {
2617                                         atomSize -= DEFAULT_ATOM_SIZE;
2618                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
2619                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2620                                     }
2621                                 }
2622                             }
2623 
2624                             uint32 fileSize = 0;
2625                             AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
2626                             uint32 currFilePos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2627                             if (currFilePos < _ptrMoofEnds)
2628                             {
2629                                 uint32 offset = (_ptrMoofEnds - currFilePos);
2630                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
2631                             }
2632                             else
2633                             {
2634                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
2635                             }
2636                             uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2637                             int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
2638 
2639                             while (count > 0)
2640                             {
2641                                 uint32 atomType = UNKNOWN_ATOM;
2642                                 uint32 atomSize = 0;
2643                                 uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2644                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
2645                                 if ((currPos + atomSize) > fileSize)
2646                                 {
2647                                     AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
2648                                     if (_movieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
2649                                     {
2650                                         // dont report insufficient data as we still have a moof/moofs to
2651                                         // retrieve data. So just go and retrieve the data.
2652                                         break;
2653                                     }
2654                                     else
2655                                     {
2656                                         // We have run out of MOOF atoms so report insufficient data.
2657                                         return  INSUFFICIENT_DATA;
2658                                     }
2659                                 }
2660 
2661                                 if (atomType == MOVIE_FRAGMENT_ATOM)
2662                                 {
2663                                     uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2664                                     moofStartOffset -= DEFAULT_ATOM_SIZE;
2665                                     parseMoofCompletely = false;
2666                                     moofSize = atomSize;
2667                                     moofType = atomType;
2668                                     moofCount = count;
2669                                     _ptrMoofEnds = moofStartOffset + atomSize;
2670 
2671                                     PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
2672                                     moofSize = atomSize;
2673                                     moofPtrPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2674 
2675                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
2676                                     if (moofToBeParsed)
2677                                     {
2678                                         (*_pMovieFragmentAtomVec)[moofIndex] = _pMovieFragmentAtom;
2679                                         (*_pMoofOffsetVec)[moofIndex] = moofStartOffset;
2680                                     }
2681                                     else
2682                                     {
2683                                         _pMoofOffsetVec->push_back(moofStartOffset);
2684                                         _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
2685                                     }
2686 
2687                                     if (moofParsingCompleted)
2688                                     {
2689                                         if (!_pMovieFragmentAtom->MP4Success())
2690                                         {
2691                                             _success = false;
2692                                             _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
2693                                             oAllMoofExhausted = true;
2694                                             break;
2695                                         }
2696                                         _pMovieFragmentAtom->setParent(this);
2697                                         count -= _pMovieFragmentAtom->getSize();
2698 
2699                                         break;
2700                                     }
2701 
2702                                     break;
2703                                 }
2704                                 else if (atomType == MEDIA_DATA_ATOM)
2705                                 {
2706                                     if (atomSize == 1)
2707                                     {
2708                                         uint64 largeSize = 0;
2709                                         AtomUtils::read64(_movieFragmentFilePtr, largeSize);
2710                                         uint32 size =
2711                                             Oscl_Int64_Utils::get_uint64_lower32(largeSize);
2712                                         count -= size;
2713                                         size -= 8; //for large size
2714                                         size -= DEFAULT_ATOM_SIZE;
2715                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
2716                                     }
2717                                     else
2718                                     {
2719                                         if (atomSize < DEFAULT_ATOM_SIZE)
2720                                         {
2721                                             _success = false;
2722                                             _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
2723                                             oAllMoofExhausted = true;
2724                                             break;
2725                                         }
2726                                         if (count < (int32)atomSize)
2727                                         {
2728                                             _success = false;
2729                                             _mp4ErrorCode = INSUFFICIENT_DATA;
2730                                             ret = _mp4ErrorCode;
2731                                             oAllMoofExhausted = true;
2732                                             AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
2733                                             break;
2734                                         }
2735                                         count -= atomSize;
2736                                         atomSize -= DEFAULT_ATOM_SIZE;
2737                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
2738                                     }
2739                                 }
2740 
2741                                 else
2742                                 {
2743                                     if (count > 0)
2744                                     {
2745                                         count -= atomSize;
2746                                         atomSize -= DEFAULT_ATOM_SIZE;
2747                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
2748                                     }
2749 
2750                                 }
2751                             }
2752                             if (count <= 0)
2753                             {
2754                                 oAllMoofParsed = true;
2755                                 break;
2756                             }
2757                             break;
2758                         }
2759                         else if (!moofParsingCompleted)
2760                         {
2761                             if (currMoofNum != (uint32) _pMovieFragmentAtom->getSequenceNumber())
2762                             {
2763                                 uint32 size = _pMovieFragmentAtomVec->size();
2764                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[size - 1];
2765                             }
2766                             uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2767                             if (currPos > moofPtrPos)
2768                             {
2769                                 uint32 offset = (currPos - moofPtrPos);
2770                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, -((int32)offset));
2771                             }
2772                             else
2773                             {
2774                                 uint32 offset = (moofPtrPos - currPos);
2775                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
2776                             }
2777 
2778                             _pMovieFragmentAtom->ParseMoofAtom(_movieFragmentFilePtr, moofSize, moofType, _pTrackDurationContainer, _pTrackExtendsAtomVec, moofParsingCompleted, countOfTrunsParsed);
2779                             moofPtrPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
2780                             if (moofParsingCompleted)
2781                             {
2782                                 if (!_pMovieFragmentAtom->MP4Success())
2783                                 {
2784                                     _success = false;
2785                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
2786                                     oAllMoofExhausted = true;
2787                                     break;
2788                                 }
2789                                 _pMovieFragmentAtom->setParent(this);
2790                                 moofCount -= _pMovieFragmentAtom->getSize();
2791                             }
2792 
2793                             if (currPos > moofPtrPos)
2794                             {
2795                                 uint32 offset = (currPos - moofPtrPos);
2796                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
2797                             }
2798                             else
2799                             {
2800                                 uint32 offset = (moofPtrPos - currPos);
2801                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, -((int32)offset));
2802                             }
2803 
2804                             if (moofCount <= 0)
2805                             {
2806                                 oAllMoofParsed = true;
2807                                 break;
2808                             }
2809                             break;
2810                         }
2811                     }
2812 
2813                     if (return1 != END_OF_TRACK)
2814                     {
2815                         if (samplesTobeRead >= *n)
2816                             *n = samplesTobeRead - *n;
2817                     }
2818 
2819                     uint32 movieFragmentIdx = _movieFragmentIdx[trackID];
2820                     MovieFragmentAtom *pMovieFragmentAtom = NULL;
2821 
2822                     if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
2823                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
2824 
2825                     if (pMovieFragmentAtom != NULL)
2826                     {
2827                         uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
2828                         if (seqNum == _movieFragmentSeqIdx[trackID])
2829                         {
2830                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
2831                             if (trackfragment != NULL)
2832                             {
2833                                 if (trackfragment->getTrackId() == trackID)
2834                                 {
2835                                     return1 = pMovieFragmentAtom->getNextBundledAccessUnits(trackID, n, totalSampleRead, pgau);
2836                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::getNextBundledAccessUnits return %d", return1));
2837                                     totalSampleRead += *n;
2838                                     if (return1 != END_OF_TRACK)
2839                                     {
2840                                         *n = totalSampleRead;
2841                                         return return1;
2842                                     }
2843                                     else
2844                                     {
2845                                         _movieFragmentSeqIdx[trackID]++;
2846                                         if (samplesTobeRead >= *n)
2847                                         {
2848                                             samplesTobeRead = samplesTobeRead - *n;
2849                                             *n = samplesTobeRead;
2850                                             if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
2851                                             {
2852                                                 _movieFragmentIdx[trackID]++;
2853                                             }
2854                                         }
2855                                     }
2856                                 }
2857                             }
2858                             else
2859                             {
2860                                 uint32 movieFragmentIdx2 = _movieFragmentIdx[trackID];
2861 
2862                                 if (oAllMoofParsed)
2863                                 {
2864                                     // look for all moofs
2865                                     if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
2866                                     {
2867                                         _movieFragmentIdx[trackID]++;
2868                                         _movieFragmentSeqIdx[trackID]++;
2869                                     }
2870                                     else
2871                                     {
2872                                         return END_OF_TRACK;
2873                                     }
2874 
2875                                 }
2876                                 else
2877                                 {
2878                                     if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
2879                                     {
2880                                         if ((movieFragmentIdx2 == (_pMovieFragmentAtomVec->size() - 1)) && moofParsingCompleted)
2881                                         {
2882                                             _movieFragmentIdx[trackID]++;
2883                                             _movieFragmentSeqIdx[trackID]++;
2884                                         }
2885                                         else if (movieFragmentIdx2 < (_pMovieFragmentAtomVec->size() - 1))
2886                                         {
2887                                             _movieFragmentIdx[trackID]++;
2888                                             _movieFragmentSeqIdx[trackID]++;
2889                                             *n = 0;
2890                                             return NO_SAMPLE_IN_CURRENT_MOOF;
2891                                         }
2892                                     }
2893                                 }
2894                             }
2895                         }
2896                         else
2897                         {
2898                             uint32 movieFragmentIdx2 = _movieFragmentIdx[trackID];
2899 
2900                             if (oAllMoofParsed)
2901                             {
2902                                 // look for all moofs
2903                                 if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
2904                                 {
2905                                     _movieFragmentIdx[trackID]++;
2906                                     _movieFragmentSeqIdx[trackID]++;
2907                                 }
2908                                 else
2909                                 {
2910                                     return END_OF_TRACK;
2911                                 }
2912 
2913                             }
2914                             else
2915                             {
2916                                 if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
2917                                 {
2918                                     if ((movieFragmentIdx2 == (_pMovieFragmentAtomVec->size() - 1)) && moofParsingCompleted)
2919                                     {
2920                                         _movieFragmentIdx[trackID]++;
2921                                         _movieFragmentSeqIdx[trackID]++;
2922                                     }
2923                                     else if (movieFragmentIdx2 < (_pMovieFragmentAtomVec->size() - 1))
2924                                     {
2925                                         _movieFragmentIdx[trackID]++;
2926                                         _movieFragmentSeqIdx[trackID]++;
2927                                         *n = 0;
2928                                         return NO_SAMPLE_IN_CURRENT_MOOF;
2929                                     }
2930                                 }
2931                             }
2932                         }
2933                     }
2934                     else
2935                     {
2936                         if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
2937                         {
2938                             _movieFragmentIdx[trackID]++;
2939                             _movieFragmentSeqIdx[trackID]++;
2940                         }
2941                         else if (oAllMoofParsed)
2942                         {
2943                             _movieFragmentIdx[trackID]++;
2944                             _movieFragmentSeqIdx[trackID]++;
2945                         }
2946 
2947                     }
2948                 }
2949             }
2950         }
2951         return ret;
2952     }
2953     return -1;
2954 }
2955 
getMovieFragmentForTrackId(uint32 id)2956 MovieFragmentAtom * Mpeg4File::getMovieFragmentForTrackId(uint32 id)
2957 {
2958     MovieFragmentAtom *movieFragmentAtom = NULL;
2959     uint32 i = 0;
2960 
2961     if (_pMovieFragmentAtomVec == NULL)
2962         return NULL;
2963 
2964     while (i < _pMovieFragmentAtomVec->size())
2965     {
2966         movieFragmentAtom = (*_pMovieFragmentAtomVec)[i];
2967         if (movieFragmentAtom != NULL)
2968         {
2969             TrackFragmentAtom *trackfragment = movieFragmentAtom->getTrackFragmentforID(id);
2970             if (trackfragment != NULL)
2971             {
2972                 if (trackfragment->getTrackId() == id)
2973                 {
2974                     return movieFragmentAtom;
2975                 }
2976             }
2977         }
2978         i++;
2979     }
2980     return NULL;
2981 }
2982 
populateTrackDurationVec()2983 void Mpeg4File::populateTrackDurationVec()
2984 {
2985     uint32 trackDuration = 0;
2986     if (_pmovieAtom != NULL)
2987     {
2988         uint32 ids[256];
2989         uint32 size = 256;
2990         _pmovieAtom->getTrackIDList(ids, size);
2991         int32 numtracks = _pmovieAtom->getNumTracks();
2992         PV_MP4_FF_NEW(fp->auditCB, TrackDurationContainer, (), _pTrackDurationContainer);
2993         PV_MP4_FF_NEW(fp->auditCB, trackDurationInfoVecType, (), _pTrackDurationContainer->_pTrackdurationInfoVec);
2994         for (int32 i = 0; i < numtracks; i++)
2995         {
2996             uint32 trackID = ids[i];
2997             TrackDurationInfo *trackinfo = NULL;
2998             trackDuration = Oscl_Int64_Utils::get_uint64_lower32(_pmovieAtom->getTrackMediaDuration(trackID));
2999             PV_MP4_FF_NEW(fp->auditCB, TrackDurationInfo, (trackDuration, trackID), trackinfo);
3000             (*_pTrackDurationContainer->_pTrackdurationInfoVec).push_back(trackinfo);
3001             _movieFragmentIdx[trackID] = 0;
3002             _peekMovieFragmentIdx[trackID] = 0;
3003             _movieFragmentSeqIdx[trackID] = 1;
3004             _peekMovieFragmentSeqIdx[trackID] = 1;
3005         }
3006     }
3007 }
3008 
GetByteOffsetToStartOfAudioFrames()3009 uint32 Mpeg4File::GetByteOffsetToStartOfAudioFrames()
3010 {
3011     return _pID3Parser->GetByteOffsetToStartOfAudioFrames();
3012 
3013 }
3014 
GetID3MetaData(PvmiKvpSharedPtrVector & id3Frames)3015 void Mpeg4File::GetID3MetaData(PvmiKvpSharedPtrVector &id3Frames)
3016 {
3017     _pID3Parser->GetID3Frames(id3Frames);
3018 
3019 }
3020 
IsID3Frame(const OSCL_String & frameType)3021 bool Mpeg4File::IsID3Frame(const OSCL_String& frameType)
3022 {
3023     return _pID3Parser->IsID3FrameAvailable(frameType);
3024 }
3025 
GetID3Frame(const OSCL_String & aFrameType,PvmiKvpSharedPtrVector & aFrame)3026 void Mpeg4File::GetID3Frame(const OSCL_String& aFrameType, PvmiKvpSharedPtrVector& aFrame)
3027 {
3028     _pID3Parser->GetID3Frame(aFrameType, aFrame);
3029 }
3030 
GetID3Version() const3031 PVID3Version Mpeg4File::GetID3Version() const
3032 {
3033     return _pID3Parser->GetID3Version();
3034 }
3035 
parseID3Header(MP4_FF_FILE * aFile)3036 void Mpeg4File::parseID3Header(MP4_FF_FILE *aFile)
3037 {
3038     int32 curpos = AtomUtils::getCurrentFilePosition(aFile);
3039     AtomUtils::seekFromStart(aFile, 0);
3040     _pID3Parser->ParseID3Tag(&aFile->_pvfile);
3041     AtomUtils::seekFromStart(aFile, curpos);
3042 }
3043 
getContentType()3044 uint32 Mpeg4File::getContentType()
3045 {
3046     PVContentTypeAtom *pAtom = NULL;
3047 
3048     if (_puserDataAtom != NULL)
3049     {
3050         pAtom =
3051             (PVContentTypeAtom*) _puserDataAtom->getAtomOfType(PV_CONTENT_TYPE_ATOM);
3052 
3053         if (pAtom != NULL)
3054         {
3055             return pAtom->getContentType();
3056         }
3057         else
3058         {
3059             if (_oPVContent)
3060             {
3061                 //Old PV Content, that doesnt have this atom
3062                 //All such content is non-interleaved, with meta data
3063                 //towards the very end
3064                 return (DEFAULT_AUTHORING_MODE);
3065             }
3066         }
3067     }
3068 
3069     //Third party content
3070     return (0xFFFFFFFF);
3071 }
3072 
3073 
getKeyMediaSampleNumAt(uint32 aTrackId,uint32 aKeySampleNum,GAU * pgau)3074 MP4_ERROR_CODE Mpeg4File::getKeyMediaSampleNumAt(uint32 aTrackId,
3075         uint32 aKeySampleNum,
3076         GAU    *pgau)
3077 {
3078     if (_pmovieAtom == NULL)
3079     {
3080         return READ_SAMPLE_TABLE_ATOM_FAILED;
3081     }
3082     MP4_ERROR_CODE ret = _pmovieAtom->getKeyMediaSampleNumAt(aTrackId, aKeySampleNum, pgau);
3083     if (ret == READ_FAILED)
3084     {
3085         uint32 totalSampleRead = 0;
3086         if (_isMovieFragmentsPresent)
3087         {
3088             uint32 n = 1;
3089             uint32 movieFragmentIdx = _movieFragmentIdx[aTrackId];
3090             MovieFragmentAtom *pMovieFragmentAtom = NULL;
3091 
3092             if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
3093                 pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
3094 
3095             if (pMovieFragmentAtom != NULL)
3096             {
3097                 uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
3098                 if (seqNum == _movieFragmentSeqIdx[aTrackId])
3099                 {
3100                     TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(aTrackId);
3101                     if (trackfragment != NULL)
3102                     {
3103                         if (trackfragment->getTrackId() == aTrackId)
3104                         {
3105                             return (MP4_ERROR_CODE)pMovieFragmentAtom->getNextBundledAccessUnits(aTrackId, &n, totalSampleRead, pgau);
3106                         }
3107                     }
3108                 }
3109             }
3110         }
3111         return READ_FAILED;
3112     }
3113     else
3114     {
3115         return ret;
3116     }
3117 }
3118 
3119 
3120 
getOffsetByTime(uint32 id,uint32 ts,int32 * sampleFileOffset,uint32 jitterbuffertimeinmillisec)3121 int32 Mpeg4File::getOffsetByTime(uint32 id, uint32 ts, int32* sampleFileOffset , uint32 jitterbuffertimeinmillisec)
3122 {
3123     int32 ret =  DEFAULT_ERROR;
3124     uint32 sigmaAtomSize = 0;
3125     if (_pmovieAtom != NULL)
3126     {
3127         ret = _pmovieAtom->getOffsetByTime(id, ts, sampleFileOffset);
3128         if (ret == DEFAULT_ERROR || ret == LAST_SAMPLE_IN_MOOV)
3129         {
3130             if (_isMovieFragmentsPresent)
3131             {
3132                 uint32 sigmaTrafDuration = 0;
3133 
3134                 for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
3135                 {
3136                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
3137                     if (pMovieFragmentAtom != NULL)
3138                     {
3139                         uint32 currTrafDuration = pMovieFragmentAtom->getCurrentTrafDuration(id);
3140                         if (currTrafDuration >= ts)
3141                         {
3142                             pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
3143                             return pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
3144                         }
3145                         sigmaTrafDuration += currTrafDuration;
3146                     }
3147                 }
3148 
3149                 if (_parsing_mode == 1)
3150                 {
3151                     if (moofParsingCompleted)
3152                     {
3153                         // do nothing
3154                     }
3155                     else
3156                     {
3157                         if ((uint32)_pMovieFragmentAtom->getSequenceNumber() == _movieFragmentSeqIdx[id])
3158                         {
3159                             AtomUtils::seekFromStart(_movieFragmentFilePtr, moofPtrPos);
3160 
3161                             while (!moofParsingCompleted)
3162                             {
3163                                 _pMovieFragmentAtom->ParseMoofAtom(_movieFragmentFilePtr, moofSize, moofType, _pTrackDurationContainer, _pTrackExtendsAtomVec, moofParsingCompleted, countOfTrunsParsed);
3164                             }
3165 
3166                             if (moofParsingCompleted)
3167                             {
3168                                 if (!_pMovieFragmentAtom->MP4Success())
3169                                 {
3170                                     _success = false;
3171                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
3172                                 }
3173                                 _pMovieFragmentAtom->setParent(this);
3174                                 moofSize = _pMovieFragmentAtom->getSize();
3175                                 moofCount -= _pMovieFragmentAtom->getSize();
3176                             }
3177 
3178                             uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(id);
3179 
3180                             if (currTrafDuration >= ts)
3181                             {
3182                                 ret = _pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
3183                                 if (*sampleFileOffset == 0)
3184                                 {
3185                                     // do nothing, continue parsing
3186                                 }
3187                                 else
3188                                 {
3189                                     return ret;
3190                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: ret Sample Offset=> Sample Offset= %d ret %d********@@@@@@@@@@@@@@@@", *sampleFileOffset, ret));
3191                                 }
3192                             }
3193                             sigmaTrafDuration += currTrafDuration;
3194                         }
3195                         else
3196                         {
3197                             // This condition will only happen when the MovieFragmentAtomVec size is
3198                             // greater than 1.
3199                             uint32 i = _pMovieFragmentAtomVec->size();
3200                             _ptrMoofEnds = (*_pMoofOffsetVec)[i-2] + (*_pMovieFragmentAtomVec)[i-2]->getSize();
3201                             _pMoofOffsetVec->pop_back();
3202                             _pMovieFragmentAtomVec->pop_back();
3203                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3204                             parseMoofCompletely = true;
3205                             moofParsingCompleted = true;
3206                             moofSize = 0;
3207                             moofType = UNKNOWN_ATOM;
3208                             moofCount = 0;
3209                             moofPtrPos = 0;
3210                         }
3211                     }
3212 
3213                     uint32 fileSize = 0;
3214                     uint32 currfptr = 0;
3215 
3216                     AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
3217                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime::FileSize %d Track ID %d ********@@@@@@@@@@@@@@@@", fileSize, id));
3218 
3219                     AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
3220                     uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3221                     int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
3222                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: TS= %d ********@@@@@@@@@@@@@@@@, count=%d, filePointer=%d", ts, count, filePointer));
3223 
3224                     while (count > 0)
3225                     {
3226                         uint32 atomType = UNKNOWN_ATOM;
3227                         uint32 atomSize = 0;
3228                         AtomUtils::Flush(_movieFragmentFilePtr);
3229                         AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
3230                         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: count=%d, AtomSize=%d, atomtype=%d", count, atomSize, atomType));
3231                         if (atomSize < DEFAULT_ATOM_SIZE)
3232                         {
3233 
3234                             ret = DEFAULT_ERROR;
3235                             break;
3236                         }
3237                         sigmaAtomSize += atomSize;
3238                         if (atomType == MOVIE_FRAGMENT_ATOM)
3239                         {
3240                             uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3241                             moofStartOffset -= DEFAULT_ATOM_SIZE;
3242                             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: MovieFragmentAtom moofStartOffset=%d", moofStartOffset));
3243 
3244                             moofSize = atomSize;
3245 
3246                             if ((moofStartOffset + atomSize) > fileSize)
3247                             {
3248                                 uint32 timeScale = _pmovieAtom->getTrackMediaTimescale(id);
3249                                 if ((timeScale == 0) || (timeScale == 0xFFFFFFFF))
3250                                 {
3251                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Invalid timeScale %d for Id %d", timeScale, id));
3252                                     return DEFAULT_ERROR;
3253                                 }
3254 
3255                                 uint32 trackPlayedSoFarInSec = ts / timeScale - jitterbuffertimeinmillisec / 1000;
3256                                 uint32 rateOfDataUsageKbPerSec = 0;
3257                                 if (trackPlayedSoFarInSec != 0)
3258                                 {
3259                                     rateOfDataUsageKbPerSec = fileSize / trackPlayedSoFarInSec;
3260                                 }
3261                                 // estimate data for PVMF_MP4FFPARSER_PSEUDO_STREAMING_DURATION_IN_SEC
3262                                 uint32 dataNeededAhead = (rateOfDataUsageKbPerSec * jitterbuffertimeinmillisec) / 1000;
3263 
3264                                 *sampleFileOffset = moofStartOffset + atomSize + DEFAULT_ATOM_SIZE + dataNeededAhead;
3265                                 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Insufficient data ot get Sample Offset= %d ********@@@@@@@@@@@@@@@@", *sampleFileOffset));
3266                                 ret =  EVERYTHING_FINE;
3267                                 break;
3268                             }
3269 
3270                             _pMoofOffsetVec->push_back(moofStartOffset);
3271                             parseMoofCompletely = true;
3272 
3273                             PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
3274 
3275                             if (!_pMovieFragmentAtom->MP4Success())
3276                             {
3277 
3278                                 _success = false;
3279                                 _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
3280                                 break;
3281                             }
3282                             count -= _pMovieFragmentAtom->getSize();
3283                             _pMovieFragmentAtom->setParent(this);
3284 
3285                             _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
3286                             _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3287 
3288                             uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(id);
3289 
3290                             if (currTrafDuration >= ts)
3291                             {
3292                                 ret = _pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
3293                                 if (*sampleFileOffset == 0)
3294                                 {
3295                                     // do nothing, continue parsing
3296                                 }
3297                                 else
3298                                 {
3299                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: ret Sample Offset=> Sample Offset= %d ret %d********@@@@@@@@@@@@@@@@", *sampleFileOffset, ret));
3300                                     break;
3301                                 }
3302                             }
3303                             sigmaTrafDuration += currTrafDuration;
3304                         }
3305                         else if (atomType == MEDIA_DATA_ATOM)
3306                         {
3307 
3308                             if (atomSize == 1)
3309                             {
3310                                 uint64 largeSize = 0;
3311                                 AtomUtils::read64(_movieFragmentFilePtr, largeSize);
3312                                 uint32 size =
3313                                     Oscl_Int64_Utils::get_uint64_lower32(largeSize);
3314                                 count -= size;
3315                                 size -= 8; //for large size
3316                                 size -= DEFAULT_ATOM_SIZE;
3317                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
3318                             }
3319                             else
3320                             {
3321                                 currfptr = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3322                                 if ((currfptr + atomSize) > fileSize)
3323                                 {
3324                                     uint32 timeScale = _pmovieAtom->getTrackMediaTimescale(id);
3325                                     if ((timeScale == 0) || (timeScale == 0xFFFFFFFF))
3326                                     {
3327                                         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Invalid timeScale %d for Id %d", timeScale, id));
3328                                         return DEFAULT_ERROR;
3329                                     }
3330                                     uint32 trackPlayedSoFarInSec = ts / timeScale - jitterbuffertimeinmillisec / 1000;
3331                                     uint32 rateOfDataUsageKbPerSec = 0;
3332                                     if (trackPlayedSoFarInSec != 0)
3333                                     {
3334                                         rateOfDataUsageKbPerSec = fileSize / trackPlayedSoFarInSec;
3335                                     }
3336 
3337                                     // estimate data for PVMF_MP4FFPARSER_PSEUDO_STREAMING_DURATION_IN_SEC
3338                                     uint32 dataNeededAhead = (rateOfDataUsageKbPerSec * jitterbuffertimeinmillisec) / 1000;
3339                                     *sampleFileOffset = currfptr + atomSize + moofSize + dataNeededAhead;
3340                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Insufficient data ot get Sample Offset= %d ********@@@@@@@@@@@@@@@@", *sampleFileOffset));
3341                                     ret = EVERYTHING_FINE;
3342                                     break;
3343 
3344                                 }
3345                                 count -= atomSize;
3346                                 atomSize -= DEFAULT_ATOM_SIZE;
3347                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3348                             }
3349                         }
3350 
3351                         else
3352                         {
3353                             if (count > 0)
3354                             {
3355                                 count -= atomSize;
3356                                 atomSize -= DEFAULT_ATOM_SIZE;
3357                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3358                             }
3359                         }
3360                     }
3361                     if (sigmaTrafDuration == 0)
3362                     {
3363                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
3364                         *sampleFileOffset = fileSize + 1000;
3365 
3366                         ret = EVERYTHING_FINE;
3367                     }
3368                 }
3369             }
3370             else if (ret == LAST_SAMPLE_IN_MOOV)
3371             {
3372                 ret = EVERYTHING_FINE;
3373             }
3374 
3375         }
3376 
3377         return ret;
3378     }
3379     else
3380     {
3381 
3382         return ret;
3383     }
3384 }
3385 
getTimestampForRandomAccessPoints(uint32 id,uint32 * num,uint32 * tsBuf,uint32 * numBuf,uint32 * offsetBuf)3386 int32 Mpeg4File::getTimestampForRandomAccessPoints(uint32 id, uint32 *num, uint32 *tsBuf, uint32* numBuf, uint32 *offsetBuf)
3387 {
3388     if (_pmovieAtom != NULL)
3389     {
3390         uint32 requestedSamples = *num, delta = 0, returnedSampleFromMoov = 0;
3391         uint32 ret =  _pmovieAtom->getTimestampForRandomAccessPoints(id, num, tsBuf, numBuf, offsetBuf);
3392         if (ret == 1)
3393         {
3394             returnedSampleFromMoov = *num;
3395             if (requestedSamples != 0)
3396             {
3397                 if (requestedSamples == returnedSampleFromMoov)
3398                     return ret;
3399 
3400                 if (requestedSamples > returnedSampleFromMoov)
3401                 {
3402                     delta = requestedSamples - returnedSampleFromMoov;
3403                 }
3404             }
3405 
3406         }
3407         else
3408             delta = *num;
3409 
3410         if (_isMovieFragmentsPresent)
3411         {
3412             if (_pMovieFragmentRandomAccessAtomVec != NULL)
3413             { // Only one mfra possible in a clip so this loop will run only once
3414                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
3415                 {
3416                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
3417                     ret = pMovieFragmentRandomAccessAtom->getTimestampForRandomAccessPoints(id, &delta, tsBuf, numBuf, offsetBuf, returnedSampleFromMoov);
3418                     *num = delta;
3419                     return ret;
3420                 }
3421 
3422             }
3423         }
3424         return ret;
3425     }
3426     return 0;
3427 }
3428 
getTimestampForRandomAccessPointsBeforeAfter(uint32 id,uint32 ts,uint32 * tsBuf,uint32 * numBuf,uint32 & numsamplestoget,uint32 howManyKeySamples)3429 int32 Mpeg4File::getTimestampForRandomAccessPointsBeforeAfter(uint32 id, uint32 ts, uint32 *tsBuf, uint32* numBuf,
3430         uint32& numsamplestoget,
3431         uint32 howManyKeySamples)
3432 {
3433     if (_pmovieAtom != NULL)
3434     {
3435         int32 ret = _pmovieAtom->getTimestampForRandomAccessPointsBeforeAfter(id, ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples);
3436         if (ret != 1)
3437         {
3438             if (_isMovieFragmentsPresent)
3439             {
3440                 if (_pMovieFragmentRandomAccessAtomVec != NULL)
3441                 { // Only one mfra possible in a clip so this loop will run only once
3442                     for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
3443                     {
3444                         MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
3445                         ret = pMovieFragmentRandomAccessAtom->getTimestampForRandomAccessPointsBeforeAfter(id, ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples);
3446                         return ret;
3447                     }
3448 
3449                 }
3450             }
3451         }
3452         return ret;
3453 
3454     }
3455     else
3456     {
3457         return 0;
3458     }
3459 }
3460 
3461 
3462 
resetAllMovieFragments()3463 void Mpeg4File::resetAllMovieFragments()
3464 {
3465     uint32 trackDuration = 0;
3466     if (_isMovieFragmentsPresent)
3467     {
3468         if (_pMovieFragmentAtomVec != NULL)
3469         {
3470             int numTracks = _pmovieAtom->getNumTracks();
3471             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
3472             if (!trackList)
3473                 return;       // malloc failed
3474 
3475             _pmovieAtom->getTrackWholeIDList(trackList);
3476             for (int32 i = 0; i < numTracks; i++)
3477             {
3478                 uint32 trackID = trackList[i];
3479                 _movieFragmentIdx[trackID] = 0;
3480                 _peekMovieFragmentIdx[trackID] = 0;
3481                 _movieFragmentSeqIdx[trackID] = 1;
3482                 _peekMovieFragmentSeqIdx[trackID] = 1;
3483                 TrackDurationInfo *trackinfo = NULL;
3484                 if (_pTrackDurationContainer != NULL)
3485                 {
3486                     TrackDurationInfo *pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
3487                     if (pTrackDurationInfo != NULL)
3488                     {
3489                         PV_MP4_FF_DELETE(NULL, TrackDurationInfo, pTrackDurationInfo);
3490                         pTrackDurationInfo = NULL;
3491                     }
3492                 }
3493                 trackDuration = Oscl_Int64_Utils::get_uint64_lower32(_pmovieAtom->getTrackMediaDuration(trackID));
3494                 PV_MP4_FF_NEW(fp->auditCB, TrackDurationInfo, (trackDuration, trackID), trackinfo);
3495                 (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i] = trackinfo;
3496             }
3497             oscl_free(trackList);
3498             for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
3499             {
3500                 MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
3501                 if (pMovieFragmentAtom != NULL)
3502                     pMovieFragmentAtom->resetPlayback();
3503 
3504             }
3505         }
3506     }
3507 }
3508 
3509 
resetPlayback(uint32 time,uint16 numTracks,uint32 * trackList,bool bResetToIFrame)3510 uint32 Mpeg4File::resetPlayback(uint32 time, uint16 numTracks, uint32 *trackList, bool bResetToIFrame)
3511 {
3512     OSCL_UNUSED_ARG(numTracks);
3513 
3514     uint32 modifiedTimeStamp = time;
3515     uint32 trackID = 0;
3516 
3517     uint32 retVal = 0;
3518     bool oMoofFound = false;
3519 
3520     uint32 convertedTS = 0;
3521     uint32 timestamp = 0, returnedTS = 0;
3522 
3523     uint32 moof_offset = 0, traf_number = 0, trun_number = 0, sample_num = 0;
3524 
3525     trackID = *trackList; //  numTracks is the track index in trackList
3526     if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
3527     {
3528         _oVideoTrackPresent = true;
3529     }
3530 
3531     if (_isMovieFragmentsPresent)
3532     {
3533         if (_pMovieFragmentAtomVec->size() > 1)
3534         {
3535             // The boolean is used to reset all MOOFs to start after reposition. This should
3536             // be true only when number of MOOFs in MOOF vector queue is more than one.
3537             isResetPlayBackCalled = true;
3538         }
3539     }
3540 
3541     if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
3542     {
3543         if (repositionFromMoof(time, trackID))
3544         {
3545             //moof
3546             modifiedTimeStamp = time;
3547 
3548             // convert modifiedTimeStamp (which is in ms) to the appropriate
3549             // media time scale
3550             MediaClockConverter mcc1(1000);
3551             mcc1.update_clock(modifiedTimeStamp);
3552             convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
3553             if (oMfraFound)
3554             {
3555                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
3556                 {
3557                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
3558                     uint32 ret = pMovieFragmentRandomAccessAtom->getSyncSampleInfoClosestToTime(trackID, convertedTS, moof_offset, traf_number, trun_number, sample_num);
3559                     if (ret == 0)
3560                     {
3561                         if (moofParsingCompleted)
3562                         {
3563                             // do nothing
3564                         }
3565                         else
3566                         {
3567                             uint32 i = _pMovieFragmentAtomVec->size();
3568                             _pMoofOffsetVec->pop_back();
3569                             _pMovieFragmentAtomVec->pop_back();
3570                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3571                             parseMoofCompletely = true;
3572                             moofParsingCompleted = true;
3573                             moofSize = 0;
3574                             moofType = UNKNOWN_ATOM;
3575                             moofCount = 0;
3576                             moofPtrPos = 0;
3577                         }
3578 
3579                         for (uint32 idx = 0; idx < _pMoofOffsetVec->size(); idx++)
3580                         {
3581                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
3582                             if (moof_start_offset == moof_offset)
3583                             {
3584                                 _movieFragmentIdx[trackID] = idx;
3585                                 _peekMovieFragmentIdx[trackID] = idx;
3586                                 _movieFragmentSeqIdx[trackID] = (*_pMovieFragmentAtomVec)[idx]->getSequenceNumber();
3587                                 _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
3588                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
3589                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3590                                 oMoofFound = true;
3591 
3592                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_offset);
3593                                 uint32 atomType = UNKNOWN_ATOM;
3594                                 uint32 atomSize = 0;
3595                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
3596                                 if (atomType == MOVIE_FRAGMENT_ATOM)
3597                                 {
3598                                     atomSize -= DEFAULT_ATOM_SIZE;
3599                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3600                                     _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3601                                 }
3602                                 break;
3603                             }
3604                         }
3605 
3606                         if (_parsing_mode == 1)
3607                         {
3608                             if (!oMoofFound)
3609                             {
3610                                 uint32 fileSize = 0;
3611                                 _ptrMoofEnds = moof_offset;
3612                                 AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
3613                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
3614                                 uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3615                                 int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
3616 
3617                                 while (count > 0)
3618                                 {
3619                                     uint32 atomType = UNKNOWN_ATOM;
3620                                     uint32 atomSize = 0;
3621                                     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
3622                                     if (atomType == MOVIE_FRAGMENT_ATOM)
3623                                     {
3624                                         parseMoofCompletely = true;
3625 
3626                                         uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3627                                         moofStartOffset -= DEFAULT_ATOM_SIZE;
3628 
3629                                         if (moofParsingCompleted)
3630                                         {
3631                                             // do nothing
3632                                         }
3633                                         else
3634                                         {
3635                                             uint32 i = _pMovieFragmentAtomVec->size();
3636                                             _pMoofOffsetVec->pop_back();
3637                                             _pMovieFragmentAtomVec->pop_back();
3638                                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3639                                             parseMoofCompletely = true;
3640                                             moofParsingCompleted = true;
3641                                             moofSize = 0;
3642                                             moofType = UNKNOWN_ATOM;
3643                                             moofCount = 0;
3644                                             moofPtrPos = 0;
3645                                         }
3646 
3647                                         PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
3648 
3649                                         if (!_pMovieFragmentAtom->MP4Success())
3650                                         {
3651                                             _success = false;
3652                                             _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
3653                                             break;
3654                                         }
3655 
3656                                         _pMovieFragmentAtom->setParent(this);
3657                                         count -= _pMovieFragmentAtom->getSize();
3658 
3659                                         uint32 i = _pMovieFragmentAtomVec->size();
3660 
3661                                         MovieFragmentAtom *pMovieFragmentAtom = NULL;
3662                                         uint32 prevMoofSeqNum = 0;
3663 
3664                                         if (i > 0)
3665                                         {
3666                                             pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[i-1];
3667 
3668                                             if (pMovieFragmentAtom != NULL)
3669                                                 prevMoofSeqNum = (*_pMovieFragmentAtomVec)[i-1]->getSequenceNumber();
3670                                         }
3671 
3672                                         currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3673 
3674                                         for (uint32 idx = prevMoofSeqNum; idx < currMoofNum - 1; idx++)
3675                                         {
3676                                             _pMovieFragmentAtomVec->push_back(NULL);
3677                                             _pMoofOffsetVec->push_back(0);
3678                                         }
3679                                         if (currMoofNum > i)
3680                                         {
3681                                             _pMoofOffsetVec->push_back(moofStartOffset);
3682                                             _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
3683                                         }
3684                                         else if ((*_pMovieFragmentAtomVec)[currMoofNum-1] == NULL)
3685                                         {
3686                                             (*_pMovieFragmentAtomVec)[currMoofNum-1] = _pMovieFragmentAtom;
3687                                             (*_pMoofOffsetVec)[currMoofNum-1] = moofStartOffset;
3688                                         }
3689                                         else
3690                                         {
3691                                             PV_MP4_FF_DELETE(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, _pMovieFragmentAtom);
3692                                             _pMovieFragmentAtom = NULL;
3693                                             break;
3694 
3695                                         }
3696                                         _movieFragmentSeqIdx[trackID] = currMoofNum;
3697                                         _movieFragmentIdx[trackID] = currMoofNum - 1;
3698                                         _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
3699                                         _peekMovieFragmentSeqIdx[trackID] = currMoofNum;
3700 
3701                                         oMoofFound = true;
3702 
3703                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3704                                         break;
3705                                     }
3706                                     else if (atomType == MEDIA_DATA_ATOM)
3707                                     {
3708                                         if (atomSize == 1)
3709                                         {
3710                                             uint64 largeSize = 0;
3711                                             AtomUtils::read64(_movieFragmentFilePtr, largeSize);
3712                                             uint32 size =
3713                                                 Oscl_Int64_Utils::get_uint64_lower32(largeSize);
3714                                             count -= size;
3715                                             size -= 8; //for large size
3716                                             size -= DEFAULT_ATOM_SIZE;
3717                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
3718                                         }
3719                                         else
3720                                         {
3721                                             if (atomSize < DEFAULT_ATOM_SIZE)
3722                                             {
3723                                                 _success = false;
3724                                                 _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
3725                                                 break;
3726                                             }
3727                                             if (count < (int32)atomSize)
3728                                             {
3729                                                 _success = false;
3730                                                 _mp4ErrorCode = READ_FAILED;
3731                                                 break;
3732                                             }
3733                                             count -= atomSize;
3734                                             atomSize -= DEFAULT_ATOM_SIZE;
3735                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3736                                         }
3737                                     }
3738 
3739                                     else
3740                                     {
3741                                         if (count > 0)
3742                                         {
3743                                             count -= atomSize;
3744                                             atomSize -= DEFAULT_ATOM_SIZE;
3745                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3746                                         }
3747 
3748                                     }
3749                                 }
3750                             }
3751 
3752                         }
3753 
3754                         if (_pmovieAtom != NULL)
3755                             _pmovieAtom->resetTrackToEOT();
3756 
3757                         if (_pMovieFragmentAtom != NULL)
3758                             returnedTS = _pMovieFragmentAtom->resetPlayback(trackID, convertedTS, traf_number, trun_number, sample_num);
3759                     }
3760                     else
3761                     {
3762                         // Not a valid tfra entries, cannot reposition.
3763                         return 0;
3764                     }
3765                 }
3766 
3767             }
3768             else
3769                 return 0;
3770 
3771             // convert returnedTS (which is in media time scale) to the ms
3772             MediaClockConverter mcc(getTrackMediaTimescale(trackID));
3773             mcc.update_clock(returnedTS);
3774             timestamp = mcc.get_converted_ts(1000);
3775 
3776             if (timestamp <= modifiedTimeStamp)
3777             {
3778                 modifiedTimeStamp = timestamp;
3779             }
3780 
3781         }
3782         else
3783         {
3784             if (_isMovieFragmentsPresent)
3785             {
3786                 if (_pMovieFragmentAtomVec->size() > 0)
3787                 {
3788                     if (moofParsingCompleted)
3789                     {
3790                         // do nothing
3791                     }
3792                     else
3793                     {
3794                         uint32 i = _pMovieFragmentAtomVec->size();
3795                         _pMoofOffsetVec->pop_back();
3796                         _pMovieFragmentAtomVec->pop_back();
3797                         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3798                         parseMoofCompletely = true;
3799                         moofParsingCompleted = true;
3800                         moofSize = 0;
3801                         moofType = UNKNOWN_ATOM;
3802                         moofCount = 0;
3803                         moofPtrPos = 0;
3804                     }
3805                 }
3806             }
3807 
3808             //movie
3809             if (_pmovieAtom != NULL)
3810             {
3811                 resetAllMovieFragments();
3812                 uint32 trackVideo = trackID;
3813                 uint32 numTrackForVideo = 1;
3814                 modifiedTimeStamp =  _pmovieAtom->resetPlayback(modifiedTimeStamp, numTrackForVideo, &trackVideo, bResetToIFrame);
3815             }
3816         }
3817     }
3818     retVal = modifiedTimeStamp;
3819     if ((getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO) ||
3820             (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT))
3821     {
3822         if (repositionFromMoof(time, trackID))
3823         {
3824             oMoofFound = false;
3825             //moof
3826             // convert modifiedTimeStamp (which is in ms) to the appropriate
3827             // media time scale
3828             MediaClockConverter mcc1(1000);
3829             mcc1.update_clock(modifiedTimeStamp);
3830             convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
3831             if (oMfraFound)
3832             {
3833                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
3834                 {
3835                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
3836                     uint32 ret = pMovieFragmentRandomAccessAtom->getSyncSampleInfoClosestToTime(trackID, convertedTS, moof_offset, traf_number, trun_number, sample_num);
3837                     if (ret == 0)
3838                     {
3839                         if (moofParsingCompleted)
3840                         {
3841                             // do nothing
3842                         }
3843                         else
3844                         {
3845                             uint32 i = _pMovieFragmentAtomVec->size();
3846                             _pMoofOffsetVec->pop_back();
3847                             _pMovieFragmentAtomVec->pop_back();
3848                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3849                             parseMoofCompletely = true;
3850                             moofParsingCompleted = true;
3851                             moofSize = 0;
3852                             moofType = UNKNOWN_ATOM;
3853                             moofCount = 0;
3854                             moofPtrPos = 0;
3855                         }
3856                         //
3857                         for (idx = 0; idx < _pMoofOffsetVec->size(); idx++)
3858                         {
3859                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
3860                             if (moof_start_offset == moof_offset)
3861                             {
3862                                 _movieFragmentIdx[trackID] = idx;
3863                                 _peekMovieFragmentIdx[trackID] = idx;
3864                                 _movieFragmentSeqIdx[trackID] = (*_pMovieFragmentAtomVec)[idx]->getSequenceNumber();
3865                                 _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
3866                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
3867                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3868                                 oMoofFound = true;
3869 
3870                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_offset);
3871                                 uint32 atomType = UNKNOWN_ATOM;
3872                                 uint32 atomSize = 0;
3873                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
3874                                 if (atomType == MOVIE_FRAGMENT_ATOM)
3875                                 {
3876                                     atomSize -= DEFAULT_ATOM_SIZE;
3877                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
3878                                     _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3879                                 }
3880                                 break;
3881                             }
3882                         }
3883                         //
3884                     }
3885                     else
3886                     {
3887                         // Not a valid tfra entries, cannot reposition.
3888                         return 0;
3889                     }
3890                 }
3891                 if (_parsing_mode == 1 && !oMoofFound)
3892                 {
3893 
3894                     if (!oMoofFound)
3895                     {
3896                         _ptrMoofEnds = moof_offset;
3897                         uint32 fileSize = 0;
3898                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
3899                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
3900                         uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3901                         int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
3902 
3903                         while (count > 0)
3904                         {
3905                             uint32 atomType = UNKNOWN_ATOM;
3906                             uint32 atomSize = 0;
3907                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
3908                             if (atomType == MOVIE_FRAGMENT_ATOM)
3909                             {
3910                                 uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3911                                 moofStartOffset -= DEFAULT_ATOM_SIZE;
3912                                 parseMoofCompletely = true;
3913 
3914                                 if (moofParsingCompleted)
3915                                 {
3916                                     // do nothing
3917                                 }
3918                                 else
3919                                 {
3920                                     uint32 i = _pMovieFragmentAtomVec->size();
3921                                     _pMoofOffsetVec->pop_back();
3922                                     _pMovieFragmentAtomVec->pop_back();
3923                                     PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
3924                                     parseMoofCompletely = true;
3925                                     moofParsingCompleted = true;
3926                                     moofSize = 0;
3927                                     moofType = UNKNOWN_ATOM;
3928                                     moofCount = 0;
3929                                     moofPtrPos = 0;
3930                                 }
3931 
3932                                 PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
3933 
3934                                 if (!_pMovieFragmentAtom->MP4Success())
3935                                 {
3936                                     _success = false;
3937                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
3938                                     break;
3939                                 }
3940 
3941                                 _pMovieFragmentAtom->setParent(this);
3942                                 count -= _pMovieFragmentAtom->getSize();
3943                                 uint32 i = _pMovieFragmentAtomVec->size();
3944 
3945                                 MovieFragmentAtom *pMovieFragmentAtom = NULL;
3946                                 uint32 prevMoofSeqNum = 0;
3947 
3948                                 if (i > 0)
3949                                 {
3950                                     pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[i-1];
3951 
3952                                     if (pMovieFragmentAtom != NULL)
3953                                         prevMoofSeqNum = (*_pMovieFragmentAtomVec)[i-1]->getSequenceNumber();
3954                                 }
3955                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3956 
3957                                 for (uint32 idx = prevMoofSeqNum; idx < currMoofNum - 1; idx++)
3958                                 {
3959                                     _pMovieFragmentAtomVec->push_back(NULL);
3960                                     _pMoofOffsetVec->push_back(0);
3961                                 }
3962 
3963                                 if (currMoofNum > i)
3964                                 {
3965                                     _pMoofOffsetVec->push_back(moofStartOffset);
3966                                     _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
3967                                 }
3968                                 else if ((*_pMovieFragmentAtomVec)[currMoofNum-1] == NULL)
3969                                 {
3970                                     (*_pMovieFragmentAtomVec)[currMoofNum-1] = _pMovieFragmentAtom;
3971                                     (*_pMoofOffsetVec)[currMoofNum-1] = moofStartOffset;
3972                                 }
3973                                 else
3974                                 {
3975                                     PV_MP4_FF_DELETE(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, _pMovieFragmentAtom);
3976                                     _pMovieFragmentAtom = NULL;
3977                                     break;
3978 
3979                                 }
3980                                 if (oMfraFound)
3981                                 {
3982                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3983                                     _movieFragmentIdx[trackID] = currMoofNum - 1 ;
3984                                     _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
3985                                     _movieFragmentSeqIdx[trackID] = currMoofNum;
3986                                     _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
3987                                     oMoofFound = true;
3988                                     if (!_oVideoTrackPresent)
3989                                     {
3990                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
3991                                     }
3992                                     break;
3993                                 }
3994                                 uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(trackID);
3995                                 if (currTrafDuration >= modifiedTimeStamp)
3996                                 {
3997                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
3998                                     _movieFragmentIdx[trackID] = currMoofNum - 1;
3999                                     _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
4000                                     _movieFragmentSeqIdx[trackID] = currMoofNum;
4001                                     _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
4002                                     oMoofFound = true;
4003                                     if (!_oVideoTrackPresent)
4004                                     {
4005                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
4006                                     }
4007                                     break;
4008                                 }
4009 
4010                             }
4011                             else if (atomType == MEDIA_DATA_ATOM)
4012                             {
4013                                 if (atomSize == 1)
4014                                 {
4015                                     uint64 largeSize = 0;
4016                                     AtomUtils::read64(_movieFragmentFilePtr, largeSize);
4017                                     uint32 size =
4018                                         Oscl_Int64_Utils::get_uint64_lower32(largeSize);
4019                                     count -= size;
4020                                     size -= 8; //for large size
4021                                     size -= DEFAULT_ATOM_SIZE;
4022                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
4023                                 }
4024                                 else
4025                                 {
4026                                     if (atomSize < DEFAULT_ATOM_SIZE)
4027                                     {
4028                                         _success = false;
4029                                         _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
4030                                         break;
4031                                     }
4032                                     if (count < (int32)atomSize)
4033                                     {
4034                                         _success = false;
4035                                         _mp4ErrorCode = READ_FAILED;
4036                                         break;
4037                                     }
4038                                     count -= atomSize;
4039                                     atomSize -= DEFAULT_ATOM_SIZE;
4040                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
4041                                 }
4042                             }
4043 
4044                             else
4045                             {
4046                                 if (count > 0)
4047                                 {
4048                                     count -= atomSize;
4049                                     atomSize -= DEFAULT_ATOM_SIZE;
4050                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
4051                                 }
4052 
4053                             }
4054                         }
4055                     }
4056 
4057                 }
4058 
4059                 if (_pmovieAtom != NULL)
4060                     _pmovieAtom->resetTrackToEOT();
4061 
4062                 if (_pMovieFragmentAtom != NULL)
4063                     returnedTS = _pMovieFragmentAtom->resetPlayback(trackID, convertedTS, traf_number, trun_number, sample_num);
4064             }
4065             else
4066                 return 0;
4067 
4068             // convert returnedTS (which is in media time scale) to the ms
4069             MediaClockConverter mcc(getTrackMediaTimescale(trackID));
4070             mcc.update_clock(returnedTS);
4071             timestamp = mcc.get_converted_ts(1000);
4072 
4073 
4074             if (timestamp <= modifiedTimeStamp)
4075             {
4076                 modifiedTimeStamp = timestamp;
4077             }
4078             retVal = modifiedTimeStamp;
4079 
4080         }
4081         else
4082         {
4083             if (_isMovieFragmentsPresent)
4084             {
4085                 if (_pMovieFragmentAtomVec->size() > 0)
4086                 {
4087                     if (moofParsingCompleted)
4088                     {
4089                         // do nothing
4090                     }
4091                     else
4092                     {
4093                         uint32 i = _pMovieFragmentAtomVec->size();
4094                         _pMoofOffsetVec->pop_back();
4095                         _pMovieFragmentAtomVec->pop_back();
4096                         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
4097                         parseMoofCompletely = true;
4098                         moofParsingCompleted = true;
4099                         moofSize = 0;
4100                         moofType = UNKNOWN_ATOM;
4101                         moofCount = 0;
4102                         moofPtrPos = 0;
4103                     }
4104                 }
4105             }
4106 
4107             //movie
4108             if (_pmovieAtom != NULL)
4109             {
4110                 resetAllMovieFragments();
4111                 uint32 trackAudio = trackID;
4112                 uint32 numTrackforAudio = 1;
4113                 retVal = _pmovieAtom->resetPlayback(modifiedTimeStamp, numTrackforAudio, &trackAudio
4114                                                     , bResetToIFrame);
4115             }
4116         }
4117 
4118     }
4119     return retVal;
4120 
4121 }
4122 
4123 
4124 
queryRepositionTime(uint32 time,uint16 numTracks,uint32 * trackList,bool bResetToIFrame,bool bBeforeRequestedTime)4125 int32 Mpeg4File::queryRepositionTime(uint32 time,
4126                                      uint16 numTracks,
4127                                      uint32 *trackList,
4128                                      bool bResetToIFrame,
4129                                      bool bBeforeRequestedTime)
4130 {
4131 
4132     uint32 i = 0;
4133     uint32 ret = 0;
4134     uint32 modifiedTimeStamp = time;
4135     uint32 trackID = 0;
4136     uint32 trackIds[256];
4137 
4138     bool oVideoTrackFound = false;
4139     int j = 1;
4140     for (i = 0; i < numTracks; i++)
4141     {
4142         trackID = trackList[i];
4143         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
4144         {
4145             trackIds[0] = trackList[i];
4146             oVideoTrackFound = true;
4147         }
4148         else
4149         {
4150             trackIds[j++] = trackList[i];
4151         }
4152     }
4153 
4154     uint32 convertedTS = 0;
4155     uint32 timestamp = 0, returnedTS = 0;
4156 
4157     for (i = 0; i < numTracks; i++)
4158     {
4159         trackID = trackIds[i];
4160 
4161         if (!oVideoTrackFound)
4162             trackID = trackList[i];
4163 
4164         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
4165         {
4166             if (repositionFromMoof(time, trackID))
4167             {
4168                 //moof
4169                 modifiedTimeStamp = time;
4170 
4171                 // convert modifiedTimeStamp (which is in ms) to the appropriate
4172                 // media time scale
4173                 MediaClockConverter mcc1(1000);
4174                 mcc1.update_clock(modifiedTimeStamp);
4175                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
4176                 if (oMfraFound)
4177                 {
4178                     oMfraFound = true;
4179                     for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
4180                     {
4181 
4182                         MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
4183                         returnedTS = pMovieFragmentRandomAccessAtom->queryRepositionTime(trackID, convertedTS, bResetToIFrame,
4184                                      bBeforeRequestedTime);
4185                         if (returnedTS != 0)
4186                         {
4187                             break;
4188                         }
4189                     }
4190                 }
4191                 else
4192                 {
4193                     oMfraFound = false;
4194                     if (_parsing_mode == 1)
4195                         return -1;
4196                 }
4197 
4198                 // convert returnedTS (which is in media time scale) to the ms
4199                 MediaClockConverter mcc(getTrackMediaTimescale(trackID));
4200                 mcc.update_clock(returnedTS);
4201                 timestamp = mcc.get_converted_ts(1000);
4202 
4203                 modifiedTimeStamp = timestamp;
4204 
4205                 ret = modifiedTimeStamp;
4206 
4207             }
4208             else
4209             {
4210                 //movie
4211                 if (_pmovieAtom != NULL)
4212                 {
4213                     modifiedTimeStamp =  _pmovieAtom->queryRepositionTime(time,
4214                                          numTracks,
4215                                          trackList,
4216                                          bResetToIFrame,
4217                                          bBeforeRequestedTime);
4218                     ret = modifiedTimeStamp;
4219                 }
4220             }
4221         }
4222 
4223         if ((getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO) ||
4224                 (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT))
4225         {
4226             if (repositionFromMoof(time, trackID))
4227             {
4228                 //moof
4229                 MediaClockConverter mcc1(1000);
4230                 mcc1.update_clock(modifiedTimeStamp);
4231                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
4232 
4233                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
4234                 {
4235 
4236                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
4237                     returnedTS = pMovieFragmentRandomAccessAtom->queryRepositionTime(trackID, convertedTS, bResetToIFrame,
4238                                  bBeforeRequestedTime);
4239                     if (returnedTS != 0)
4240                     {
4241                         break;
4242                     }
4243                 }
4244                 // convert returnedTS (which is in media time scale) to the ms
4245                 MediaClockConverter mcc(getTrackMediaTimescale(trackID));
4246                 mcc.update_clock(returnedTS);
4247                 timestamp = mcc.get_converted_ts(1000);
4248 
4249                 if (!oVideoTrackFound)
4250                 {
4251                     if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
4252                     {
4253                         modifiedTimeStamp = timestamp;
4254                     }
4255                     else if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT && numTracks == 1)
4256                     {
4257                         modifiedTimeStamp = timestamp;
4258                     }
4259                 }
4260 
4261                 return modifiedTimeStamp;
4262 
4263             }
4264             else
4265             {
4266                 //movie
4267                 if (_pmovieAtom != NULL)
4268                 {
4269                     modifiedTimeStamp =   _pmovieAtom->queryRepositionTime(modifiedTimeStamp,
4270                                           numTracks,
4271                                           trackList,
4272                                           bResetToIFrame,
4273                                           bBeforeRequestedTime);
4274 
4275                     if (!oVideoTrackFound)
4276                     {
4277                         if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
4278                         {
4279                             ret = modifiedTimeStamp;
4280                         }
4281                         else if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT && numTracks == 1)
4282                         {
4283                             ret = modifiedTimeStamp;
4284                         }
4285                     }
4286                 }
4287 
4288             }
4289 
4290         }
4291     }
4292     return ret;
4293 }
4294 
4295 
4296 
parseMFRA()4297 int32 Mpeg4File::parseMFRA()
4298 {
4299     uint32 ret = 0;
4300     uint32 fileSize = 0;
4301     uint32 MfraStartOffset = 0;
4302     AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
4303     AtomUtils::seekFromStart(_movieFragmentFilePtr, fileSize);
4304     AtomUtils::rewindFilePointerByN(_movieFragmentFilePtr, 16);
4305 
4306     uint32 atomType = UNKNOWN_ATOM;
4307     uint32 atomSize = 0;
4308     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
4309 
4310     if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_OFFSET_ATOM)
4311     {
4312         if (_pMfraOffsetAtom == NULL)
4313         {
4314             PV_MP4_FF_NEW(fp->auditCB, MfraOffsetAtom, (_movieFragmentFilePtr, atomSize, atomType), _pMfraOffsetAtom);
4315             if (!_pMfraOffsetAtom->MP4Success())
4316             {
4317                 _success = false;
4318                 _mp4ErrorCode = READ_MOVIE_FRAGMENT_RANDOM_ACCESS_OFFSET_FAILED;
4319                 return _mp4ErrorCode;
4320             }
4321             MfraStartOffset = _pMfraOffsetAtom->getSizeStoredInmfro();
4322 
4323         }
4324     }
4325     AtomUtils::rewindFilePointerByN(_movieFragmentFilePtr, MfraStartOffset);
4326     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
4327     if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_ATOM)
4328     {
4329         if (_pMovieFragmentRandomAccessAtomVec->size() == 0)
4330         {
4331             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = NULL;
4332             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentRandomAccessAtom, (_movieFragmentFilePtr, atomSize, atomType), pMovieFragmentRandomAccessAtom);
4333 
4334             if (!pMovieFragmentRandomAccessAtom->MP4Success())
4335             {
4336                 PV_MP4_FF_DELETE(NULL, MovieFragmentRandomAccessAtom, pMovieFragmentRandomAccessAtom);
4337                 _success = false;
4338                 _mp4ErrorCode = pMovieFragmentRandomAccessAtom->GetMP4Error();
4339                 return _mp4ErrorCode ;
4340             }
4341             pMovieFragmentRandomAccessAtom->setParent(this);
4342             _pMovieFragmentRandomAccessAtomVec->push_back(pMovieFragmentRandomAccessAtom);
4343             oMfraFound = true;
4344         }
4345     }
4346 
4347     return ret;
4348 
4349 }
4350 
4351 
peekNextBundledAccessUnits(const uint32 trackID,uint32 * n,MediaMetaInfo * mInfo)4352 int32 Mpeg4File::peekNextBundledAccessUnits(const uint32 trackID,
4353         uint32 *n,
4354         MediaMetaInfo *mInfo)
4355 {
4356     // IF THERE ARE NO MEDIA TRACKS, RETURN READ ERROR
4357     uint32 samplesTobeRead;
4358     samplesTobeRead = *n;
4359     uint32 totalSampleRead = 0;
4360     if (getNumTracks() == 0)
4361     {
4362         return -1;
4363     }
4364     if (_pmovieAtom != NULL)
4365     {
4366         uint32 ret = (_pmovieAtom->peekNextBundledAccessUnits(trackID, n, mInfo));
4367         if (ret == END_OF_TRACK)
4368         {
4369             if (!_isMovieFragmentsPresent)
4370                 return ret;
4371 
4372             bool oAllMoofExhausted = false;
4373 
4374             totalSampleRead += *n;
4375 
4376             if (totalSampleRead == samplesTobeRead)
4377             {
4378                 *n = totalSampleRead;
4379                 return EVERYTHING_FINE;
4380             }
4381 
4382             if (_pMovieFragmentAtomVec != NULL)
4383             {
4384                 if (samplesTobeRead >= *n)
4385                     *n = samplesTobeRead - *n;
4386                 if (*n == 0)
4387                     *n = samplesTobeRead;
4388             }
4389             else
4390                 return ret;
4391 
4392             if (_parsing_mode == 0)
4393             {
4394                 int32 return1 = 0;
4395                 while (_peekMovieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
4396                 {
4397                     uint32 peekMovieFragmentIdx = _peekMovieFragmentIdx[trackID];
4398                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[peekMovieFragmentIdx];
4399                     if (pMovieFragmentAtom != NULL)
4400                     {
4401                         if ((uint32)pMovieFragmentAtom->getSequenceNumber() == _peekMovieFragmentSeqIdx[trackID])
4402                         {
4403                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
4404                             if (trackfragment != NULL)
4405                             {
4406                                 if (trackfragment->getTrackId() == trackID)
4407                                 {
4408                                     return1 = pMovieFragmentAtom->peekNextBundledAccessUnits(trackID, n, totalSampleRead, mInfo);
4409                                     totalSampleRead += *n;
4410                                     if (return1 != END_OF_TRACK)
4411                                     {
4412                                         *n = totalSampleRead;
4413                                         return return1;
4414                                     }
4415                                     else
4416                                     {
4417                                         _peekMovieFragmentSeqIdx[trackID]++;
4418                                         if (samplesTobeRead >= *n)
4419                                         {
4420                                             samplesTobeRead = samplesTobeRead - *n;
4421                                             *n = samplesTobeRead;
4422                                         }
4423                                     }
4424                                 }
4425                             }
4426                         }
4427                     }
4428                     _peekMovieFragmentIdx[trackID]++;
4429                 }
4430                 if (return1 == END_OF_TRACK)
4431                 {
4432                     *n = totalSampleRead;
4433                     _peekMovieFragmentIdx[trackID] = 0;
4434                     _peekMovieFragmentSeqIdx[trackID] = 1;
4435                     return return1;
4436                 }
4437             }
4438             else
4439             {
4440 
4441                 while (!oAllMoofExhausted)
4442                 {
4443                     uint32 moofIndex = 0;
4444                     bool moofToBeParsed = false;
4445 
4446                     if (_pMovieFragmentAtomVec->size() > _peekMovieFragmentIdx[trackID])
4447                     {
4448                         MovieFragmentAtom *pMovieFragmentAtom = NULL;
4449                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[_peekMovieFragmentIdx[trackID]];
4450                         if (pMovieFragmentAtom == NULL)
4451                         {
4452                             moofToBeParsed = true;
4453                             moofIndex = _peekMovieFragmentIdx[trackID];
4454                         }
4455                     }
4456                     if ((_pMovieFragmentAtomVec->size() <= _peekMovieFragmentIdx[trackID]) || moofToBeParsed)
4457                     {
4458                         uint32 fileSize = 0;
4459                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
4460                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
4461                         uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
4462                         int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
4463 
4464                         while (count > 0)
4465                         {
4466                             uint32 atomType = UNKNOWN_ATOM;
4467                             uint32 atomSize = 0;
4468                             uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
4469                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
4470                             if ((currPos + atomSize) > fileSize)
4471                             {
4472                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
4473                                 return  INSUFFICIENT_DATA;
4474                             }
4475                             if (atomType == MOVIE_FRAGMENT_ATOM)
4476                             {
4477                                 uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
4478                                 moofStartOffset -= DEFAULT_ATOM_SIZE;
4479 
4480                                 parseMoofCompletely = true;
4481 
4482                                 PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
4483 
4484                                 if (!_pMovieFragmentAtom->MP4Success())
4485                                 {
4486                                     _success = false;
4487                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
4488                                     oAllMoofExhausted = true;
4489                                     break;
4490                                 }
4491                                 _pMovieFragmentAtom->setParent(this);
4492                                 count -= _pMovieFragmentAtom->getSize();
4493                                 if (moofToBeParsed)
4494                                 {
4495                                     (*_pMovieFragmentAtomVec)[moofIndex] = _pMovieFragmentAtom;
4496                                     (*_pMoofOffsetVec)[moofIndex] = moofStartOffset;
4497                                 }
4498                                 else
4499                                 {
4500                                     _pMoofOffsetVec->push_back(moofStartOffset);
4501                                     _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
4502                                 }
4503                                 _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
4504 
4505                                 break;
4506                             }
4507                             else if (atomType == MEDIA_DATA_ATOM)
4508                             {
4509                                 if (atomSize == 1)
4510                                 {
4511                                     uint64 largeSize = 0;
4512                                     AtomUtils::read64(_movieFragmentFilePtr, largeSize);
4513                                     uint32 size =
4514                                         Oscl_Int64_Utils::get_uint64_lower32(largeSize);
4515                                     count -= size;
4516                                     size -= 8; //for large size
4517                                     size -= DEFAULT_ATOM_SIZE;
4518                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
4519                                 }
4520                                 else
4521                                 {
4522                                     if (atomSize < DEFAULT_ATOM_SIZE)
4523                                     {
4524                                         _success = false;
4525                                         oAllMoofExhausted = true;
4526                                         _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
4527                                         break;
4528                                     }
4529                                     if (count < (int32)atomSize)
4530                                     {
4531                                         _success = false;
4532                                         oAllMoofExhausted = true;
4533                                         _mp4ErrorCode = INSUFFICIENT_DATA;
4534                                         AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
4535                                         ret = _mp4ErrorCode;
4536                                         break;
4537                                     }
4538                                     count -= atomSize;
4539                                     atomSize -= DEFAULT_ATOM_SIZE;
4540                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
4541                                 }
4542                             }
4543 
4544                             else
4545                             {
4546                                 if (count > 0)
4547                                 {
4548                                     count -= atomSize;
4549                                     atomSize -= DEFAULT_ATOM_SIZE;
4550                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
4551                                 }
4552                                 break;
4553                             }
4554                         }
4555                         if (count <= 0)
4556                         {
4557                             oAllMoofExhausted = true;
4558                             if (_pMovieFragmentAtomVec->size() < _peekMovieFragmentIdx[trackID])
4559                                 break;
4560                         }
4561                     }
4562 
4563                     int32 return1 = 0;
4564                     MovieFragmentAtom *pMovieFragmentAtom = NULL;
4565                     uint32 movieFragmentIdx = _peekMovieFragmentIdx[trackID];
4566 
4567                     if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
4568                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
4569 
4570                     if (pMovieFragmentAtom != NULL)
4571                     {
4572                         uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
4573                         if (seqNum == _peekMovieFragmentSeqIdx[trackID])
4574                         {
4575                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
4576                             if (trackfragment != NULL)
4577                             {
4578                                 if (trackfragment->getTrackId() == trackID)
4579                                 {
4580                                     return1 = pMovieFragmentAtom->peekNextBundledAccessUnits(trackID, n, totalSampleRead, mInfo);
4581                                     totalSampleRead += *n;
4582                                     if (return1 != END_OF_TRACK)
4583                                     {
4584                                         *n = totalSampleRead;
4585                                         return return1;
4586                                     }
4587                                     else
4588                                     {
4589                                         _peekMovieFragmentSeqIdx[trackID]++;
4590                                         if (samplesTobeRead >= *n)
4591                                         {
4592                                             samplesTobeRead = samplesTobeRead - *n;
4593                                             *n = samplesTobeRead;
4594                                         }
4595                                     }
4596                                 }
4597                             }
4598                             else
4599                             {
4600                                 _peekMovieFragmentIdx[trackID]++;
4601                                 _peekMovieFragmentSeqIdx[trackID]++;
4602                                 *n = 0;
4603                                 return NO_SAMPLE_IN_CURRENT_MOOF;
4604                             }
4605                         }
4606                     }
4607                     _peekMovieFragmentIdx[trackID]++;
4608 
4609                 }
4610             }
4611         }
4612         return ret;
4613     }
4614     else
4615     {
4616         return -1;
4617     }
4618 }
4619 
4620 
getSampleCountInTrack(uint32 id)4621 uint32 Mpeg4File::getSampleCountInTrack(uint32 id)
4622 {
4623     uint32 nTotalSamples = 0;
4624     if (_pmovieAtom != NULL)
4625     {
4626         nTotalSamples = (_pmovieAtom->getSampleCountInTrack(id));
4627         if (!_isMovieFragmentsPresent)
4628             return nTotalSamples;
4629 
4630         if (_parsing_mode == 0)
4631         {
4632             if (_pMovieFragmentAtomVec->size() > 0)
4633             {
4634                 for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
4635                 {
4636                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
4637                     if (pMovieFragmentAtom != NULL)
4638                     {
4639                         nTotalSamples += pMovieFragmentAtom->getTotalSampleInTraf(id);
4640                     }
4641                 }
4642                 return nTotalSamples;
4643             }
4644         }
4645         return nTotalSamples;
4646     }
4647     return 0;
4648 }
4649 
4650 
IsTFRAPresentForTrack(uint32 TrackId,bool oVideoAudioTextTrack)4651 bool Mpeg4File::IsTFRAPresentForTrack(uint32 TrackId, bool oVideoAudioTextTrack)
4652 {
4653     if (_pMovieFragmentRandomAccessAtomVec != NULL)
4654     {
4655         for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
4656         {
4657 
4658             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
4659             return pMovieFragmentRandomAccessAtom->IsTFRAPresentForTrack(TrackId, oVideoAudioTextTrack);
4660         }
4661     }
4662     return false;
4663 }
4664 
4665 
4666 /*
4667 This function has been modified to check the entry count in TFRA for all tracks are equal.
4668 The code change is under macro DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT
4669 */
IsTFRAPresentForAllTrack(uint32 numTracks,uint32 * trackList)4670 bool Mpeg4File::IsTFRAPresentForAllTrack(uint32 numTracks, uint32 *trackList)
4671 {
4672 
4673 #if (DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT)
4674     bool oVideoAudioTextTrack  = false;
4675 // This flag will be true for Video in AVT,VT & AV and for Audio in AT.
4676 // Based on this flag IsTFRAPresentForTrack() functions behaviour is changing
4677 // We are comparing the entry count for all the tracks to entry count of V in case of Vonly,AVT,VT & AV clips
4678 // and in case of Aonly & AT clips, entry count for all the tracks is compared with entry count of audio. For Tonly
4679 // clips, entry count for text track is compared with its own entry count.
4680 
4681     // Support for clips having Video track.
4682     for (int32 i = 0; i < numTracks; i++)
4683     {
4684         uint32 trackID = trackList[i];
4685         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
4686         {
4687             oVideoAudioTextTrack  = true;
4688             if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
4689             {
4690                 return false;
4691             }
4692             break;
4693         }
4694     }
4695     // Support for clips having Audio track and no Video track.
4696     if (!oVideoAudioTextTrack)
4697     {
4698         for (int32 i = 0; i < numTracks; i++)
4699         {
4700             uint32 trackID = trackList[i];
4701             if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
4702             {
4703                 oVideoAudioTextTrack = true;
4704                 if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
4705                 {
4706                     return false;
4707                 }
4708                 break;
4709             }
4710         }
4711     }
4712     // Support for clips having only Text track.
4713     if (!oVideoAudioTextTrack && numTracks == 1)
4714     {
4715         for (uint32 i = 0; i < numTracks; i++)
4716         {
4717             uint32 trackID = trackList[i];
4718             if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT)
4719             {
4720                 oVideoAudioTextTrack = true;
4721                 if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
4722                 {
4723                     return false;
4724                 }
4725                 break;
4726             }
4727         }
4728     }
4729 #endif // DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT
4730     for (uint32 idx = 0; idx < numTracks; idx++)
4731     {
4732         uint32 trackID = trackList[idx];
4733         // second argument is false always
4734         if (IsTFRAPresentForTrack(trackID, false) == false)
4735         {
4736             return false;
4737         }
4738     }
4739     return true;
4740 }
4741 
resetPlayback()4742 void Mpeg4File::resetPlayback()
4743 {
4744     if (_pmovieAtom == NULL)
4745         return;
4746 
4747     _pmovieAtom->resetPlayback();
4748 
4749     if (_isMovieFragmentsPresent)
4750     {
4751         if (_pMovieFragmentAtomVec != NULL)
4752         {
4753             int numTracks = _pmovieAtom->getNumTracks();
4754             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
4755             if (!trackList)
4756                 return;       // malloc failed
4757 
4758             _pmovieAtom->getTrackWholeIDList(trackList);
4759             for (int i = 0; i < numTracks; i++)
4760             {
4761                 uint32 trackID = trackList[i];
4762                 _peekMovieFragmentIdx[trackID] = 0;
4763                 _movieFragmentIdx[trackID] = 0;
4764                 _movieFragmentSeqIdx[trackID] = 1;
4765                 _peekMovieFragmentSeqIdx[trackID] = 1;
4766             }
4767             oscl_free(trackList);
4768             for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
4769             {
4770                 MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
4771                 if (pMovieFragmentAtom != NULL)
4772                     pMovieFragmentAtom->resetPlayback();
4773 
4774             }
4775         }
4776     }
4777 }
4778 
repositionFromMoof(uint32 time,uint32 trackID)4779 uint32 Mpeg4File::repositionFromMoof(uint32 time, uint32 trackID)
4780 {
4781     uint32 modifiedTimeStamp = time;
4782     uint32 convertedTS = 0;
4783     uint32 trackDuration = Oscl_Int64_Utils::get_uint64_lower32(getTrackMediaDurationForMovie(trackID));//getMovieDuration() - getMovieFragmentDuration();
4784 
4785     MediaClockConverter mcc1(1000);
4786     mcc1.update_clock(modifiedTimeStamp);
4787     convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
4788 
4789     if (_isMovieFragmentsPresent)
4790     {
4791         if (IsTFRAPresentForTrack(trackID, false) == false)
4792         {
4793             return 0;
4794         }
4795         if (modifiedTimeStamp >= trackDuration)
4796         {
4797             return 1; //repos in moof
4798         }
4799     }
4800     return 0; //repos in moov
4801 }
4802 
CancelNotificationSync()4803 MP4_ERROR_CODE Mpeg4File::CancelNotificationSync()
4804 {
4805     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::CancelNotificationSync"));
4806 
4807     bool retVal = _commonFilePtr->_pvfile.CancelNotificationSync();
4808 
4809     if (retVal)
4810     {
4811         return EVERYTHING_FINE;
4812     }
4813     else
4814     {
4815         return DEFAULT_ERROR;
4816     }
4817 }
4818 
CreateDataStreamSessionForExternalDownload(OSCL_wString & aFilename,PVMFCPMPluginAccessInterfaceFactory * aCPMAccessFactory,OsclFileHandle * aHandle,Oscl_FileServer * aFileServSession)4819 bool Mpeg4File::CreateDataStreamSessionForExternalDownload(OSCL_wString& aFilename,
4820         PVMFCPMPluginAccessInterfaceFactory* aCPMAccessFactory,
4821         OsclFileHandle* aHandle,
4822         Oscl_FileServer* aFileServSession)
4823 {
4824     OsclAny*ptr = oscl_malloc(sizeof(MP4_FF_FILE));
4825     if (ptr == NULL)
4826     {
4827         _success = false;
4828         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
4829         return false;
4830     }
4831     _commonFilePtr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE());
4832 
4833     if (_commonFilePtr != NULL)
4834     {
4835         _commonFilePtr->_fileServSession = aFileServSession;
4836         _commonFilePtr->_pvfile.SetCPM(aCPMAccessFactory);
4837         _commonFilePtr->_pvfile.SetFileHandle(aHandle);
4838 
4839         if (AtomUtils::OpenMP4File(aFilename,
4840                                    Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
4841                                    _commonFilePtr) != 0)
4842         {
4843             return false;
4844         }
4845 
4846         uint32 fileSize;
4847         AtomUtils::getCurrentFileSize(_commonFilePtr, fileSize);
4848         _commonFilePtr->_fileSize = (int32)fileSize;
4849     }
4850     return true;
4851 }
4852 
DestroyDataStreamForExternalDownload()4853 void Mpeg4File::DestroyDataStreamForExternalDownload()
4854 {
4855     if (_commonFilePtr != NULL)
4856     {
4857         if (_commonFilePtr->IsOpen())
4858         {
4859             AtomUtils::CloseMP4File(_commonFilePtr);
4860         }
4861         oscl_free(_commonFilePtr);
4862         _commonFilePtr = NULL;
4863     }
4864 }
4865 
4866 //Below APIs are used to supress Warning
ReserveMemoryForLangCodeVector(Oscl_Vector<uint16,OsclMemAllocator> & iLangCode,int32 capacity,int32 & leavecode)4867 void Mpeg4File::ReserveMemoryForLangCodeVector(Oscl_Vector<uint16, OsclMemAllocator> &iLangCode, int32 capacity, int32 &leavecode)
4868 {
4869     leavecode = 0;
4870     OSCL_TRY(leavecode, iLangCode.reserve(capacity));
4871 
4872 }
4873 
ReserveMemoryForValuesVector(Oscl_Vector<OSCL_wHeapString<OsclMemAllocator>,OsclMemAllocator> & iValues,int32 capacity,int32 & leavecode)4874 void Mpeg4File::ReserveMemoryForValuesVector(Oscl_Vector<OSCL_wHeapString<OsclMemAllocator>, OsclMemAllocator> &iValues, int32 capacity, int32 &leavecode)
4875 {
4876     leavecode = 0;
4877     OSCL_TRY(leavecode, iValues.reserve(capacity));
4878 
4879 }
4880 
4881 
4882