• 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 /*                            MPEG-4 IMpeg4File Class                            */
21 /*     -------------------------------------------------------------------       */
22 /*********************************************************************************/
23 /*
24     The IMpeg4File Class is INTERFACE that exsposes only those necessary
25     methods of the underlying Mpeg4File class.
26 */
27 
28 #define IMPLEMENT_IMpeg4File_H__
29 
30 #define GENERIC_ATOM_SIZE 8
31 
32 #ifndef OSCL_FILE_IO_H_INCLUDED
33 #include "oscl_file_io.h"
34 #endif
35 
36 #include "atom.h"
37 #include "atomutils.h"
38 #include "atomdefs.h"
39 
40 #include "pvuserdataatom.h"
41 #include "oscl_utf8conv.h"
42 #include "isucceedfail.h"
43 
44 #include "impeg4file.h"
45 #include "mpeg4file.h"
46 
47 #include "oscl_string.h"
48 
49 
50 // Use default DLL entry point for Symbian
51 #include "oscl_dll.h"
OSCL_DLL_ENTRY_POINT_DEFAULT()52 OSCL_DLL_ENTRY_POINT_DEFAULT()
53 
54 
55 /* ======================================================================== */
56 OSCL_EXPORT_REF  IMpeg4File *IMpeg4File::readMP4File(OSCL_wString& aFilename,
57         PVMFCPMPluginAccessInterfaceFactory* aCPMAccessFactory,
58         OsclFileHandle* aHandle,
59         uint32 aParsingMode,
60         Oscl_FileServer* aFileServSession)
61 {
62     //optimized mode is not supported if multiple file ptrs are not allowed
63     if (aParsingMode == 1)
64     {
65 #ifndef OPEN_FILE_ONCE_PER_TRACK
66         aParsingMode = 0;
67 #endif
68     }
69 
70     MP4_FF_FILE fileStruct;
71     MP4_FF_FILE *fp = &fileStruct;
72 
73     fp->_fileServSession = aFileServSession;
74     fp->_pvfile.SetCPM(aCPMAccessFactory);
75     fp->_pvfile.SetFileHandle(aHandle);
76 
77     if (AtomUtils::OpenMP4File(aFilename,
78                                Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
79                                fp) != 0)
80     {
81         return NULL;
82     }
83 
84     uint32 fileSize;
85     AtomUtils::getCurrentFileSize(fp, fileSize);
86     fp->_fileSize = (int32)fileSize;
87 
88     Mpeg4File *mp4 = NULL;
89     PV_MP4_FF_NEW(fp->auditCB, Mpeg4File, (fp, aFilename, aParsingMode), mp4);
90 
91 #ifdef OPEN_FILE_ONCE_PER_TRACK
92     if (mp4 != NULL)
93     {
94         if (!mp4->IsMovieFragmentsPresent())
95         {
96             if (fp->IsOpen())
97                 AtomUtils::CloseMP4File(fp);
98         }
99     }
100 #endif
101 
102     return mp4;
103 }
104 
105 //IsXXXable *******************************************
106 /*
107 oMoovBeforeMdat: as input,
108                 1: IsMobileMP4 check
109                 2: IsPseudoStreamable() check
110                 3: IsPlayable() check
111                  as output,
112                  1: moov atom is in front of the mdat atom
113                  0: there is mdat atom in front of moov atom
114 
115 metaDataSize   : as input. It is the available data size
116                  as output. It is the offset of the file where the full "moov" atom is available.
117 */
118 
119 OSCL_EXPORT_REF
120 int32
IsXXXable(OSCL_wString & filename,int32 & metaDataSize,int32 & oMoovBeforeMdat,uint32 * pMajorBrand,uint32 * pCompatibleBrands,Oscl_FileServer * fileServSession)121 IMpeg4File::IsXXXable(OSCL_wString& filename,
122                       int32 &metaDataSize,
123                       int32  &oMoovBeforeMdat,
124                       uint32 *pMajorBrand,
125                       uint32 *pCompatibleBrands,
126                       Oscl_FileServer* fileServSession)
127 {
128     const int ISMOBILEMP4 = 1, ISPSEUDOSTREMABLE = 2, ISPLAYABLE = 3;
129 
130     if (metaDataSize <= DEFAULT_ATOM_SIZE)
131         return READ_FAILED;
132 
133     if ((oMoovBeforeMdat < ISMOBILEMP4) || (oMoovBeforeMdat > ISPLAYABLE))
134         return DEFAULT_ERROR;
135 
136     int32 checkType = oMoovBeforeMdat;
137     int32 fileSize = metaDataSize;
138 
139     MP4_FF_FILE fileStruct;
140     MP4_FF_FILE *fp = &fileStruct;
141 
142     fp->_fileServSession = fileServSession;
143 
144     if (AtomUtils::OpenMP4File(filename,
145                                Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
146                                fp) != 0)
147     {
148         return (FILE_OPEN_FAILED);
149     }
150 
151     fp->_fileSize = fileSize;
152 
153     int32   mp4ErrorCode = DEFAULT_ERROR;
154 
155     uint32 atomType = UNKNOWN_ATOM;
156     uint32 atomSize = 0;
157 
158     AtomUtils::getNextAtomType(fp, atomSize, atomType);
159 
160     if (atomType == FILE_TYPE_ATOM)
161     {
162         //"ftyp"
163         if (fileSize < (int32)atomSize)
164         {
165             AtomUtils::CloseMP4File(fp);
166             return READ_FAILED;
167         }
168         FileTypeAtom *_pFileTypeAtom = NULL;
169         PV_MP4_FF_NEW(fp->auditCB, FileTypeAtom, (fp, atomSize, atomType), _pFileTypeAtom);
170 
171         if (!_pFileTypeAtom->MP4Success())
172         {
173             PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
174             AtomUtils::CloseMP4File(fp);
175             return READ_FILE_TYPE_ATOM_FAILED;
176         }
177         //get file type
178         {
179             *pMajorBrand = ENoFileType;
180 
181             uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
182 
183             //conversion
184             if (majorBrand == MOBILE_MP4)   *pMajorBrand = EMMP4;
185             else if (majorBrand == BRAND_3GPP4) *pMajorBrand = E3GP4;
186             else if (majorBrand == BRAND_3GPP5) *pMajorBrand = E3GP5;
187             else if (majorBrand == BRAND_ISOM)  *pMajorBrand = EISOM;
188             else if (majorBrand == BRAND_MP41)  *pMajorBrand = EMP41;
189             else if (majorBrand == BRAND_MP42)  *pMajorBrand = EMP42;
190             else if (majorBrand == WMF_BRAND)   *pMajorBrand = EWMF;
191             // else .. set to ENoFileType above
192 
193             Oscl_Vector<uint32, OsclMemAllocator> *compatibleBrandArray =
194                 _pFileTypeAtom->getCompatibleBrand();
195 
196             *pCompatibleBrands = ENoFileType;
197 
198             if (compatibleBrandArray != NULL)
199             {
200                 for (uint32 i = 0; i < compatibleBrandArray->size(); i++)
201                 {
202                     uint32 compatibleBrand = (*compatibleBrandArray)[i];
203 
204                     if (compatibleBrand == MOBILE_MP4)          *pCompatibleBrands |= EMMP4;
205                     else if (compatibleBrand == BRAND_3GPP4)    *pCompatibleBrands |= E3GP4;
206                     else if (compatibleBrand == BRAND_3GPP5)    *pCompatibleBrands |= E3GP5;
207                     else if (compatibleBrand == BRAND_ISOM)     *pCompatibleBrands |= EISOM;
208                     else if (compatibleBrand == BRAND_MP41)     *pCompatibleBrands |= EMP41;
209                     else if (compatibleBrand == BRAND_MP42)     *pCompatibleBrands |= EMP42;
210                     else if (compatibleBrand == WMF_BRAND)      *pCompatibleBrands |= EWMF;
211                 }
212             }
213         }//end of get file type
214 
215         int32 fpos = _pFileTypeAtom->getSize();
216         PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
217 
218         if (checkType == ISMOBILEMP4)
219         {
220             AtomUtils::CloseMP4File(fp);
221             return EVERYTHING_FINE;
222         }
223 
224         oMoovBeforeMdat = true;
225         metaDataSize = 0;
226 
227         if ((fpos + DEFAULT_ATOM_SIZE) > fileSize)
228         {
229             AtomUtils::CloseMP4File(fp);
230             return READ_FAILED;
231         }
232 
233         while (fpos < fileSize)
234         {
235             uint32 atomType = UNKNOWN_ATOM;
236             uint32 atomSize = 0;
237 
238             AtomUtils::getNextAtomType(fp, atomSize, atomType);
239 
240             fpos += DEFAULT_ATOM_SIZE;
241 
242             if ((atomType == FREE_SPACE_ATOM)
243                     || (atomType == SKIP_ATOM)
244                     || (atomType == USER_DATA_ATOM)
245                     || (atomType == UUID_ATOM)
246                     || (atomType == MOVIE_ATOM)
247                     || (atomType == MEDIA_DATA_ATOM)
248                     || (atomType == UNKNOWN_ATOM))
249             {
250                 if (atomSize < DEFAULT_ATOM_SIZE)
251                 {
252                     mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
253                     break;
254                 }
255                 atomSize -= DEFAULT_ATOM_SIZE;
256                 if (atomType == MOVIE_ATOM)
257                 {
258                     //this is an exit
259                     //no check of the "size" validity
260                     metaDataSize = fpos + atomSize;
261                     mp4ErrorCode = EVERYTHING_FINE;
262                     break;
263                 }
264                 else if (atomType == MEDIA_DATA_ATOM)
265                 {
266                     oMoovBeforeMdat = false;
267                     if (checkType == ISPSEUDOSTREMABLE)
268                     {
269                         mp4ErrorCode = EVERYTHING_FINE;
270                         break;
271                     }
272                 }
273 
274                 if ((int32)(fpos + atomSize) > fileSize)
275                 {
276                     mp4ErrorCode = READ_FAILED;
277                     break;
278                 }
279                 AtomUtils::seekFromCurrPos(fp, atomSize);
280                 fpos += atomSize;
281 
282             }
283             else if (atomType == 0)
284             {
285                 //return READ_FAILED;
286                 //since extra check is put above, it should NEVER fall in this bracket
287                 mp4ErrorCode = READ_FAILED;
288                 break;
289             }
290             else
291             {   //error: other atoms should not be in file level
292                 mp4ErrorCode = DEFAULT_ERROR;
293                 break;
294             }
295         }
296     }
297     AtomUtils::CloseMP4File(fp);
298     return (mp4ErrorCode);
299 }
300 
301 OSCL_EXPORT_REF
302 int32
IsXXXable(MP4_FF_FILE_REFERENCE fileRef,int32 & metaDataSize,int32 & oMoovBeforeMdat,uint32 * pMajorBrand,uint32 * pCompatibleBrands)303 IMpeg4File::IsXXXable(MP4_FF_FILE_REFERENCE fileRef,
304                       int32 &metaDataSize,
305                       int32  &oMoovBeforeMdat,
306                       uint32 *pMajorBrand,
307                       uint32 *pCompatibleBrands)
308 {
309     const int ISMOBILEMP4 = 1, ISPSEUDOSTREMABLE = 2, ISPLAYABLE = 3;
310 
311     if (metaDataSize <= DEFAULT_ATOM_SIZE)
312         return READ_FAILED;
313 
314     if ((oMoovBeforeMdat < ISMOBILEMP4) || (oMoovBeforeMdat > ISPLAYABLE))
315         return DEFAULT_ERROR;
316 
317     int32 checkType = oMoovBeforeMdat;
318     int32 fileSize = metaDataSize;
319 
320     MP4_FF_FILE fileStruct;
321     MP4_FF_FILE *fp = &fileStruct;
322 
323     fp->_pvfile.SetFilePtr(fileRef);
324 
325     AtomUtils::seekFromStart(fp, 0);
326     fp->_fileSize = fileSize;
327 
328     int32   mp4ErrorCode = DEFAULT_ERROR;
329 
330     uint32 atomType = UNKNOWN_ATOM;
331     uint32 atomSize = 0;
332 
333     AtomUtils::getNextAtomType(fp, atomSize, atomType);
334 
335     if (atomType == FILE_TYPE_ATOM)
336     {
337         //"ftyp"
338         if (fileSize < (int32)atomSize)
339         {
340             AtomUtils::CloseMP4File(fp);
341             return READ_FAILED;
342         }
343         FileTypeAtom *_pFileTypeAtom = NULL;
344         PV_MP4_FF_NEW(fp->auditCB, FileTypeAtom, (fp, atomSize, atomType), _pFileTypeAtom);
345 
346         if (!_pFileTypeAtom->MP4Success())
347         {
348             PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
349             AtomUtils::CloseMP4File(fp);
350             return READ_FILE_TYPE_ATOM_FAILED;
351         }
352         //get file type
353         {
354             *pMajorBrand = ENoFileType;
355 
356             uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
357 
358             //conversion
359             if (majorBrand == MOBILE_MP4)   *pMajorBrand = EMMP4;
360             else if (majorBrand == BRAND_3GPP4) *pMajorBrand = E3GP4;
361             else if (majorBrand == BRAND_3GPP5) *pMajorBrand = E3GP5;
362             else if (majorBrand == BRAND_ISOM)  *pMajorBrand = EISOM;
363             else if (majorBrand == BRAND_MP41)  *pMajorBrand = EMP41;
364             else if (majorBrand == BRAND_MP42)  *pMajorBrand = EMP42;
365             else if (majorBrand == WMF_BRAND)   *pMajorBrand = EWMF;
366 
367 
368             Oscl_Vector<uint32, OsclMemAllocator> *compatibleBrandArray =
369                 _pFileTypeAtom->getCompatibleBrand();
370 
371 
372             *pCompatibleBrands = ENoFileType;
373 
374             if (compatibleBrandArray != NULL)
375             {
376                 for (uint32 i = 0; i < compatibleBrandArray->size(); i++)
377                 {
378                     uint32 compatibleBrand = (*compatibleBrandArray)[i];
379 
380                     if (compatibleBrand == MOBILE_MP4)          *pCompatibleBrands |= EMMP4;
381                     else if (compatibleBrand == BRAND_3GPP4)    *pCompatibleBrands |= E3GP4;
382                     else if (compatibleBrand == BRAND_3GPP5)    *pCompatibleBrands |= E3GP5;
383                     else if (compatibleBrand == BRAND_ISOM)     *pCompatibleBrands |= EISOM;
384                     else if (compatibleBrand == BRAND_MP41)     *pCompatibleBrands |= EMP41;
385                     else if (compatibleBrand == BRAND_MP42)     *pCompatibleBrands |= EMP42;
386                     else if (compatibleBrand == WMF_BRAND)      *pCompatibleBrands |= EWMF;
387                 }
388             }
389         }//end of get file type
390 
391         int32 fpos = _pFileTypeAtom->getSize();
392         PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
393 
394         if (checkType == ISMOBILEMP4)
395         {
396             AtomUtils::CloseMP4File(fp);
397             return EVERYTHING_FINE;
398         }
399 
400         oMoovBeforeMdat = true;
401         metaDataSize = 0;
402 
403         if ((fpos + DEFAULT_ATOM_SIZE) > fileSize)
404         {
405             AtomUtils::CloseMP4File(fp);
406             return READ_FAILED;
407         }
408 
409         while (fpos < fileSize)
410         {
411             uint32 atomType = UNKNOWN_ATOM;
412             uint32 atomSize = 0;
413 
414             AtomUtils::getNextAtomType(fp, atomSize, atomType);
415 
416             fpos += DEFAULT_ATOM_SIZE;
417 
418             if ((atomType == FREE_SPACE_ATOM)
419                     || (atomType == SKIP_ATOM)
420                     || (atomType == USER_DATA_ATOM)
421                     || (atomType == UUID_ATOM)
422                     || (atomType == MOVIE_ATOM)
423                     || (atomType == MEDIA_DATA_ATOM)
424                     || (atomType == UNKNOWN_ATOM))
425             {
426                 if (atomSize < DEFAULT_ATOM_SIZE)
427                 {
428                     mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
429                     break;
430                 }
431                 atomSize -= DEFAULT_ATOM_SIZE;
432                 if (atomType == MOVIE_ATOM)
433                 {
434                     //this is an exit
435                     //no check of the "size" validity
436                     metaDataSize = fpos + atomSize;
437                     mp4ErrorCode = EVERYTHING_FINE;
438                     break;
439                 }
440                 else if (atomType == MEDIA_DATA_ATOM)
441                 {
442                     oMoovBeforeMdat = false;
443                     if (checkType == ISPSEUDOSTREMABLE)
444                     {
445                         mp4ErrorCode = EVERYTHING_FINE;
446                         break;
447                     }
448                 }
449 
450                 if ((int32)(fpos + atomSize) > fileSize)
451                 {
452                     mp4ErrorCode = READ_FAILED;
453                     break;
454                 }
455                 AtomUtils::seekFromCurrPos(fp, atomSize);
456                 fpos += atomSize;
457 
458             }
459             else if (atomType == 0)
460             {
461                 //return READ_FAILED;
462                 //since extra check is put above, it should NEVER fall in this bracket
463                 mp4ErrorCode = READ_FAILED;
464                 break;
465             }
466             else
467             {   //error: other atoms should not be in file level
468                 mp4ErrorCode = DEFAULT_ERROR;
469                 break;
470             }
471         }
472     }
473     AtomUtils::CloseMP4File(fp);
474     return (mp4ErrorCode);
475 }
476 
477 
478 OSCL_EXPORT_REF MP4_ERROR_CODE
IsProgressiveDownloadable(MP4_FF_FILE_REFERENCE filePtr,uint32 fileSize,bool & oIsProgressiveDownloadable,uint32 & metaDataSize)479 IMpeg4File::IsProgressiveDownloadable(MP4_FF_FILE_REFERENCE filePtr,
480                                       uint32 fileSize,
481                                       bool& oIsProgressiveDownloadable,
482                                       uint32& metaDataSize)
483 {
484     oIsProgressiveDownloadable = false;
485     metaDataSize  = 0;
486 
487     MP4_FF_FILE fileStruct;
488     MP4_FF_FILE *fp = &fileStruct;
489 
490     fp->_pvfile.SetFilePtr(filePtr);
491 
492     if (fileSize <= DEFAULT_ATOM_SIZE)
493     {
494         return INSUFFICIENT_DATA;
495     }
496 
497     int32 filePointer = AtomUtils::getCurrentFilePosition(fp);
498     AtomUtils::seekFromStart(fp, 0);
499 
500     fp->_fileSize = fileSize;
501 
502     uint32 atomType          = UNKNOWN_ATOM;
503     uint32 atomSize          = 0;
504     bool oMovieAtomFound     = false;
505     bool oMediaDataAtomFound = false;
506 
507     int32 fpos = 0;
508 
509     MP4_ERROR_CODE mp4ErrorCode = INSUFFICIENT_DATA;
510 
511     while ((uint32)(fpos + DEFAULT_ATOM_SIZE) < fileSize)
512     {
513         AtomUtils::getNextAtomType(fp, atomSize, atomType);
514         if (atomSize < DEFAULT_ATOM_SIZE)
515         {
516             mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
517             break;
518         }
519 
520         if ((atomType == FILE_TYPE_ATOM) ||
521                 (atomType == FREE_SPACE_ATOM) ||
522                 (atomType == SKIP_ATOM) ||
523                 (atomType == USER_DATA_ATOM) ||
524                 (atomType == UUID_ATOM) ||
525                 (atomType == UNKNOWN_ATOM))
526         {
527             fpos += atomSize;
528             if ((uint32)fpos > fileSize)
529             {
530                 break;
531             }
532             AtomUtils::seekFromStart(fp, fpos);
533             continue;
534         }
535         else if (atomType == MOVIE_ATOM)
536         {
537             fpos += atomSize;
538             oMovieAtomFound = true;
539             metaDataSize = fpos;
540         }
541         else if (atomType == MEDIA_DATA_ATOM)
542         {
543             fpos += atomSize;
544             oMediaDataAtomFound  = true;
545         }
546         else
547         {
548             //error: should never get here
549             mp4ErrorCode = DEFAULT_ERROR;
550         }
551         break;
552     }
553 
554     if (oMovieAtomFound || oMediaDataAtomFound)
555     {
556         //at most one of two can be true
557         oIsProgressiveDownloadable = oMovieAtomFound;
558         mp4ErrorCode = EVERYTHING_FINE;
559     }
560 
561     AtomUtils::seekFromStart(fp, filePointer);
562 
563     return (mp4ErrorCode);
564 }
565 
566 OSCL_EXPORT_REF MP4_ERROR_CODE
GetMetaDataSize(PVMFCPMPluginAccessInterfaceFactory * aCPMAccessFactory,bool & oIsProgressiveDownloadable,uint32 & metaDataSize)567 IMpeg4File::GetMetaDataSize(PVMFCPMPluginAccessInterfaceFactory* aCPMAccessFactory,
568                             bool& oIsProgressiveDownloadable,
569                             uint32& metaDataSize)
570 {
571     oIsProgressiveDownloadable = false;
572     metaDataSize  = 0;
573 
574     /* use a dummy string for file name */
575     OSCL_wHeapString<OsclMemAllocator> filename;
576 
577     MP4_FF_FILE fileStruct;
578     MP4_FF_FILE *fp = &fileStruct;
579     fp->_pvfile.SetCPM(aCPMAccessFactory);
580 
581     if (AtomUtils::OpenMP4File(filename,
582                                Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
583                                fp) != 0)
584     {
585         return FILE_OPEN_FAILED;
586     }
587 
588     uint32 fileSize;
589     AtomUtils::getCurrentFileSize(fp, fileSize);
590     fp->_fileSize = (int32)fileSize;
591 
592     AtomUtils::seekFromStart(fp, 0);
593 
594     if (fileSize <= DEFAULT_ATOM_SIZE)
595     {
596         return INSUFFICIENT_DATA;
597     }
598 
599     uint32 atomType          = UNKNOWN_ATOM;
600     uint32 atomSize          = 0;
601     bool oMovieAtomFound     = false;
602     bool oMediaDataAtomFound = false;
603 
604     int32 fpos = 0;
605 
606     MP4_ERROR_CODE mp4ErrorCode = INSUFFICIENT_DATA;
607 
608     while ((uint32)(fpos + DEFAULT_ATOM_SIZE) < fileSize)
609     {
610         AtomUtils::getNextAtomType(fp, atomSize, atomType);
611         if (atomSize < DEFAULT_ATOM_SIZE)
612         {
613             mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
614             break;
615         }
616 
617         if ((atomType == FILE_TYPE_ATOM) ||
618                 (atomType == FREE_SPACE_ATOM) ||
619                 (atomType == SKIP_ATOM) ||
620                 (atomType == USER_DATA_ATOM) ||
621                 (atomType == UUID_ATOM) ||
622                 (atomType == UNKNOWN_ATOM))
623         {
624             fpos += atomSize;
625             metaDataSize = fpos;
626             if ((uint32)fpos > fileSize)
627             {
628                 break;
629             }
630             AtomUtils::seekFromStart(fp, fpos);
631             continue;
632         }
633         else if (atomType == MOVIE_ATOM)
634         {
635             fpos += atomSize;
636             oMovieAtomFound = true;
637             metaDataSize = fpos;
638         }
639         else if (atomType == MEDIA_DATA_ATOM)
640         {
641             fpos += atomSize;
642             oMediaDataAtomFound  = true;
643             metaDataSize = fpos;
644         }
645         else
646         {
647             //error: should never get here
648             mp4ErrorCode = DEFAULT_ERROR;
649         }
650         break;
651     }
652 
653     if (oMovieAtomFound || oMediaDataAtomFound)
654     {
655         //at most one of two can be true
656         oIsProgressiveDownloadable = oMovieAtomFound;
657         mp4ErrorCode = EVERYTHING_FINE;
658     }
659 
660     if (!oMovieAtomFound && (0 != AtomUtils::getFileBufferingCapacity(fp)))
661     {
662         // can't support progressive playback if no movie atom found
663         mp4ErrorCode = NOT_PROGRESSIVE_STREAMABLE;
664     }
665 
666     AtomUtils::CloseMP4File(fp);
667 
668     return (mp4ErrorCode);
669 }
670 
DestroyMP4FileObject(IMpeg4File * aMP4FileObject)671 OSCL_EXPORT_REF void IMpeg4File::DestroyMP4FileObject(IMpeg4File* aMP4FileObject)
672 {
673     Mpeg4File* ptr = OSCL_STATIC_CAST(Mpeg4File*, aMP4FileObject);
674     PV_MP4_FF_DELETE(NULL, Mpeg4File, ptr);
675 }
676