• 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 MovieAtom Class                             */
21 /*     -------------------------------------------------------------------       */
22 /*********************************************************************************/
23 /*
24     This MovieAtom Class is the main atom class in the MPEG-4 File that stores
25     all the meta data about the MPEG-4 presentation.
26 */
27 
28 
29 #define IMPLEMENT_MovieAtom
30 
31 #include "movieatom.h"
32 #include "atomutils.h"
33 #include "atomdefs.h"
34 #include "amrdecoderspecificinfo.h"
35 
36 //HEADER FILES REQD FOR MULTIPLE SAMPLE RETRIEVAL API
37 #include "oscl_media_data.h"
38 #include "pv_gau.h"
39 #include "media_clock_converter.h"
40 
41 typedef Oscl_Vector<TrackAtom*, OsclMemAllocator> trackAtomVecType;
42 
43 // Stream-in ctor
MovieAtom(MP4_FF_FILE * fp,OSCL_wString & filename,uint32 size,uint32 type,bool oPVContent,bool oPVContentDownloadable,uint32 parsingMode)44 OSCL_EXPORT_REF MovieAtom::MovieAtom(MP4_FF_FILE *fp,
45                                      OSCL_wString& filename,
46                                      uint32 size,
47                                      uint32 type,
48                                      bool oPVContent,
49                                      bool oPVContentDownloadable,
50                                      uint32 parsingMode)
51         : Atom(fp, size, type)
52 {
53     PV_MP4_FF_NEW(fp->auditCB, trackAtomVecType, (), _ptrackArray);
54     _pmovieHeaderAtom = NULL;
55     _pobjectDescriptorAtom = NULL;
56     _pUserDataAtom = NULL;
57     _pMovieExtendsAtom = NULL;
58     _isMovieFragmentPresent = false;
59     _oVideoTrackPresent = false;
60 
61 
62 
63     if (_success)
64     {
65         _scalability = -1;
66         _fileType = 0;
67 
68         // initialization
69         _pparent = NULL;
70 
71         // Generalized so can read in in ANY ORDER!!!
72         int32 count = _size - DEFAULT_ATOM_SIZE;
73 
74         uint32 atomType = UNKNOWN_ATOM;
75         uint32 atomSize = 0;
76 
77         //top level below the "moov" => mvhd trak iods udta
78         while (((atomType == MOVIE_HEADER_ATOM) ||
79                 (atomType == OBJECT_DESCRIPTOR_ATOM) ||
80                 (atomType == TRACK_ATOM) ||
81                 (atomType == USER_DATA_ATOM) ||
82                 (atomType == FREE_SPACE_ATOM) ||
83                 (atomType == UUID_ATOM) ||
84                 (atomType == OMADRM_KMS_BOX) ||
85                 (atomType == MOVIE_EXTENDS_ATOM) ||
86                 (atomType == UNKNOWN_ATOM)) &&
87                 (count > 0))
88         {
89             uint32 currPtr = AtomUtils::getCurrentFilePosition(fp);
90             AtomUtils::getNextAtomType(fp, atomSize, atomType);
91 
92             if (atomType == USER_DATA_ATOM)
93             {
94                 if (_pUserDataAtom == NULL)
95                 {
96                     PV_MP4_FF_NEW(fp->auditCB, UserDataAtom, (fp, atomSize, atomType), _pUserDataAtom);
97 
98                     if (!_pUserDataAtom->MP4Success())
99                     {
100                         AtomUtils::seekFromStart(fp, currPtr);
101                         AtomUtils::seekFromCurrPos(fp, atomSize);
102                         PV_MP4_FF_DELETE(NULL, UserDataAtom, _pUserDataAtom);
103                         _pUserDataAtom = NULL;
104                         count -= atomSize;
105                     }
106                     else
107                     {
108                         _pUserDataAtom->setParent(this);
109                         count -= _pUserDataAtom->getSize();
110                     }
111                 }
112                 else
113                 {
114                     //at most one udat atom allowed
115                     if (atomSize < DEFAULT_ATOM_SIZE)
116                     {
117                         _success = false;
118                         _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
119                         break;
120                     }
121                     if (count < (int32)atomSize)
122                     {
123                         _success = false;
124                         _mp4ErrorCode = READ_FAILED;
125                         break;
126                     }
127                     count -= atomSize;
128                     atomSize -= DEFAULT_ATOM_SIZE;
129                     AtomUtils::seekFromCurrPos(fp, atomSize);
130                 }
131             }
132             else if ((atomType == FREE_SPACE_ATOM) ||
133                      (atomType == UUID_ATOM) ||
134                      (atomType == UNKNOWN_ATOM))
135             {
136                 if (atomSize < DEFAULT_ATOM_SIZE)
137                 {
138                     _success = false;
139                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
140                     break;
141                 }
142                 if (count < (int32)atomSize)
143                 {
144                     _success = false;
145                     _mp4ErrorCode = READ_FAILED;
146                     break;
147                 }
148                 count -= atomSize;
149                 atomSize -= DEFAULT_ATOM_SIZE;
150                 AtomUtils::seekFromCurrPos(fp, atomSize);
151             }
152             else if (atomType == MOVIE_HEADER_ATOM)
153             {
154                 // mvhd
155                 if (_pmovieHeaderAtom == NULL)
156                 {
157                     PV_MP4_FF_NEW(fp->auditCB, MovieHeaderAtom, (fp, atomSize, atomType), _pmovieHeaderAtom);
158 
159                     if (!_pmovieHeaderAtom->MP4Success())
160                     {
161                         _success = false;
162                         _mp4ErrorCode = _pmovieHeaderAtom->GetMP4Error();
163                         break;
164                     }
165                     _pmovieHeaderAtom->setParent(this);
166                     count -= _pmovieHeaderAtom->getSize();
167                 }
168                 else
169                 {
170                     _success = false;
171                     _mp4ErrorCode = DUPLICATE_MOVIE_HEADERS;
172                     break;
173                 }
174             }
175             else if (atomType == MOVIE_EXTENDS_ATOM)
176             {
177                 if (_pMovieExtendsAtom == NULL)
178                 {
179                     PV_MP4_FF_NEW(fp->auditCB, MovieExtendsAtom, (fp, atomSize, atomType), _pMovieExtendsAtom);
180 
181                     if (!_pMovieExtendsAtom->MP4Success())
182                     {
183                         _success = false;
184                         _mp4ErrorCode = _pMovieExtendsAtom->GetMP4Error();
185                         break;
186                     }
187                     _pMovieExtendsAtom->setParent(this);
188                     count -= _pMovieExtendsAtom->getSize();
189                     _isMovieFragmentPresent = true;
190                 }
191                 else
192                 {
193                     //duplicate atom
194                     count -= atomSize;
195                     atomSize -= DEFAULT_ATOM_SIZE;
196                     AtomUtils::seekFromCurrPos(fp, atomSize);
197                 }
198             }
199             else if (atomType == OBJECT_DESCRIPTOR_ATOM)
200             {
201                 // iods
202                 if (_pobjectDescriptorAtom == NULL)
203                 {
204                     PV_MP4_FF_NEW(fp->auditCB, ObjectDescriptorAtom,
205                                   (fp, atomSize, atomType), _pobjectDescriptorAtom);
206 
207                     if (!_pobjectDescriptorAtom->MP4Success())
208                     {
209                         _success = false;
210                         _mp4ErrorCode = _pobjectDescriptorAtom->GetMP4Error();
211                         break;
212                     }
213                     _pobjectDescriptorAtom->setParent(this);
214                     count -= _pobjectDescriptorAtom->getSize();
215                 }
216                 else
217                 {
218                     _success = false;
219                     _mp4ErrorCode = DUPLICATE_OBJECT_DESCRIPTORS;
220                     break;
221                 }
222             }
223             else if (atomType == TRACK_ATOM)
224             {
225                 TrackAtom *track = NULL;
226                 // trak
227                 if (oPVContent)
228                 {
229                     // Read in and add all the track atoms
230                     PV_MP4_FF_NEW(fp->auditCB,
231                                   TrackAtom,
232                                   (fp, filename, atomSize,
233                                    atomType, oPVContent,
234                                    oPVContentDownloadable,
235                                    parsingMode),
236                                   track);
237 
238 
239                     if (track->MP4Success())
240                     {
241                         count -= track->getSize();
242                         addTrackAtom(track);
243                     }
244                     else
245                     {
246                         _success = false;
247                         _mp4ErrorCode = track->GetMP4Error();
248                         if (track != NULL)
249                         {
250                             PV_MP4_FF_DELETE(NULL, TrackAtom, track);
251                             track = NULL;
252                         }
253                         break;
254                     }
255                 }
256                 else
257                 {
258                     // Read in and add all the track atoms
259                     uint32 currPos = AtomUtils::getCurrentFilePosition(fp);
260                     PV_MP4_FF_NEW(fp->auditCB,
261                                   TrackAtom,
262                                   (fp, filename, atomSize,
263                                    atomType, false,
264                                    false,
265                                    parsingMode),
266                                   track);
267 
268                     if (track->MP4Success())
269                     {
270                         count -= track->getSize();
271                         addTrackAtom(track);
272                     }
273                     else
274                     {
275                         count -= atomSize;
276                         atomSize -= DEFAULT_ATOM_SIZE;
277                         currPos += atomSize;
278                         AtomUtils::seekFromStart(fp, currPos);
279 
280                         if (track != NULL)
281                         {
282                             PV_MP4_FF_DELETE(NULL, TrackAtom, track);
283                             track = NULL;
284                         }
285                     }
286                 }
287 
288                 /* max limit- 1024 tracks*/
289                 if ((_ptrackArray->size()) > MAX_LIMIT_FOR_NUMBER_OF_TRACKS)
290                 {
291                     _success = false;
292                     _mp4ErrorCode = EXCEED_MAX_LIMIT_SUPPORTED_FOR_TOTAL_TRACKS;
293                     return ;
294                 }
295             }
296         }
297 
298         // IF SUCCESS IS FALSE, RETURN RIGHT AWAY
299         if (_success)
300         {
301             if (NULL == _pmovieHeaderAtom)
302             {
303                 _success = false;
304                 _mp4ErrorCode = NO_MOVIE_HEADER_ATOM_PRESENT;
305                 return;
306             }
307             else
308             {
309                 uint32 ts = _pmovieHeaderAtom->getTimeScale();
310                 if (NULL != _ptrackArray)
311                 {
312                     for (uint i = 0; i < _ptrackArray->size(); i++)
313                     {
314                         TrackAtom *trackAtom = (*_ptrackArray)[i];
315                         trackAtom->NEWsetTrackTSOffset(ts);
316                     }
317                 }
318             }
319         }
320     }
321     else
322     {
323         _mp4ErrorCode = READ_MOVIE_ATOM_FAILED;
324     }
325 }
326 
327 
328 // Destructor - delete the vector(s) of TrackAtoms from the heap
~MovieAtom()329 OSCL_EXPORT_REF MovieAtom::~MovieAtom()
330 {
331     uint32 i;
332 
333     if (_pmovieHeaderAtom != NULL)
334         PV_MP4_FF_DELETE(NULL, MovieHeaderAtom, _pmovieHeaderAtom);
335 
336     if (_pobjectDescriptorAtom != NULL)
337         PV_MP4_FF_DELETE(NULL, ObjectDescriptorAtom, _pobjectDescriptorAtom);
338 
339     if (_pUserDataAtom != NULL)
340         PV_MP4_FF_DELETE(NULL, UserDataAtom, _pUserDataAtom);
341 
342     // Delete audio tracks
343     for (i = 0; i < _ptrackArray->size(); i++)
344     {
345         PV_MP4_FF_DELETE(NULL, TrackAtom, (*_ptrackArray)[i]);
346     }
347     PV_MP4_FF_TEMPLATED_DELETE(NULL, trackAtomVecType, Oscl_Vector, _ptrackArray);
348     if (_pMovieExtendsAtom != NULL)
349     {
350         PV_MP4_FF_DELETE(NULL, MovieExtendsAtom , _pMovieExtendsAtom);
351     }
352 }
353 
getTimestampForCurrentSample(uint32 id)354 uint32 MovieAtom::getTimestampForCurrentSample(uint32 id)
355 {
356     TrackAtom *track = getTrackForID(id);
357 
358     if (track != NULL)
359     {
360         return track->getTimestampForCurrentSample();
361     }
362     else
363     {
364         return 0;
365     }
366 }
367 
getOffsetByTime(uint32 id,uint32 ts,int32 * sampleFileOffset)368 int32 MovieAtom::getOffsetByTime(uint32 id, uint32 ts, int32* sampleFileOffset)
369 {
370     TrackAtom *track = getTrackForID(id);
371     if (track == NULL)
372     {
373         return DEFAULT_ERROR;
374     }
375     return track->getOffsetByTime(ts, sampleFileOffset);
376 }
377 
getMediaSample(uint32 id,uint32 sampleNumber,uint8 * buf,int32 & size,uint32 & index,uint32 & SampleOffset)378 int32 MovieAtom::getMediaSample(uint32 id, uint32 sampleNumber, uint8 *buf, int32 &size, uint32 &index, uint32 &SampleOffset)
379 {
380     int32 nReturn = 0;
381 
382     TrackAtom *track = getTrackForID(id);
383     if (track == NULL)
384     {
385         return READ_TRACK_ATOM_FAILED;
386     }
387     nReturn =  track->getMediaSample(sampleNumber, buf, size, index, SampleOffset);
388     return (nReturn);
389 }
390 
getKeyMediaSampleNumAt(uint32 aTrackId,uint32 aKeySampleNum,GAU * pgau)391 MP4_ERROR_CODE MovieAtom::getKeyMediaSampleNumAt(uint32 aTrackId,
392         uint32 aKeySampleNum,
393         GAU    *pgau)
394 {
395     MP4_ERROR_CODE nReturn = READ_FAILED;
396 
397     TrackAtom *track = getTrackForID(aTrackId);
398     if (track == NULL)
399     {
400         return nReturn;
401     }
402     nReturn =  track->getKeyMediaSampleNumAt(aKeySampleNum, pgau);
403     return (nReturn);
404 }
405 
getPrevKeyMediaSample(uint32 inputtimestamp,uint32 & aKeySampleNum,uint32 id,uint32 * n,GAU * pgau)406 int32 MovieAtom::getPrevKeyMediaSample(uint32 inputtimestamp,
407                                        uint32 &aKeySampleNum,
408                                        uint32 id,
409                                        uint32 *n,
410                                        GAU    *pgau)
411 {
412     int32 nReturn = 0;
413 
414     TrackAtom *track = getTrackForID(id);
415 
416     if (track == NULL)
417     {
418         return READ_TRACK_ATOM_FAILED;
419     }
420     nReturn =  track->getPrevKeyMediaSample(inputtimestamp, aKeySampleNum, n, pgau);
421     return (nReturn);
422 }
423 
getNextKeyMediaSample(uint32 inputtimestamp,uint32 & aKeySampleNum,uint32 id,uint32 * n,GAU * pgau)424 int32 MovieAtom::getNextKeyMediaSample(uint32 inputtimestamp,
425                                        uint32 &aKeySampleNum,
426                                        uint32 id,
427                                        uint32 *n,
428                                        GAU    *pgau)
429 {
430     int32 nReturn = 0;
431 
432     TrackAtom *track = getTrackForID(id);
433 
434     if (track == NULL)
435     {
436         return READ_TRACK_ATOM_FAILED;
437     }
438     nReturn =  track->getNextKeyMediaSample(inputtimestamp, aKeySampleNum, n, pgau);
439     return (nReturn);
440 }
441 
getNextMediaSample(uint32 id,uint8 * buf,uint32 & size,uint32 & index,uint32 & SampleOffset)442 int32 MovieAtom::getNextMediaSample(uint32 id, uint8 *buf, uint32 &size, uint32 &index, uint32 &SampleOffset)
443 {
444     int32 nReturn = 0;
445 
446     TrackAtom *track = getTrackForID(id);
447     if (track == NULL)
448     {
449         return READ_TRACK_ATOM_FAILED;
450     }
451 
452     int32 buf_size =  size;
453     nReturn =  track->getNextMediaSample(buf, buf_size, index, SampleOffset);
454     size = buf_size;
455     return (nReturn);
456 }
457 
458 int32
getNextBundledAccessUnits(uint32 id,uint32 * n,GAU * pgau)459 MovieAtom::getNextBundledAccessUnits(uint32 id,
460                                      uint32 *n,
461                                      GAU    *pgau)
462 {
463     int32 nReturn = -1;
464 
465     TrackAtom *track = getTrackForID(id);
466 
467     if (track != NULL)
468     {
469         nReturn =  track->getNextBundledAccessUnits(n, pgau);
470     }
471 
472     return (nReturn);
473 }
474 
475 int32
peekNextBundledAccessUnits(uint32 id,uint32 * n,MediaMetaInfo * mInfo)476 MovieAtom::peekNextBundledAccessUnits(uint32 id,
477                                       uint32 *n,
478                                       MediaMetaInfo *mInfo)
479 {
480     int32 nReturn = -1;
481 
482     TrackAtom *track = getTrackForID(id);
483 
484     if (track != NULL)
485     {
486         nReturn = track->peekNextBundledAccessUnits(n, mInfo);
487     }
488 
489     return (nReturn);
490 }
491 
492 
getTrackDuration(uint32 id)493 uint64 MovieAtom::getTrackDuration(uint32 id)
494 {
495     TrackAtom *trackAtom = getTrackforID(id);
496 
497     if (trackAtom != NULL)
498     {
499         return trackAtom->getTrackDuration();
500     }
501     else
502     {
503         return 0;
504     }
505 }
506 
507 // From TrackReference
trackDependsOn(uint32 id)508 int32 MovieAtom::trackDependsOn(uint32 id)
509 {
510     TrackAtom *trackAtom = getTrackforID(id);
511 
512     if (trackAtom != NULL)
513     {
514         return trackAtom->dependsOn();
515     }
516     else
517     {
518         return 0;
519     }
520 
521 }
522 
getMovieFragmentDuration()523 OSCL_EXPORT_REF uint64 MovieAtom::getMovieFragmentDuration()
524 {
525     if (_pMovieExtendsAtom != NULL)
526     {
527         return _pMovieExtendsAtom->getFragmentDuration();
528     }
529     else
530         return 0;
531 }
532 
getTrackMediaDuration(uint32 id)533 uint64 MovieAtom::getTrackMediaDuration(uint32 id)
534 {
535     TrackAtom *trackAtom = getTrackforID(id);
536 
537     if (trackAtom != NULL)
538     {
539         return trackAtom->getMediaDuration();
540     }
541     else
542     {
543         return 0;
544     }
545 }
546 
getTrackMediaTimescale(uint32 id)547 int32 MovieAtom::getTrackMediaTimescale(uint32 id)
548 {
549     TrackAtom *trackAtom = getTrackforID(id);
550 
551     if (trackAtom != NULL)
552     {
553         return trackAtom->getMediaTimescale();
554     }
555     else
556     {
557         //RETURN SOME UNDEFINED VALUE
558         return (0xFFFFFFFF);
559     }
560 }
561 
562 // From Handler
getTrackStreamType(uint32 id)563 int32  MovieAtom::getTrackStreamType(uint32 id)
564 {
565     TrackAtom *trackAtom = getTrackforID(id);
566 
567     if (trackAtom != NULL)
568     {
569         return trackAtom->getTrackStreamType();
570     }
571     else
572     {
573         //RETURN SOME UNDEFINED VALUE
574         return (0xFFFFFFFF);
575     }
576 }
577 
578 // From SampleDescription
getTrackNumSampleEntries(uint32 id)579 OSCL_EXPORT_REF int32 MovieAtom::getTrackNumSampleEntries(uint32 id)
580 {
581     TrackAtom *trackAtom = getTrackforID(id);
582 
583     if (trackAtom != NULL)
584     {
585         return trackAtom->getNumSampleEntries();
586     }
587     else
588     {
589         return 0;
590     }
591 }
592 
593 
594 // From DecoderConfigDescriptor
getTrackDecoderSpecificInfo(uint32 id)595 DecoderSpecificInfo *MovieAtom::getTrackDecoderSpecificInfo(uint32 id)
596 {
597     TrackAtom *trackAtom = getTrackforID(id);
598 
599     if (trackAtom != NULL)
600     {
601         return trackAtom->getDecoderSpecificInfo();
602     }
603     else
604     {
605         return NULL;
606     }
607 }
608 
609 // From DecoderConfigDescriptor
610 DecoderSpecificInfo *
getTrackDecoderSpecificInfoAtSDI(uint32 trackID,uint32 index)611 MovieAtom::getTrackDecoderSpecificInfoAtSDI(uint32 trackID, uint32 index)
612 {
613     TrackAtom *trackAtom = getTrackforID(trackID);
614 
615     if (trackAtom != NULL)
616     {
617         return trackAtom->getDecoderSpecificInfoForSDI(index);
618     }
619     else
620     {
621         return NULL;
622     }
623 }
624 
getTrackMIMEType(uint32 id,OSCL_String & aMimeType)625 void MovieAtom::getTrackMIMEType(uint32 id, OSCL_String& aMimeType)
626 {
627     TrackAtom *trackAtom = getTrackforID(id);
628 
629     if (trackAtom != NULL)
630     {
631         trackAtom->getMIMEType(aMimeType);
632     }
633 }
634 
635 
getTrackMaxBufferSizeDB(uint32 id)636 int32 MovieAtom::getTrackMaxBufferSizeDB(uint32 id)
637 {
638     TrackAtom *trackAtom = getTrackforID(id);
639 
640     if (trackAtom != NULL)
641     {
642         return trackAtom->getMaxBufferSizeDB();
643     }
644     else
645     {
646         return 0;
647     }
648 }
649 
getTrackHeight(uint32 id)650 OSCL_EXPORT_REF int32 MovieAtom::getTrackHeight(uint32 id)
651 {
652     TrackAtom *trackAtom = getTrackforID(id);
653 
654     if (trackAtom != NULL)
655     {
656 
657         return trackAtom->getHeight();
658     }
659     else
660     {
661         return 0;
662     }
663 }
664 
getTrackWidth(uint32 id)665 OSCL_EXPORT_REF int32 MovieAtom::getTrackWidth(uint32 id)
666 {
667     TrackAtom *trackAtom = getTrackforID(id);
668 
669     if (trackAtom != NULL)
670     {
671         return trackAtom->getWidth();
672     }
673     else
674     {
675         return 0;
676     }
677 }
678 
getTrackAverageBitrate(uint32 id)679 int32  MovieAtom::getTrackAverageBitrate(uint32 id)
680 {
681     TrackAtom *trackAtom = getTrackforID(id);
682 
683     if (trackAtom != NULL)
684     {
685         return trackAtom->getAverageBitrate();
686     }
687     else
688     {
689         return 0;
690     }
691 }
692 
693 
694 TrackAtom *
getTrackforID(uint32 id)695 MovieAtom::getTrackforID(uint32 id)
696 {
697     TrackAtom *trackAtom = NULL;
698     uint32 i = 0;
699 
700     while (i < _ptrackArray->size())
701     {
702         trackAtom = (*_ptrackArray)[i];
703         i++;
704         if (trackAtom != NULL)
705         {
706             if (trackAtom->getTrackID() == id)
707             {
708                 return trackAtom;
709             }
710         }
711     }
712 
713     return NULL;
714 }
715 
resetPlayback()716 void MovieAtom::resetPlayback()
717 {
718     uint32 i;
719     TrackAtom *trackAtom;
720     for (i = 0; i < _ptrackArray->size(); i++)
721     {
722         trackAtom = (*_ptrackArray)[i];
723 
724         if (trackAtom != NULL)
725         {
726             //only reset video and audio track
727             if ((trackAtom->getMediaType() == MEDIA_TYPE_VISUAL) ||
728                     (trackAtom->getMediaType() == MEDIA_TYPE_AUDIO)  ||
729                     (trackAtom->getMediaType() == MEDIA_TYPE_TEXT))
730             {
731                 trackAtom->resetPlayBack();
732             }
733         }
734     }
735 }
736 
resetTrackToEOT()737 void MovieAtom::resetTrackToEOT()
738 {
739     uint32 i;
740     TrackAtom *trackAtom;
741     for (i = 0; i < _ptrackArray->size(); i++)
742     {
743         trackAtom = (*_ptrackArray)[i];
744 
745         if (trackAtom != NULL)
746         {
747             //only reset video and audio track
748             if ((trackAtom->getMediaType() == MEDIA_TYPE_VISUAL) ||
749                     (trackAtom->getMediaType() == MEDIA_TYPE_AUDIO)  ||
750                     (trackAtom->getMediaType() == MEDIA_TYPE_TEXT))
751             {
752                 trackAtom->resetTrackToEOT();
753             }
754         }
755     }
756 }
757 
758 OSCL_EXPORT_REF TrackAtom *
getTrackForID(uint32 id)759 MovieAtom::getTrackForID(uint32 id)
760 {
761     int32 i, trackArrayLength;
762     uint32 trackID = 0;
763     TrackAtom *trackAtom = NULL;
764     trackArrayLength = _ptrackArray->size();
765 
766     for (i = 0; i < trackArrayLength; i++)
767     {
768         trackAtom = (TrackAtom*)(*_ptrackArray)[i];
769 
770         if (trackAtom != NULL)
771         {
772             trackID = trackAtom->getTrackID();
773             if (trackID == id)
774             {
775                 return trackAtom;
776             }
777         }
778     }
779     return NULL;
780 
781 }
782 
783 
784 // Add a new Track (audio/video) only to the trackArray
addTrackAtom(TrackAtom * a)785 void MovieAtom::addTrackAtom(TrackAtom *a)
786 {
787     switch (a->getMediaType())
788     {
789         case MEDIA_TYPE_AUDIO:
790             (*_ptrackArray).push_back(a);
791             a->setParent(this);
792             _fileType |= FILE_TYPE_AUDIO;
793             break;
794         case MEDIA_TYPE_VISUAL:
795         {
796             (*_ptrackArray).push_back(a);
797             a->setParent(this);
798             _fileType |= FILE_TYPE_VIDEO;
799             _scalability += 1; // increment scalability with each video track read in
800             // Preferred way would be to read in the VOL headers (DecoderSpecificInfo) and parse
801             // to see the scalability and layer tags within the headers
802             break;
803         }
804 
805         case MEDIA_TYPE_TEXT:
806         {
807             (*_ptrackArray).push_back(a);
808             a->setParent(this);
809             _fileType |= FILE_TYPE_TEXT;
810             break;
811         }
812 
813         default:
814 
815             PV_MP4_FF_DELETE(NULL, TrackAtom, a);
816             break;
817     }
818 
819 }
820 
821 // Get timescale from movieheader atom for ENTIRE presentation
822 uint32
getTimeScale() const823 MovieAtom::getTimeScale() const
824 {
825     if (_pmovieHeaderAtom != NULL)
826     {
827         return _pmovieHeaderAtom->getTimeScale();
828     }
829     else
830     {
831         //RETURN SOME UNDEFINED VALUE
832         return 0xFFFFFFFF;
833     }
834 }
835 
836 
resetPlayback(uint32 time,uint16 numTracks,uint32 * trackList,bool bResetToIFrame)837 uint32 MovieAtom::resetPlayback(uint32 time, uint16 numTracks, uint32 *trackList, bool bResetToIFrame)
838 {
839     // Find base layer video track
840     // Reset time on it, get ts
841     // reset audio to that ts
842     // reset enhance layer to ts
843     //
844     uint32 i, modifiedTimeStamp;
845     uint32 timestamp, returnedTS;
846     uint32 convertedTS = 0;
847     TrackAtom *trackAtom;
848     TrackAtom *IndependentTrackAtom;
849 
850     modifiedTimeStamp = time;
851 
852     if (!bResetToIFrame)
853     {//if reset to I frame is not enforced, the FF will just move to rp time no matter
854         //it is I or P frame.
855         for (i = 0; i < numTracks; i++)
856         {
857             trackAtom = getTrackForID(*(trackList + i));
858 
859             if (trackAtom != NULL)
860             {
861                 MediaClockConverter mcc1(1000);
862                 mcc1.update_clock(modifiedTimeStamp);
863                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(*(trackList + i)));
864 
865                 returnedTS = trackAtom->resetPlayBack(convertedTS, true);
866                 // convert returnedTS (which is in media time scale) to the ms
867                 MediaClockConverter mcc(getTrackMediaTimescale(*(trackList + i)));
868                 mcc.update_clock(returnedTS);
869                 timestamp = mcc.get_converted_ts(1000);
870 
871                 if (timestamp <= modifiedTimeStamp)
872                 {
873                     modifiedTimeStamp = timestamp;
874                 }
875 
876             }
877         }
878         //this return value is meanlingless
879         return modifiedTimeStamp;
880     }
881 
882     for (i = 0; i < numTracks; i++)
883     {
884         trackAtom = getTrackForID(*(trackList + i));
885 
886         if (trackAtom != NULL)
887         {
888 
889             //only reset video and audio track
890             if (trackAtom->getMediaType() == MEDIA_TYPE_VISUAL)
891             {
892                 _oVideoTrackPresent = true;
893 
894                 if (trackAtom->dependsOn() != 0)
895                 {
896                     IndependentTrackAtom = getTrackForID(trackAtom->dependsOn());
897 
898                     if (IndependentTrackAtom != NULL)
899                     {
900                         // convert modifiedTimeStamp (which is in ms) to the appropriate
901                         // media time scale
902                         MediaClockConverter mcc1(1000);
903                         mcc1.update_clock(modifiedTimeStamp);
904                         convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(*(trackList + i)));
905 
906                         returnedTS = IndependentTrackAtom->resetPlayBack(convertedTS);
907 
908                         // convert returnedTS (which is in media time scale) to the ms
909                         MediaClockConverter mcc(getTrackMediaTimescale(*(trackList + i)));
910                         mcc.update_clock(returnedTS);
911                         timestamp = mcc.get_converted_ts(1000);
912 
913                         if (timestamp <= modifiedTimeStamp)
914                         {
915                             modifiedTimeStamp = timestamp;
916                         }
917 
918                     }
919 
920                     bool oDependsOn = true;
921 
922                     trackAtom->resetPlayBack(convertedTS, oDependsOn);
923                 }
924                 else
925                 {
926                     modifiedTimeStamp = time;
927 
928                     // convert modifiedTimeStamp (which is in ms) to the appropriate
929                     // media time scale
930                     MediaClockConverter mcc1(1000);
931                     mcc1.update_clock(modifiedTimeStamp);
932                     convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(*(trackList + i)));
933 
934                     returnedTS = trackAtom->resetPlayBack(convertedTS);
935 
936                     // convert returnedTS (which is in media time scale) to the ms
937                     MediaClockConverter mcc(getTrackMediaTimescale(*(trackList + i)));
938                     mcc.update_clock(returnedTS);
939                     timestamp = mcc.get_converted_ts(1000);
940 
941                     if (timestamp <= modifiedTimeStamp)
942                     {
943                         modifiedTimeStamp = timestamp;
944                     }
945 
946                 }
947             }
948         }
949         else
950         {
951             modifiedTimeStamp = 0;
952         }
953     }
954 
955     for (i = 0; i < numTracks; i++)
956     {
957         trackAtom = getTrackForID(*(trackList + i));
958 
959         if (trackAtom != NULL)
960         {
961 
962             //only reset video and audio track
963             if ((trackAtom ->getMediaType() == MEDIA_TYPE_AUDIO) ||
964                     (trackAtom ->getMediaType() == MEDIA_TYPE_TEXT))
965             {
966                 // convert modifiedTimeStamp (which is in ms) to the appropriate
967                 // media time scale
968                 MediaClockConverter mcc1(1000);
969                 mcc1.update_clock(modifiedTimeStamp);
970                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(*(trackList + i)));
971 
972                 if (_oVideoTrackPresent)
973                 {
974                     returnedTS = trackAtom->resetPlayBack(convertedTS, true);
975                 }
976                 else
977                 {
978                     returnedTS = trackAtom->resetPlayBack(convertedTS);
979                 }
980 
981                 // convert returnedTS (which is in media time scale) to the ms
982                 MediaClockConverter mcc(getTrackMediaTimescale(*(trackList + i)));
983                 mcc.update_clock(returnedTS);
984                 timestamp = mcc.get_converted_ts(1000);
985 
986                 if (timestamp <= modifiedTimeStamp)
987                 {
988                     modifiedTimeStamp = timestamp;
989                 }
990             }
991         }
992         else
993         {
994             modifiedTimeStamp = 0;
995         }
996     }
997 
998 
999     return modifiedTimeStamp;
1000 
1001 }
1002 
queryRepositionTime(uint32 time,uint16 numTracks,uint32 * trackList,bool bResetToIFrame,bool bBeforeRequestedTime)1003 int32 MovieAtom::queryRepositionTime(uint32 time,
1004                                      uint16 numTracks,
1005                                      uint32 *trackList,
1006                                      bool bResetToIFrame,
1007                                      bool bBeforeRequestedTime)
1008 {
1009     // Find base layer video track
1010     // Reset time on it, get ts
1011     // reset audio to that ts
1012     // reset enhance layer to ts
1013     //
1014     uint32 i, modifiedTimeStamp;
1015     uint32 timestamp, returnedTS;
1016     uint32 convertedTS = 0, minTS = 0;
1017     TrackAtom *trackAtom;
1018     TrackAtom *IndependentTrackAtom;
1019 
1020     bool  oVideoTrackPresent = false;
1021     modifiedTimeStamp = time;
1022     minTS = 0x7FFFFFFF;
1023 
1024     if (!bResetToIFrame)
1025     {//if reset to I frame is not enforced, the FF will just move to rp time no matter
1026         //it is I or P frame.
1027         for (i = 0; i < numTracks; i++)
1028         {
1029             trackAtom = getTrackForID(*(trackList + i));
1030 
1031             if (trackAtom != NULL)
1032             {
1033                 // convert modifiedTimeStamp (which is in ms) to the appropriate
1034                 // media time scale
1035                 MediaClockConverter mcc1(1000);
1036                 mcc1.update_clock(modifiedTimeStamp);
1037                 convertedTS = mcc1.get_converted_ts(trackAtom->getMediaTimescale());
1038 
1039                 returnedTS = trackAtom->queryRepositionTime(convertedTS, true, bBeforeRequestedTime);
1040 
1041                 // convert returnedTS (which is in media time scale) to the ms
1042                 MediaClockConverter mcc(trackAtom->getMediaTimescale());
1043                 mcc.update_clock(returnedTS);
1044                 timestamp = mcc.get_converted_ts(1000);
1045                 if (timestamp < minTS)
1046                     minTS = timestamp;
1047             }
1048         }
1049         return minTS;
1050 
1051     }
1052     for (i = 0; i < numTracks; i++)
1053     {
1054         trackAtom = getTrackForID(*(trackList + i));
1055 
1056         if (trackAtom != NULL)
1057         {
1058             //only reset video and audio track
1059             if (trackAtom->getMediaType() == MEDIA_TYPE_VISUAL)
1060             {
1061                 oVideoTrackPresent = true;
1062 
1063                 if (trackAtom->dependsOn() != 0)
1064                 {
1065                     // convert modifiedTimeStamp (which is in ms) to the appropriate
1066                     // media time scale
1067                     MediaClockConverter mcc1(1000);
1068                     mcc1.update_clock(modifiedTimeStamp);
1069                     convertedTS = mcc1.get_converted_ts(trackAtom->getMediaTimescale());
1070 
1071                     IndependentTrackAtom = getTrackForID(trackAtom->dependsOn());
1072 
1073                     if (IndependentTrackAtom != NULL)
1074                     {
1075                         returnedTS =
1076                             IndependentTrackAtom->queryRepositionTime(convertedTS,
1077                                     false,
1078                                     bBeforeRequestedTime);
1079 
1080                         // convert returnedTS (which is in media time scale) to the ms
1081                         MediaClockConverter mcc(trackAtom->getMediaTimescale());
1082                         mcc.update_clock(returnedTS);
1083                         timestamp = mcc.get_converted_ts(1000);
1084 
1085                         if (timestamp <= modifiedTimeStamp)
1086                         {
1087                             modifiedTimeStamp = timestamp;
1088                         }
1089                     }
1090 
1091                     trackAtom->queryRepositionTime(convertedTS, false, bBeforeRequestedTime);
1092                 }
1093                 else
1094                 {
1095                     modifiedTimeStamp = time;
1096 
1097                     // convert modifiedTimeStamp (which is in ms) to the appropriate
1098                     // media time scale
1099                     MediaClockConverter mcc1(1000);
1100                     mcc1.update_clock(modifiedTimeStamp);
1101                     convertedTS = mcc1.get_converted_ts(trackAtom->getMediaTimescale());
1102 
1103                     returnedTS = trackAtom->queryRepositionTime(convertedTS, false, bBeforeRequestedTime);
1104 
1105                     // convert returnedTS (which is in media time scale) to the ms
1106                     MediaClockConverter mcc(trackAtom->getMediaTimescale());
1107                     mcc.update_clock(returnedTS);
1108                     timestamp = mcc.get_converted_ts(1000);
1109 
1110                     modifiedTimeStamp = timestamp;
1111                 }
1112             }
1113         }
1114         else
1115         {
1116             modifiedTimeStamp = 0;
1117         }
1118     }
1119 
1120     for (i = 0; i < numTracks; i++)
1121     {
1122         trackAtom = getTrackForID(*(trackList + i));
1123 
1124         if (trackAtom != NULL)
1125         {
1126             //only reset video and audio track
1127             if ((trackAtom ->getMediaType() == MEDIA_TYPE_AUDIO) ||
1128                     (trackAtom ->getMediaType() == MEDIA_TYPE_TEXT))
1129             {
1130                 // convert modifiedTimeStamp (which is in ms) to the appropriate
1131                 // media time scale
1132                 MediaClockConverter mcc1(1000);
1133                 mcc1.update_clock(modifiedTimeStamp);
1134                 convertedTS = mcc1.get_converted_ts(trackAtom->getMediaTimescale());
1135 
1136                 returnedTS = trackAtom->queryRepositionTime(convertedTS, false, bBeforeRequestedTime);
1137 
1138                 // convert returnedTS (which is in media time scale) to the ms
1139                 MediaClockConverter mcc(trackAtom->getMediaTimescale());
1140                 mcc.update_clock(returnedTS);
1141                 timestamp = mcc.get_converted_ts(1000);
1142 
1143                 if (!oVideoTrackPresent)
1144                 {
1145                     if (trackAtom ->getMediaType() == MEDIA_TYPE_AUDIO)
1146                     {
1147                         if (timestamp <= modifiedTimeStamp)
1148                         {
1149                             modifiedTimeStamp = timestamp;
1150                         }
1151                     }
1152                 }
1153             }
1154         }
1155         else
1156         {
1157             modifiedTimeStamp = 0;
1158         }
1159     }
1160     return modifiedTimeStamp;
1161 }
1162 
querySyncFrameBeforeTime(uint32 time,uint16 numTracks,uint32 * trackList)1163 int32   MovieAtom::querySyncFrameBeforeTime(uint32 time, uint16 numTracks, uint32 *trackList)
1164 {
1165     TrackAtom *trackAtom;
1166     for (uint16 i = 0; i < numTracks; i++)
1167     {
1168         trackAtom = getTrackForID(*(trackList + i));
1169         if (trackAtom != NULL)
1170         {
1171             if (trackAtom->getMediaType() == MEDIA_TYPE_VISUAL)
1172             {
1173                 if (!trackAtom->dependsOn())
1174                 {   //base layer
1175                     return trackAtom->IsResetNeeded(time);
1176                 }
1177             }
1178         }
1179     }
1180     return EVERYTHING_FINE; //resetplayback is needed
1181 }
1182 
getTrackWholeIDList(uint32 * ids)1183 uint32 MovieAtom::getTrackWholeIDList(uint32 *ids)
1184 {
1185     int32 i = 0, totalTrackNumber;
1186     TrackAtom *trackAtom;
1187     totalTrackNumber = getNumTracks();
1188 
1189     if (ids == NULL)
1190     {
1191         return 0;
1192     }
1193 
1194     for (i = 0; i < totalTrackNumber; i++)
1195     {
1196         trackAtom = (TrackAtom *)(*_ptrackArray)[i];
1197 
1198         if (trackAtom != NULL)
1199         {
1200             (*ids) = trackAtom->getTrackID();
1201             ids++;
1202         }
1203     }
1204     return i;
1205 }
1206 
1207 
updateFileSize(uint32 filesize)1208 int32 MovieAtom::updateFileSize(uint32  filesize)
1209 {
1210     if (NULL == _ptrackArray)
1211     {
1212         return DEFAULT_ERROR;
1213     }
1214     TrackAtom *trackAtom;
1215     int32   returnVal = EVERYTHING_FINE;//success
1216     for (uint32 i = 0; i < _ptrackArray->size(); i++)
1217     {
1218         trackAtom = (TrackAtom *)(*_ptrackArray)[i];
1219         if (trackAtom != NULL)
1220         {
1221             if (EVERYTHING_FINE != trackAtom->updateFileSize(filesize))
1222             {
1223                 returnVal = DEFAULT_ERROR;
1224             }
1225         }
1226 
1227     }
1228     return returnVal;   //success
1229 }
1230 
getTrackIDList(uint32 * ids,int size)1231 OSCL_EXPORT_REF uint32 MovieAtom::getTrackIDList(uint32 *ids, int size)
1232 {
1233     int32 i = 0, totalTrackNumber;
1234     TrackAtom *trackAtom;
1235     totalTrackNumber = getNumTracks();
1236 
1237     if (ids == NULL)
1238     {
1239         return 0;
1240     }
1241 
1242     while ((i < size) && (i < totalTrackNumber))
1243     {
1244         trackAtom = (TrackAtom *)(*_ptrackArray)[i];
1245         if (trackAtom != NULL)
1246         {
1247             (*ids) = trackAtom->getTrackID();
1248             ids++;
1249         }
1250         i++;
1251     }
1252     return i;
1253 }
1254 
getSampleCountInTrack(uint32 id)1255 OSCL_EXPORT_REF uint32 MovieAtom::getSampleCountInTrack(uint32 id)
1256 {
1257     TrackAtom *track = getTrackForID(id);
1258 
1259     if (track != NULL)
1260     {
1261         return track->getSampleCount();
1262     }
1263     else
1264     {
1265         // BY DEFAULT NO RANDOM ACCESS
1266         return 0;
1267     }
1268 }
1269 
checkMMP4()1270 bool MovieAtom::checkMMP4()
1271 {
1272     uint32 i;
1273     TrackAtom *trackAtom;
1274 
1275     int32 numAudioTracks = 0;
1276     int32 numVideoTracks = 0;
1277     int32 numTextTracks  = 0;
1278 
1279     for (i = 0; i < _ptrackArray->size(); i++)
1280     {
1281         trackAtom = (*_ptrackArray)[i];
1282 
1283         if (trackAtom != NULL)
1284         {
1285             //only reset video and audio track
1286             if (trackAtom->getMediaType() == MEDIA_TYPE_VISUAL)
1287             {
1288                 numVideoTracks += 1;
1289             }
1290 
1291             if (trackAtom->getMediaType() == MEDIA_TYPE_AUDIO)
1292             {
1293                 numAudioTracks += 1;
1294             }
1295 
1296             if (trackAtom->getMediaType() == MEDIA_TYPE_TEXT)
1297             {
1298                 numTextTracks += 1;
1299             }
1300         }
1301     }
1302 
1303     if ((numAudioTracks > 1) || (numVideoTracks > 1) || (numTextTracks > 1))
1304     {
1305         return false;
1306     }
1307     else
1308     {
1309         return true;
1310     }
1311 }
getAssetInfoTitleLangCode(int32 index)1312 uint16 MovieAtom::getAssetInfoTitleLangCode(int32 index)
1313 {
1314     AssetInfoTitleAtom *pAtom = NULL;
1315 
1316     if (_pUserDataAtom != NULL)
1317     {
1318         pAtom = _pUserDataAtom->getAssetInfoTitleAtomAt(index);
1319     }
1320     else
1321     {
1322         return (0xFFFF);
1323     }
1324 
1325     if (pAtom != NULL)
1326     {
1327         return pAtom->getTitleLangCode();
1328     }
1329     else
1330     {
1331         return (0xFFFF);
1332     }
1333 }
1334 
getAssetInfoTitleNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1335 OSCL_wString& MovieAtom::getAssetInfoTitleNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1336 {
1337     AssetInfoTitleAtom *pAtom = NULL;
1338     if (_pUserDataAtom != NULL)
1339     {
1340         pAtom = _pUserDataAtom->getAssetInfoTitleAtomAt(index);
1341     }
1342     else
1343     {
1344         return _emptyString;
1345     }
1346 
1347     if (pAtom != NULL)
1348     {
1349         return pAtom->getTitleNotice(charType);
1350     }
1351     else
1352     {
1353         return _emptyString;
1354     }
1355 }
getAssetInfoDescLangCode(int32 index)1356 uint16 MovieAtom::getAssetInfoDescLangCode(int32 index)
1357 {
1358     AssetInfoDescAtom *pAtom = NULL;
1359 
1360     if (_pUserDataAtom != NULL)
1361     {
1362         pAtom = _pUserDataAtom->getAssetInfoDescAtomAt(index);
1363     }
1364     else
1365     {
1366         return (0xFFFF);
1367     }
1368 
1369     if (pAtom != NULL)
1370     {
1371         return pAtom->getDescLangCode();
1372     }
1373     else
1374     {
1375         return (0xFFFF);
1376     }
1377 }
1378 
getAssetInfoDescNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1379 OSCL_wString& MovieAtom::getAssetInfoDescNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1380 {
1381     AssetInfoDescAtom *pAtom = NULL;
1382     if (_pUserDataAtom != NULL)
1383     {
1384         pAtom = _pUserDataAtom->getAssetInfoDescAtomAt(index);
1385     }
1386     else
1387     {
1388         return _emptyString;
1389     }
1390 
1391     if (pAtom != NULL)
1392     {
1393         return pAtom->getDescNotice(charType);
1394     }
1395     else
1396     {
1397         return _emptyString;
1398     }
1399 }
1400 
1401 
getCopyRightString(MP4FFParserOriginalCharEnc & charType,int32 index)1402 OSCL_wString& MovieAtom::getCopyRightString(MP4FFParserOriginalCharEnc &charType, int32 index)
1403 {
1404     charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
1405 
1406     CopyRightAtom *patom = NULL;
1407     if (_pUserDataAtom != NULL)
1408     {
1409         patom = _pUserDataAtom->getCopyRightAtomAt(index);
1410     }
1411     else
1412     {
1413         return _emptyString; // return empty string
1414     }
1415 
1416     if (patom != NULL)
1417     {
1418         return patom->getCopyRightString();
1419     }
1420     else
1421     {
1422         return _emptyString; // return empty string
1423     }
1424 }
1425 
getCopyRightLanguageCode(int32 index)1426 uint16 MovieAtom::getCopyRightLanguageCode(int32 index)
1427 {
1428     CopyRightAtom *patom = NULL;
1429 
1430     if (_pUserDataAtom != NULL)
1431     {
1432         patom = _pUserDataAtom->getCopyRightAtomAt(index);
1433     }
1434     else
1435     {
1436         return 0xFFFF;
1437     }
1438 
1439     if (patom != NULL)
1440     {
1441         return patom->getLanguageCode();
1442     }
1443     else
1444     {
1445         return 0xFFFF;
1446     }
1447 }
1448 
getAssetInfoPerformerLangCode(int32 index)1449 uint16 MovieAtom::getAssetInfoPerformerLangCode(int32 index)
1450 {
1451     AssetInfoPerformerAtom *pAtom = NULL;
1452 
1453     if (_pUserDataAtom != NULL)
1454     {
1455         pAtom = _pUserDataAtom->getAssetInfoPerformerAtomAt(index);
1456     }
1457     else
1458     {
1459         return (0xFFFF);
1460     }
1461 
1462     if (pAtom != NULL)
1463     {
1464         return pAtom->getPerfLangCode();
1465     }
1466     else
1467     {
1468         return (0xFFFF);
1469     }
1470 }
1471 
getAssetInfoPerformerNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1472 OSCL_wString& MovieAtom::getAssetInfoPerformerNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1473 {
1474     AssetInfoPerformerAtom *pAtom = NULL;
1475     if (_pUserDataAtom != NULL)
1476     {
1477         pAtom = _pUserDataAtom->getAssetInfoPerformerAtomAt(index);
1478     }
1479     else
1480     {
1481         return _emptyString;
1482     }
1483 
1484     if (pAtom != NULL)
1485     {
1486         return pAtom->getPerfNotice(charType);
1487     }
1488     else
1489     {
1490         return _emptyString;
1491     }
1492 }
1493 
getAssetInfoAuthorLangCode(int32 index)1494 uint16 MovieAtom::getAssetInfoAuthorLangCode(int32 index)
1495 {
1496     AssetInfoAuthorAtom *pAtom = NULL;
1497 
1498     if (_pUserDataAtom != NULL)
1499     {
1500         pAtom = _pUserDataAtom->getAssetInfoAuthorAtomAt(index);
1501     }
1502     else
1503     {
1504         return (0xFFFF);
1505     }
1506 
1507     if (pAtom != NULL)
1508     {
1509         return pAtom->getAuthorLangCode();
1510     }
1511     else
1512     {
1513         return (0xFFFF);
1514     }
1515 }
1516 
getAssetInfoAuthorNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1517 OSCL_wString& MovieAtom::getAssetInfoAuthorNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1518 {
1519     AssetInfoAuthorAtom *pAtom = NULL;
1520     if (_pUserDataAtom != NULL)
1521     {
1522         pAtom = _pUserDataAtom->getAssetInfoAuthorAtomAt(index);
1523     }
1524     else
1525     {
1526         return _emptyString;
1527     }
1528 
1529     if (pAtom != NULL)
1530     {
1531         return pAtom->getAuthorNotice(charType);
1532     }
1533     else
1534     {
1535         return _emptyString;
1536     }
1537 }
1538 
getAssetInfoGenreLangCode(int32 index)1539 uint16 MovieAtom::getAssetInfoGenreLangCode(int32 index)
1540 {
1541     AssetInfoGenreAtom *pAtom = NULL;
1542 
1543     if (_pUserDataAtom != NULL)
1544     {
1545         pAtom = _pUserDataAtom->getAssetInfoGenreAtomAt(index);
1546     }
1547     else
1548     {
1549         return (0xFFFF);
1550     }
1551 
1552     if (pAtom != NULL)
1553     {
1554         return pAtom->getGenreLangCode();
1555     }
1556     else
1557     {
1558         return (0xFFFF);
1559     }
1560 }
1561 
getAssetInfoGenreNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1562 OSCL_wString& MovieAtom::getAssetInfoGenreNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1563 {
1564     AssetInfoGenreAtom *pAtom = NULL;
1565     if (_pUserDataAtom != NULL)
1566     {
1567         pAtom = _pUserDataAtom->getAssetInfoGenreAtomAt(index);
1568     }
1569     else
1570     {
1571         return _emptyString;
1572     }
1573 
1574     if (pAtom != NULL)
1575     {
1576         return pAtom->getGenreNotice(charType);
1577     }
1578     else
1579     {
1580         return _emptyString;
1581     }
1582 }
1583 
getAssetInfoRatingCriteria(int32 index)1584 uint32 MovieAtom::getAssetInfoRatingCriteria(int32 index)
1585 {
1586     AssetInfoRatingAtom *pAtom = NULL;
1587 
1588     if (_pUserDataAtom != NULL)
1589     {
1590         pAtom = _pUserDataAtom->getAssetInfoRatingAtomAt(index);
1591     }
1592     else
1593     {
1594         return (0);
1595     }
1596 
1597     if (pAtom != NULL)
1598     {
1599         return pAtom->getRatingCriteria();
1600     }
1601     else
1602     {
1603         return 0;
1604     }
1605 }
1606 
getAssetInfoRatingEntity(int32 index)1607 uint32 MovieAtom::getAssetInfoRatingEntity(int32 index)
1608 {
1609     AssetInfoRatingAtom *pAtom = NULL;
1610 
1611     if (_pUserDataAtom != NULL)
1612     {
1613         pAtom = _pUserDataAtom->getAssetInfoRatingAtomAt(index);
1614     }
1615     else
1616     {
1617         return (0);
1618     }
1619 
1620     if (pAtom != NULL)
1621     {
1622         return pAtom->getRatingEntity();
1623     }
1624     else
1625     {
1626         return (0);
1627     }
1628 }
1629 
getAssetInfoRatingLangCode(int32 index)1630 uint16 MovieAtom::getAssetInfoRatingLangCode(int32 index)
1631 {
1632     AssetInfoRatingAtom *pAtom = NULL;
1633 
1634     if (_pUserDataAtom != NULL)
1635     {
1636         pAtom = _pUserDataAtom->getAssetInfoRatingAtomAt(index);
1637     }
1638     else
1639     {
1640         return (0xFFFF);
1641     }
1642 
1643     if (pAtom != NULL)
1644     {
1645         return pAtom->getRatingLangCode();
1646     }
1647     else
1648     {
1649         return (0xFFFF);
1650     }
1651 }
1652 
getAssetInfoRatingNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1653 OSCL_wString& MovieAtom::getAssetInfoRatingNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1654 {
1655     AssetInfoRatingAtom *pAtom = NULL;
1656     if (_pUserDataAtom != NULL)
1657     {
1658         pAtom = _pUserDataAtom->getAssetInfoRatingAtomAt(index);
1659     }
1660     else
1661     {
1662         return _emptyString;
1663     }
1664 
1665     if (pAtom != NULL)
1666     {
1667         return pAtom->getRatingNotice(charType);
1668     }
1669     else
1670     {
1671         return _emptyString;
1672     }
1673 }
1674 
getAssetInfoClassificationEntity(int32 index)1675 uint32 MovieAtom::getAssetInfoClassificationEntity(int32 index)
1676 {
1677     AssetInfoClassificationAtom *pAtom = NULL;
1678 
1679     if (_pUserDataAtom != NULL)
1680     {
1681         pAtom = _pUserDataAtom->getAssetInfoClassificationAtomAt(index);
1682     }
1683     else
1684     {
1685         return (0);
1686     }
1687 
1688     if (pAtom != NULL)
1689     {
1690         return pAtom->getClassificationEntity();
1691     }
1692     else
1693     {
1694         return 0;
1695     }
1696 }
1697 
getAssetInfoClassificationTable(int32 index)1698 uint16 MovieAtom::getAssetInfoClassificationTable(int32 index)
1699 {
1700     AssetInfoClassificationAtom *pAtom = NULL;
1701 
1702     if (_pUserDataAtom != NULL)
1703     {
1704         pAtom = _pUserDataAtom->getAssetInfoClassificationAtomAt(index);
1705     }
1706     else
1707     {
1708         return (0);
1709     }
1710 
1711     if (pAtom != NULL)
1712     {
1713         return pAtom->getClassificationTable();
1714     }
1715     else
1716     {
1717         return (0);
1718     }
1719 }
1720 
getAssetInfoClassificationLangCode(int32 index)1721 uint16 MovieAtom::getAssetInfoClassificationLangCode(int32 index)
1722 {
1723     AssetInfoClassificationAtom *pAtom = NULL;
1724 
1725     if (_pUserDataAtom != NULL)
1726     {
1727         pAtom = _pUserDataAtom->getAssetInfoClassificationAtomAt(index);
1728     }
1729     else
1730     {
1731         return (0xFFFF);
1732     }
1733 
1734     if (pAtom != NULL)
1735     {
1736         return pAtom->getClassificationLangCode();
1737     }
1738     else
1739     {
1740         return (0xFFFF);
1741     }
1742 }
1743 
getAssetInfoClassificationNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1744 OSCL_wString& MovieAtom::getAssetInfoClassificationNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1745 {
1746     AssetInfoClassificationAtom *pAtom = NULL;
1747     if (_pUserDataAtom != NULL)
1748     {
1749         pAtom = _pUserDataAtom->getAssetInfoClassificationAtomAt(index);
1750     }
1751     else
1752     {
1753         return _emptyString;
1754     }
1755 
1756     if (pAtom != NULL)
1757     {
1758         return pAtom->getClassificationNotice(charType);
1759     }
1760     else
1761     {
1762         return _emptyString;
1763     }
1764 }
1765 
getAssetInfoNumKeyWords(int32 index)1766 uint16 MovieAtom::getAssetInfoNumKeyWords(int32 index)
1767 {
1768     AssetInfoKeyWordAtom *pAtom = NULL;
1769 
1770     if (_pUserDataAtom != NULL)
1771     {
1772         pAtom = _pUserDataAtom->getAssetInfoKeyWordAtomAt(index);
1773     }
1774     else
1775     {
1776         return (0);
1777     }
1778 
1779     if (pAtom != NULL)
1780     {
1781         return (uint16)pAtom->getNumKeyWords();
1782     }
1783     else
1784     {
1785         return (0);
1786     }
1787 }
1788 
getAssetInfoKeyWordLangCode(int32 index)1789 uint16 MovieAtom::getAssetInfoKeyWordLangCode(int32 index)
1790 {
1791     AssetInfoKeyWordAtom *pAtom = NULL;
1792 
1793     if (_pUserDataAtom != NULL)
1794     {
1795         pAtom = _pUserDataAtom->getAssetInfoKeyWordAtomAt(index);
1796     }
1797     else
1798     {
1799         return (0xFFFF);
1800     }
1801 
1802     if (pAtom != NULL)
1803     {
1804         return pAtom->getKeyWordLangCode();
1805     }
1806     else
1807     {
1808         return (0xFFFF);
1809     }
1810 }
1811 
getAssetInfoKeyWord(int32 atomIndex,int32 keyWordIndex)1812 OSCL_wString& MovieAtom::getAssetInfoKeyWord(int32 atomIndex, int32 keyWordIndex)
1813 {
1814     AssetInfoKeyWordAtom *pAtom = NULL;
1815     if (_pUserDataAtom != NULL)
1816     {
1817         pAtom = _pUserDataAtom->getAssetInfoKeyWordAtomAt(atomIndex);
1818     }
1819     else
1820     {
1821         return _emptyString;
1822     }
1823 
1824     if (pAtom != NULL)
1825     {
1826         return pAtom->getKeyWordAt(keyWordIndex);
1827     }
1828     else
1829     {
1830         return _emptyString;
1831     }
1832 }
1833 
getAssetInfoLocationStruct(int32 index) const1834 PvmfAssetInfo3GPPLocationStruct* MovieAtom::getAssetInfoLocationStruct(int32 index) const
1835 {
1836     AssetInfoLocationAtom *pAtom = NULL;
1837 
1838     if (_pUserDataAtom != NULL)
1839     {
1840         pAtom = _pUserDataAtom->getAssetInfoLocationAtomAt(index);
1841     }
1842     else
1843     {
1844         return NULL;
1845     }
1846 
1847     if (pAtom != NULL)
1848     {
1849         return pAtom->getAssetInfoLocationStruct();
1850     }
1851     else
1852     {
1853         return NULL;
1854     }
1855 
1856 }
1857 
1858 
getAssetInfoAlbumLangCode(int32 index)1859 uint16 MovieAtom::getAssetInfoAlbumLangCode(int32 index)
1860 {
1861     AssetInfoAlbumAtom *pAtom = NULL;
1862 
1863     if (_pUserDataAtom != NULL)
1864     {
1865         pAtom = _pUserDataAtom->getAssetInfoAlbumAtomAt(index);
1866     }
1867     else
1868     {
1869         return (0xFFFF);
1870     }
1871 
1872     if (pAtom != NULL)
1873     {
1874         return pAtom->getAlbumLangCode();
1875     }
1876     else
1877     {
1878         return (0xFFFF);
1879     }
1880 }
1881 
getAssetInfoAlbumNotice(MP4FFParserOriginalCharEnc & charType,int32 index)1882 OSCL_wString& MovieAtom::getAssetInfoAlbumNotice(MP4FFParserOriginalCharEnc &charType, int32 index)
1883 {
1884     AssetInfoAlbumAtom *pAtom = NULL;
1885     if (_pUserDataAtom != NULL)
1886     {
1887         pAtom = _pUserDataAtom->getAssetInfoAlbumAtomAt(index);
1888     }
1889     else
1890     {
1891         return _emptyString;
1892     }
1893 
1894     if (pAtom != NULL)
1895     {
1896         return pAtom->getAlbumNotice(charType);
1897     }
1898     else
1899     {
1900         return _emptyString;
1901     }
1902 }
1903 
getAssetInfoAlbumTrackNumber(int32 index)1904 uint8 MovieAtom::getAssetInfoAlbumTrackNumber(int32 index)
1905 {
1906     AssetInfoAlbumAtom *pAtom = NULL;
1907     if (_pUserDataAtom != NULL)
1908     {
1909         pAtom = _pUserDataAtom->getAssetInfoAlbumAtomAt(index);
1910     }
1911     else
1912     {
1913         return 0;
1914     }
1915 
1916     if (pAtom != NULL)
1917     {
1918         return pAtom->getTrackNumber();
1919     }
1920     else
1921     {
1922         return 0;
1923     }
1924 }
1925 
getAssetInfoRecordingYear(int32 index)1926 uint16 MovieAtom::getAssetInfoRecordingYear(int32 index)
1927 {
1928     AssetInfoRecordingYearAtom *pAtom = NULL;
1929     if (_pUserDataAtom != NULL)
1930     {
1931         pAtom = _pUserDataAtom->getAssetInfoRecordingYearAtomAt(index);
1932     }
1933     else
1934     {
1935         return 0;
1936     }
1937 
1938     if (pAtom != NULL)
1939     {
1940         return pAtom->getRecordingYear();
1941     }
1942     else
1943     {
1944         return 0;
1945     }
1946 }
1947 
getLayer(uint32 id)1948 int16 MovieAtom::getLayer(uint32 id)
1949 {
1950     TrackAtom *track = getTrackForID(id);
1951 
1952     if (track != NULL)
1953     {
1954         return track->getLayer();
1955     }
1956     else
1957     {
1958         return 0;
1959     }
1960 }
1961 
getAlternateGroup(uint32 id)1962 uint16 MovieAtom::getAlternateGroup(uint32 id)
1963 {
1964     TrackAtom *track = getTrackForID(id);
1965 
1966     if (track != NULL)
1967     {
1968         return track->getAlternateGroup();
1969     }
1970     else
1971     {
1972         return 0;
1973     }
1974 }
1975 
getTextTrackWidth(uint32 id)1976 int32 MovieAtom::getTextTrackWidth(uint32 id)
1977 {
1978     TrackAtom *track = getTrackForID(id);
1979 
1980     if (track != NULL)
1981     {
1982         return track->getTextTrackWidth();
1983     }
1984     else
1985     {
1986         return (-1);
1987     }
1988 }
1989 
getTextTrackHeight(uint32 id)1990 int32 MovieAtom::getTextTrackHeight(uint32 id)
1991 {
1992     TrackAtom *track = getTrackForID(id);
1993 
1994     if (track != NULL)
1995     {
1996         return track->getTextTrackHeight();
1997     }
1998     else
1999     {
2000         return (-1);
2001     }
2002 }
2003 
getTextTrackXOffset(uint32 id)2004 int32 MovieAtom::getTextTrackXOffset(uint32 id)
2005 {
2006     TrackAtom *track = getTrackForID(id);
2007 
2008     if (track != NULL)
2009     {
2010         return track->getTextTrackXOffset();
2011     }
2012     else
2013     {
2014         return (-1);
2015     }
2016 }
2017 
2018 
getTextTrackYOffset(uint32 id)2019 int32 MovieAtom::getTextTrackYOffset(uint32 id)
2020 {
2021     TrackAtom *track = getTrackForID(id);
2022 
2023     if (track != NULL)
2024     {
2025         return track->getTextTrackYOffset();
2026     }
2027     else
2028     {
2029         return (-1);
2030     }
2031 }
2032 
2033 SampleEntry*
getTextSampleEntryAt(uint32 id,uint32 index)2034 MovieAtom::getTextSampleEntryAt(uint32 id, uint32 index)
2035 {
2036     TrackAtom *track = getTrackForID(id);
2037 
2038     if (track != NULL)
2039     {
2040         return track->getTextSampleEntryAt(index);
2041     }
2042     else
2043     {
2044         return NULL;
2045     }
2046 }
2047 
getTrackTSStartOffset(uint32 & aTSOffset,uint32 aTrackID)2048 int32 MovieAtom::getTrackTSStartOffset(uint32& aTSOffset, uint32 aTrackID)
2049 {
2050     aTSOffset = 0;
2051     TrackAtom *track = getTrackForID(aTrackID);
2052 
2053     uint32 movieTimeScale = _pmovieHeaderAtom->getTimeScale();
2054     if (track != NULL)
2055     {
2056         return track->getTrackTSOffset(aTSOffset, movieTimeScale);
2057     }
2058     else
2059     {
2060         return READ_FAILED;
2061     }
2062 }
2063 
2064 
2065 
getNumAMRFramesPerSample(uint32 trackID)2066 int32 MovieAtom::getNumAMRFramesPerSample(uint32 trackID)
2067 {
2068     TrackAtom *trackAtom;
2069     trackAtom = getTrackForID(trackID);
2070 
2071     if (trackAtom != NULL)
2072     {
2073         return (trackAtom->getNumAMRFramesPerSample());
2074     }
2075     else
2076     {
2077         return 0;
2078     }
2079 }
2080 
2081 
getMaxTrackTimeStamp(uint32 trackID,uint32 fileSize,uint32 & timeStamp)2082 MP4_ERROR_CODE MovieAtom::getMaxTrackTimeStamp(uint32 trackID,
2083         uint32 fileSize,
2084         uint32& timeStamp)
2085 {
2086     TrackAtom *trackAtom;
2087     trackAtom = getTrackForID(trackID);
2088 
2089     if (trackAtom != NULL)
2090     {
2091         return (trackAtom->getMaxTrackTimeStamp(fileSize,
2092                                                 timeStamp));
2093     }
2094     else
2095     {
2096         return DEFAULT_ERROR;
2097     }
2098 }
2099 
getSampleNumberClosestToTimeStamp(uint32 trackID,uint32 & sampleNumber,uint32 timeStamp,uint32 sampleOffset)2100 MP4_ERROR_CODE MovieAtom::getSampleNumberClosestToTimeStamp(uint32 trackID,
2101         uint32 &sampleNumber,
2102         uint32 timeStamp,
2103         uint32 sampleOffset)
2104 {
2105     TrackAtom *trackAtom;
2106     trackAtom = getTrackForID(trackID);
2107 
2108     if (trackAtom != NULL)
2109     {
2110         return
2111             (trackAtom->getSampleNumberClosestToTimeStamp(sampleNumber,
2112                     timeStamp,
2113                     sampleOffset));
2114     }
2115     else
2116     {
2117         return (READ_FAILED);
2118     }
2119 }
2120 
2121 
getAVCSampleEntry(uint32 trackID,uint32 index)2122 AVCSampleEntry* MovieAtom::getAVCSampleEntry(uint32 trackID, uint32 index)
2123 {
2124     TrackAtom *trackAtom;
2125     trackAtom = getTrackForID(trackID);
2126 
2127     if (trackAtom != NULL)
2128     {
2129         return (trackAtom->getAVCSampleEntry(index));
2130     }
2131     return (NULL);
2132 }
2133 
2134 
getAVCNALLengthSize(uint32 trackID,uint32 index)2135 uint32 MovieAtom::getAVCNALLengthSize(uint32 trackID, uint32 index)
2136 {
2137     TrackAtom *trackAtom;
2138     trackAtom = getTrackForID(trackID);
2139 
2140     if (trackAtom != NULL)
2141     {
2142         return (trackAtom->getAVCNALLengthSize(index));
2143     }
2144     return 0;
2145 }
2146 
2147 
2148 
getNumAVCSampleEntries(uint32 trackID)2149 uint32 MovieAtom::getNumAVCSampleEntries(uint32 trackID)
2150 {
2151     TrackAtom *trackAtom;
2152     trackAtom = getTrackForID(trackID);
2153 
2154     if (trackAtom != NULL)
2155     {
2156         return (trackAtom->getNumAVCSampleEntries());
2157     }
2158     return 0;
2159 }
2160 
2161 
isMultipleSampleDescriptionAvailable(uint32 trackID)2162 OSCL_EXPORT_REF bool MovieAtom::isMultipleSampleDescriptionAvailable(uint32 trackID)
2163 {
2164     TrackAtom *trackAtom;
2165     trackAtom = getTrackForID(trackID);
2166 
2167     if (trackAtom != NULL)
2168     {
2169         return (trackAtom->isMultipleSampleDescriptionAvailable());
2170     }
2171     return 0;
2172 }
2173 
getTimestampForRandomAccessPoints(uint32 id,uint32 * num,uint32 * tsBuf,uint32 * numBuf,uint32 * offsetBuf)2174 int32 MovieAtom::getTimestampForRandomAccessPoints(uint32 id, uint32 *num, uint32 *tsBuf, uint32* numBuf, uint32* offsetBuf)
2175 {
2176     TrackAtom *trackAtom;
2177     trackAtom = getTrackForID(id);
2178     if (trackAtom != NULL)
2179     {
2180         return trackAtom->getTimestampForRandomAccessPoints(num, tsBuf, numBuf, offsetBuf);
2181     }
2182     else
2183     {
2184         return 0;
2185     }
2186 }
2187 
getTimestampForRandomAccessPointsBeforeAfter(uint32 id,uint32 ts,uint32 * tsBuf,uint32 * numBuf,uint32 & numsamplestoget,uint32 howManyKeySamples)2188 int32 MovieAtom::getTimestampForRandomAccessPointsBeforeAfter(uint32 id, uint32 ts, uint32 *tsBuf, uint32* numBuf,
2189         uint32& numsamplestoget,
2190         uint32 howManyKeySamples)
2191 {
2192     TrackAtom *trackAtom;
2193     trackAtom = getTrackForID(id);
2194     if (trackAtom != NULL)
2195     {
2196         return trackAtom->getTimestampForRandomAccessPointsBeforeAfter(ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples);
2197     }
2198     else
2199     {
2200         return 0;
2201     }
2202 
2203 }
2204 
2205