• 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     This PVA_FF_MovieAtom Class fp the main atom class in the MPEG-4 File that stores
20     all the meta data about the MPEG-4 presentation.
21 */
22 
23 
24 #define IMPLEMENT_MovieAtom
25 
26 #include "movieatom.h"
27 #include "atomutils.h"
28 #include "a_atomdefs.h"
29 
30 #define MEDIA_TRACK_ID_OFFSET 3
31 
32 typedef Oscl_Vector<PVA_FF_TrackAtom*, OsclMemAllocator> PVA_FF_TrackAtomVecType;
33 
34 // Constructor
PVA_FF_MovieAtom(uint32 fileAuthoringFlags)35 PVA_FF_MovieAtom::PVA_FF_MovieAtom(uint32 fileAuthoringFlags)
36         :   PVA_FF_Atom(MOVIE_ATOM)
37 {
38     _success = true;
39 
40     _scalability = -1;
41     _fileType = 0;
42 
43     // Initializations
44 
45     _pAssetInfoCopyRightAtom        = NULL;
46     _pAssetInfoAuthorAtom           = NULL;
47     _pAssetInfoTitleAtom            = NULL;
48     _pAssetInfoDescAtom             = NULL;
49     _pAssetInfoPerformerAtom        = NULL;
50     _pAssetInfoGenreAtom            = NULL;
51     _pAssetInfoRatingAtom           = NULL;
52     _pAssetInfoClassificationAtom   = NULL;
53     _pAssetInfoKeyWordsAtom         = NULL;
54     _pAssetInfoLocationInfoAtom     = NULL;
55     _pAssetInfoKeyAlbumAtom         = NULL;
56     _pAssetInfoKeyRecordingYearAtom = NULL;
57 
58     _oMovieFragmentEnabled = false;
59     //Movie Fragment : Enable movie fragment mode and create movie extends atom
60     if ((fileAuthoringFlags & PVMP4FF_MOVIE_FRAGMENT_MODE) == (PVMP4FF_MOVIE_FRAGMENT_MODE))
61     {
62         _oMovieFragmentEnabled = true;
63         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieExtendsAtom, (), _pMovieExtendsAtom);
64 
65     }
66 
67     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_MovieHeaderAtom, ((uint8)0, (uint32)0, fileAuthoringFlags), _pmovieHeaderAtom);
68 
69 
70     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _pMediaTrackVec);
71     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackAtomVecType, (), _pmpeg4TrackVec);
72 
73     // Create user data atom
74     PV_MP4_FF_NEW(fp->auditCB, PVA_FF_UserDataAtom, (), _puserDataAtom);
75     _puserDataAtom->setParent(this);
76 
77     setTimeScale(DEFAULT_PRESENTATION_TIMESCALE); // Set default value for timescale
78 
79     recomputeSize();
80 
81     _pmovieHeaderAtom->setParent(this);
82 }
83 
84 // Destructor - delete the vector(s) of TrackAtoms from the heap
~PVA_FF_MovieAtom()85 PVA_FF_MovieAtom::~PVA_FF_MovieAtom()
86 {
87     uint32 i;
88 
89     PV_MP4_FF_DELETE(NULL, PVA_FF_MovieHeaderAtom, _pmovieHeaderAtom);
90 
91     // Delete mpeg4 general tracks
92     for (i = 0; i < _pmpeg4TrackVec->size(); i++)
93     {
94         PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, (*_pmpeg4TrackVec)[i]);
95     }
96     PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackAtomVecType, Oscl_Vector, _pmpeg4TrackVec);
97 
98     // Delete media tracks
99     for (i = 0; i < _pMediaTrackVec->size(); i++)
100     {
101         PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, (*_pMediaTrackVec)[i]);
102     }
103     PV_MP4_FF_TEMPLATED_DELETE(NULL, PVA_FF_TrackAtomVecType, Oscl_Vector, _pMediaTrackVec);
104 
105     if (_puserDataAtom != NULL)
106     {
107         PV_MP4_FF_DELETE(NULL, PVA_FF_UserDataAtom, _puserDataAtom);
108     }
109     //Movie Fragment : delete mvex atom
110     if (_oMovieFragmentEnabled == true)
111     {
112         PV_MP4_FF_DELETE(NULL, PVA_FF_MovieExtendsAtom, _pMovieExtendsAtom);
113     }
114 
115 }
116 
117 // Add a new PVA_FF_TrackAtom to this container
118 void
addTrackAtom(PVA_FF_TrackAtom * a)119 PVA_FF_MovieAtom::addTrackAtom(PVA_FF_TrackAtom *a)
120 {
121     // Set presentation timescale
122     a->setTimeScale(getTimeScale());
123 
124     switch (a->getMediaType())
125     {
126         case MEDIA_TYPE_TEXT://added for timed text track
127         {
128             _fileType |= FILE_TYPE_TIMED_TEXT;
129             _pMediaTrackVec->push_back(a);
130             a->setParent(this);
131         }
132         break;
133         case MEDIA_TYPE_AUDIO:
134         {
135             _fileType |= FILE_TYPE_AUDIO;
136             _pMediaTrackVec->push_back(a);
137             a->setParent(this);
138             // add trex atom in movie fragment mode
139             if (_oMovieFragmentEnabled == true)
140             {
141                 PVA_FF_TrackExtendsAtom  *pTrexAtom;
142                 PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackExtendsAtom, (a->getMediaType(), a->getCodecType(), a->getTrackID()), pTrexAtom);
143                 _pMovieExtendsAtom->addTrexAtom(pTrexAtom);
144             }
145 
146         }
147         break;
148         case MEDIA_TYPE_VISUAL:
149         {
150             _fileType |= FILE_TYPE_VIDEO;
151             _scalability += 1;
152             _pMediaTrackVec->push_back(a);
153             a->setParent(this);
154 
155             // add trex atom in movie fragment mode
156             if (_oMovieFragmentEnabled == true)
157             {
158                 PVA_FF_TrackExtendsAtom  *pTrexAtom;
159                 PV_MP4_FF_NEW(fp->auditCB, PVA_FF_TrackExtendsAtom, (a->getMediaType(), a->getCodecType(), a->getTrackID()), pTrexAtom);
160                 _pMovieExtendsAtom->addTrexAtom(pTrexAtom);
161             }
162         }
163         break;
164         default:
165             PV_MP4_FF_DELETE(NULL, PVA_FF_TrackAtom, a);
166             break;
167     }
168     recomputeSize();
169 
170 }
171 
172 void
setTargetBitrate(uint32 trackID,uint32 avgBitRate,uint32 maxBitRate,uint32 bufferSizeDB)173 PVA_FF_MovieAtom::setTargetBitrate(uint32 trackID, uint32 avgBitRate, uint32 maxBitRate, uint32 bufferSizeDB)
174 {
175     PVA_FF_TrackAtom *track = getMediaTrack(trackID);
176 
177     if (track != NULL)
178     {
179         track->setTargetBitrate(avgBitRate, maxBitRate, bufferSizeDB);
180     }
181     return;
182 }
183 
184 void
setTimeScale(uint32 trackID,uint32 rate)185 PVA_FF_MovieAtom::setTimeScale(uint32 trackID, uint32 rate)
186 {
187     PVA_FF_TrackAtom *track = getMediaTrack(trackID);
188 
189     if (track != NULL)
190     {
191         track->setMediaTimeScale(rate);
192     }
193     return;
194 }
195 
196 PVA_FF_TrackAtom*
getMpeg4Track(int32 index)197 PVA_FF_MovieAtom::getMpeg4Track(int32 index)
198 {
199     if (index < (int32)_pmpeg4TrackVec->size())
200     {
201         return (*_pmpeg4TrackVec)[index];
202     }
203     else
204     {
205         return NULL;
206     }
207 }
208 
209 
210 // timescale for ENTIRE presentation
211 void
setTimeScale(uint32 ts)212 PVA_FF_MovieAtom::setTimeScale(uint32 ts)
213 {
214     // Set timescale in movieheader atom
215     _pmovieHeaderAtom->setTimeScale(ts);
216 
217 }
218 
219 
220 // Get timescale from movieheader atom for ENTIRE presentation
221 uint32
getTimeScale() const222 PVA_FF_MovieAtom::getTimeScale() const
223 {
224     return _pmovieHeaderAtom->getTimeScale();
225 }
226 
227 // Recomputes the size of the current atom by checking all contained atoms
228 void
recomputeSize()229 PVA_FF_MovieAtom::recomputeSize()
230 {
231     int32 size = getDefaultSize(); // From base class
232 
233     size += _pmovieHeaderAtom->getSize();
234 
235     if (_puserDataAtom != NULL)
236     {
237         if (_puserDataAtom->getUserDataAtomVecSize() > 0)
238         {
239             size += _puserDataAtom->getSize();
240         }
241     }
242 
243     if (_pMediaTrackVec != NULL)
244     {
245         for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
246         {
247             if ((*_pMediaTrackVec)[i]->getSampleCount() > 0)
248             {
249                 size += (*_pMediaTrackVec)[i]->getSize();
250             }
251         }
252     }
253 
254     // in movie fragment mode add size of mvex
255     if (_oMovieFragmentEnabled == true)
256     {
257         size += _pMovieExtendsAtom->getSize();
258     }
259 
260     _size = size;
261 
262     // Update the size of the parent atom since this child atom may have changed
263     if (_pparent != NULL)
264     {
265         _pparent->recomputeSize();
266     }
267 
268 }
269 
270 void
prepareToRender()271 PVA_FF_MovieAtom::prepareToRender()
272 {
273     uint32 maxTrackDuration = 0;
274 
275     uint32 creationTime = _pmovieHeaderAtom->getCreationTime();
276     uint32 modTime      = _pmovieHeaderAtom->getModificationTime();
277 
278     if (_pMediaTrackVec != NULL)
279     {
280         for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
281         {
282             PVA_FF_TrackAtom *track = (*_pMediaTrackVec)[i];
283 
284             PVA_FF_TrackHeaderAtom *tkhdPtr = track->getTrackHeaderAtomPtr();
285 
286             if (tkhdPtr != NULL)
287             {
288                 tkhdPtr->setCreationTime(creationTime);
289                 tkhdPtr->setModificationTime(modTime);
290             }
291 
292             track->prepareToRender();
293 
294             uint32 TrackDuration = track->getDuration();
295 
296             if (TrackDuration > maxTrackDuration)
297             {
298                 maxTrackDuration = TrackDuration;
299             }
300         }
301 
302         if (maxTrackDuration > 0)
303         {
304             _pmovieHeaderAtom->setDuration(maxTrackDuration);
305         }
306     }
307 
308     recomputeSize();
309 
310     return;
311 }
312 
313 // Render this atom to a file stream
314 bool
renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP * fp)315 PVA_FF_MovieAtom::renderToFileStream(MP4_AUTHOR_FF_FILE_IO_WRAP *fp)
316 {
317     int32 rendered = 0; // Keep track of number of bytes rendered
318 
319     // Render PVA_FF_Atom type and size
320     if (!renderAtomBaseMembers(fp))
321     {
322         return false;
323     }
324     rendered += getDefaultSize();
325 
326 
327     // Render rest of atoms in container
328     // Render the movie header
329     if (!_pmovieHeaderAtom->renderToFileStream(fp))
330     {
331         return false;
332     }
333     rendered += _pmovieHeaderAtom->getSize();
334     {
335         if (_puserDataAtom != NULL)
336         {
337             if (_puserDataAtom->getUserDataAtomVecSize() > 0)
338             {
339                 if (!_puserDataAtom->renderToFileStream(fp))
340                 {
341                     return false;
342                 }
343             }
344         }
345     }
346     // Render the object descriptor
347     if (_pMediaTrackVec != NULL)
348     {
349         for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
350         {
351             if ((*_pMediaTrackVec)[i]->getSampleCount() > 0)
352             {
353                 if (!((*_pMediaTrackVec)[i]->renderToFileStream(fp)))
354                 {
355                     return false;
356                 }
357                 rendered += (*_pMediaTrackVec)[i]->getSize();
358             }
359         }
360     }
361     // render MVEX atom in movie fragment mode
362     if (_oMovieFragmentEnabled == true)
363     {
364         if (_pMovieExtendsAtom->getDuration() == 0)
365         {
366             _pMovieExtendsAtom->setMovieFragmentDuration(getDuration());
367         }
368 
369         if (!_pMovieExtendsAtom->renderToFileStream(fp))
370         {
371             return false;
372         }
373         rendered += _pMovieExtendsAtom->getSize();
374     }
375 
376     return true;
377 }
378 
379 void
addDecoderSpecificInfo(PVA_FF_DecoderSpecificInfo * pinfo,int32 trackID)380 PVA_FF_MovieAtom::addDecoderSpecificInfo(PVA_FF_DecoderSpecificInfo *pinfo, int32 trackID)
381 {
382     PVA_FF_TrackAtom *mediaTrack = getMediaTrack(trackID);
383 
384     mediaTrack->addDecoderSpecificInfo(pinfo);
385 }
386 
387 //added for timed text
388 void
addTextDecoderSpecificInfo(PVA_FF_TextSampleDescInfo * pinfo,int32 trackID)389 PVA_FF_MovieAtom::addTextDecoderSpecificInfo(PVA_FF_TextSampleDescInfo *pinfo, int32 trackID)
390 {
391     PVA_FF_TrackAtom *mediaTrack = getMediaTrack(trackID);
392     mediaTrack->addTextDecoderSpecificInfo(pinfo);
393 }
394 
395 int32
getCodecType(uint32 trackID)396 PVA_FF_MovieAtom::getCodecType(uint32 trackID)
397 {
398     PVA_FF_TrackAtom *track = getMediaTrack(trackID);
399 
400     if (track != NULL)
401     {
402         return (track->getCodecType());
403     }
404     else
405     {
406         return (-1);
407     }
408 }
409 
410 PVA_FF_TrackAtom*
getMediaTrack(uint32 trackID)411 PVA_FF_MovieAtom::getMediaTrack(uint32 trackID)
412 {
413     for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
414     {
415         PVA_FF_TrackHeaderAtom *ptkhdr = (*_pMediaTrackVec)[i]->getTrackHeaderAtomPtr();
416 
417         if (ptkhdr->getTrackID() == trackID)
418         {
419             return (*_pMediaTrackVec)[i];
420         }
421     }
422 
423     return NULL;
424 }
425 
426 
427 void
setMaxBufferSizeDB(uint32 trackID,uint32 max)428 PVA_FF_MovieAtom::setMaxBufferSizeDB(uint32 trackID, uint32 max)
429 {
430     PVA_FF_TrackAtom *trackAtom = getMediaTrack(trackID);
431 
432     if (trackAtom != NULL)
433     {
434         trackAtom->setMaxBufferSizeDB(max);
435     }
436 }
437 
438 void
addSampleToTrack(uint32 trackID,uint8 * psample,uint32 size,uint32 ts,uint8 flags,uint32 baseOffset,bool oChunkStart)439 PVA_FF_MovieAtom::addSampleToTrack(uint32 trackID,
440                                    uint8 *psample,
441                                    uint32 size,
442                                    uint32 ts,
443                                    uint8 flags,
444                                    uint32 baseOffset,
445                                    bool oChunkStart)
446 {
447     PVA_FF_TrackAtom *mediaTrack;
448     uint32 mediaType = 0;
449 
450     mediaTrack = getMediaTrack(trackID);
451 
452     if (mediaTrack != NULL)
453     {
454         mediaType  = mediaTrack->getMediaType();
455 
456         uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
457         if (mediaTimeScale != 0)
458         {
459             uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
460 
461             // Add sample to movie header so can update its _duration
462             _pmovieHeaderAtom->addSample(ts_in_milliseconds);
463         }
464     }
465 
466 
467     if (mediaType == MEDIA_TYPE_VISUAL)
468     {
469         // Updates the members with the next sample received
470         mediaTrack->nextSample(MEDIA_TYPE_VISUAL,
471                                psample,
472                                size,
473                                ts,
474                                flags,
475                                baseOffset,
476                                oChunkStart);
477     }
478 
479     if (mediaType == MEDIA_TYPE_AUDIO)
480     {
481         // Updates the members with the next sample received
482         mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
483                                psample,
484                                size,
485                                ts,
486                                flags,
487                                baseOffset,
488                                oChunkStart);
489     }
490     if (mediaType == MEDIA_TYPE_TEXT)
491     {
492         // Updates the members with the next sample received
493         mediaTrack->nextSample(MEDIA_TYPE_TEXT,
494                                psample,
495                                size,
496                                ts,
497                                flags,
498                                baseOffset,
499                                oChunkStart);
500     }
501 }
502 
503 void
addTextSampleToTrack(uint32 trackID,uint8 * psample,uint32 size,uint32 ts,uint8 flags,int32 index,uint32 baseOffset,bool oChunkStart)504 PVA_FF_MovieAtom::addTextSampleToTrack(uint32 trackID,
505                                        uint8 *psample,
506                                        uint32 size,
507                                        uint32 ts,
508                                        uint8 flags,
509                                        int32 index,
510                                        uint32 baseOffset,
511                                        bool oChunkStart)
512 {
513     PVA_FF_TrackAtom *mediaTrack;
514     uint32 mediaType = 0;
515 
516     mediaTrack = getMediaTrack(trackID);
517 
518     if (mediaTrack != NULL)
519     {
520         mediaType  = mediaTrack->getMediaType();
521 
522         uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
523         if (mediaTimeScale != 0)
524         {
525             uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
526 
527             // Add sample to movie header so can update its _duration
528             _pmovieHeaderAtom->addSample(ts_in_milliseconds);
529         }
530     }
531 
532 
533     if (mediaType == MEDIA_TYPE_TEXT)
534     {
535         // Updates the members with the next sample received
536         mediaTrack->nextTextSample(MEDIA_TYPE_TEXT,
537                                    psample,
538                                    size,
539                                    ts,
540                                    flags,
541                                    index,
542                                    baseOffset,
543                                    oChunkStart);
544     }
545 }
546 
547 void
addSampleToTrack(uint32 trackID,Oscl_Vector<OsclMemoryFragment,OsclMemAllocator> & fragmentList,uint32 size,uint32 ts,uint8 flags,uint32 baseOffset,bool oChunkStart)548 PVA_FF_MovieAtom::addSampleToTrack(uint32 trackID,
549                                    Oscl_Vector <OsclMemoryFragment, OsclMemAllocator>& fragmentList,
550                                    uint32 size,
551                                    uint32 ts,
552                                    uint8 flags,
553                                    uint32 baseOffset,
554                                    bool oChunkStart)
555 {
556     PVA_FF_TrackAtom *mediaTrack;
557     uint32 mediaType = 0;
558 
559     mediaTrack = getMediaTrack(trackID);
560 
561     if (mediaTrack != NULL)
562     {
563         mediaType  = mediaTrack->getMediaType();
564 
565         uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
566         if (mediaTimeScale != 0)
567         {
568             uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
569 
570             // Add sample to movie header so can update its _duration
571             _pmovieHeaderAtom->addSample(ts_in_milliseconds);
572         }
573     }
574 
575     if (mediaType == MEDIA_TYPE_VISUAL)
576     {
577         // Updates the members with the next sample received
578         mediaTrack->nextSample(MEDIA_TYPE_VISUAL,
579                                fragmentList,
580                                size,
581                                ts,
582                                flags,
583                                baseOffset,
584                                oChunkStart);
585     }
586 
587     if (mediaType == MEDIA_TYPE_AUDIO)
588     {
589         // Updates the members with the next sample received
590         mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
591                                fragmentList,
592                                size,
593                                ts,
594                                flags,
595                                baseOffset,
596                                oChunkStart);
597     }
598 
599     if (mediaType == MEDIA_TYPE_TEXT)//added for the support of timed text track
600     {
601         // Updates the members with the next sample received
602         mediaTrack->nextSample(MEDIA_TYPE_AUDIO,
603                                fragmentList,
604                                size,
605                                ts,
606                                flags,
607                                baseOffset,
608                                oChunkStart);
609     }
610 
611 }
612 
613 void
addTextSampleToTrack(uint32 trackID,Oscl_Vector<OsclMemoryFragment,OsclMemAllocator> & fragmentList,uint32 size,uint32 ts,uint8 flags,int32 index,uint32 baseOffset,bool oChunkStart)614 PVA_FF_MovieAtom::addTextSampleToTrack(uint32 trackID,
615                                        Oscl_Vector <OsclMemoryFragment, OsclMemAllocator>& fragmentList,
616                                        uint32 size,
617                                        uint32 ts,
618                                        uint8 flags,
619                                        int32 index,
620                                        uint32 baseOffset,
621                                        bool oChunkStart)
622 {
623     PVA_FF_TrackAtom *mediaTrack;
624     uint32 mediaType = 0;
625 
626     mediaTrack = getMediaTrack(trackID);
627 
628     if (mediaTrack != NULL)
629     {
630         mediaType  = mediaTrack->getMediaType();
631 
632         uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
633         if (mediaTimeScale != 0)
634         {
635             uint32 ts_in_milliseconds = (uint32)((ts * 1000.0f) / mediaTimeScale);
636 
637             // Add sample to movie header so can update its _duration
638             _pmovieHeaderAtom->addSample(ts_in_milliseconds);
639         }
640     }
641 
642     if (mediaType == MEDIA_TYPE_TEXT)//added for the support of timed text track
643     {
644         // Updates the members with the next sample received
645         mediaTrack->nextTextSample(MEDIA_TYPE_TEXT,
646                                    fragmentList,
647                                    size,
648                                    ts,
649                                    flags,
650                                    index,
651                                    baseOffset,
652                                    oChunkStart);
653     }
654 
655 }
656 
657 bool
reAuthorFirstSampleInTrack(uint32 trackID,uint32 size,uint32 baseOffset)658 PVA_FF_MovieAtom::reAuthorFirstSampleInTrack(uint32 trackID,
659         uint32 size,
660         uint32 baseOffset)
661 {
662 
663     PVA_FF_TrackAtom *mediaTrack;
664 
665     mediaTrack = getMediaTrack(trackID);
666 
667     return (
668                mediaTrack->reAuthorFirstSample(size,
669                                                baseOffset));
670 }
671 
672 
673 void
populateCommonMetadataAtoms()674 PVA_FF_MovieAtom::populateCommonMetadataAtoms()
675 {
676 
677     if (_pAssetInfoCopyRightAtom == NULL)
678     {
679         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoCopyRightAtom, (), _pAssetInfoCopyRightAtom);
680         if (_puserDataAtom != NULL)
681         {
682             _puserDataAtom->addAtom(_pAssetInfoCopyRightAtom);
683         }
684     }
685 
686     if (_pAssetInfoAuthorAtom == NULL)
687     {
688         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoAuthorAtom, (), _pAssetInfoAuthorAtom);
689         if (_puserDataAtom != NULL)
690         {
691             _puserDataAtom->addAtom(_pAssetInfoAuthorAtom);
692         }
693     }
694     if (_pAssetInfoTitleAtom == NULL)
695     {
696         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoTitleAtom, (), _pAssetInfoTitleAtom);
697         if (_puserDataAtom != NULL)
698         {
699             _puserDataAtom->addAtom(_pAssetInfoTitleAtom);
700         }
701     }
702     if (_pAssetInfoDescAtom == NULL)
703     {
704         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoDescAtom, (), _pAssetInfoDescAtom);
705         if (_puserDataAtom != NULL)
706         {
707             _puserDataAtom->addAtom(_pAssetInfoDescAtom);
708         }
709     }
710 }
711 
712 
713 void
createAssetInfoAtoms()714 PVA_FF_MovieAtom::createAssetInfoAtoms()
715 {
716     populateCommonMetadataAtoms();
717 
718     if (_pAssetInfoPerformerAtom == NULL)
719     {
720         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoPerformerAtom, (), _pAssetInfoPerformerAtom);
721         if (_puserDataAtom != NULL)
722         {
723             _puserDataAtom->addAtom(_pAssetInfoPerformerAtom);
724         }
725     }
726 
727     if (_pAssetInfoGenreAtom == NULL)
728     {
729         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoGenreAtom, (), _pAssetInfoGenreAtom);
730         if (_puserDataAtom != NULL)
731         {
732             _puserDataAtom->addAtom(_pAssetInfoGenreAtom);
733         }
734     }
735 
736     if (_pAssetInfoRatingAtom == NULL)
737     {
738         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoRatingAtom, (), _pAssetInfoRatingAtom);
739         if (_puserDataAtom != NULL)
740         {
741             _puserDataAtom->addAtom(_pAssetInfoRatingAtom);
742         }
743     }
744 
745     if (_pAssetInfoClassificationAtom == NULL)
746     {
747         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoClassificationAtom, (), _pAssetInfoClassificationAtom);
748         if (_puserDataAtom != NULL)
749         {
750             _puserDataAtom->addAtom(_pAssetInfoClassificationAtom);
751         }
752     }
753 
754     if (_pAssetInfoKeyWordsAtom == NULL)
755     {
756         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoKeyWordsAtom, (), _pAssetInfoKeyWordsAtom);
757         if (_puserDataAtom != NULL)
758         {
759             _puserDataAtom->addAtom(_pAssetInfoKeyWordsAtom);
760         }
761     }
762 
763     if (_pAssetInfoLocationInfoAtom == NULL)
764     {
765         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoLocationInfoAtom, (), _pAssetInfoLocationInfoAtom);
766         if (_puserDataAtom != NULL)
767         {
768             _puserDataAtom->addAtom(_pAssetInfoLocationInfoAtom);
769         }
770     }
771 
772     if (_pAssetInfoKeyAlbumAtom == NULL)
773     {
774         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoAlbumAtom, (), _pAssetInfoKeyAlbumAtom);
775         if (_puserDataAtom != NULL)
776         {
777             _puserDataAtom->addAtom(_pAssetInfoKeyAlbumAtom);
778         }
779     }
780 
781     if (_pAssetInfoKeyRecordingYearAtom == NULL)
782     {
783         PV_MP4_FF_NEW(fp->auditCB, PVA_FF_AssetInfoRecordingYearAtom, (), _pAssetInfoKeyRecordingYearAtom);
784         if (_puserDataAtom != NULL)
785         {
786             _puserDataAtom->addAtom(_pAssetInfoKeyRecordingYearAtom);
787         }
788     }
789 
790 }
791 
792 // functions to set and update fragment duration in MVEX atom
793 void
setMovieFragmentDuration()794 PVA_FF_MovieAtom::setMovieFragmentDuration()
795 {
796 
797     _pMovieExtendsAtom->setMovieFragmentDuration(getDuration());
798 
799 }
800 
801 
802 void
updateMovieFragmentDuration(uint32 trackID,uint32 ts)803 PVA_FF_MovieAtom::updateMovieFragmentDuration(uint32 trackID, uint32 ts)
804 {
805     PVA_FF_TrackAtom *mediaTrack;
806     mediaTrack = getMediaTrack(trackID);
807     uint32 mediaTimeScale = mediaTrack->getMediaTimeScale();
808 
809     if (mediaTimeScale != 0)
810     {
811         uint32 ts_moviescale = (uint32)(ts * ((float)getTimeScale() / (float)mediaTimeScale));
812         _pMovieExtendsAtom->updateMovieFragmentDuration(ts_moviescale);
813     }
814 }
815 
816 void
writeMovieFragmentDuration(MP4_AUTHOR_FF_FILE_IO_WRAP * fp)817 PVA_FF_MovieAtom::writeMovieFragmentDuration(MP4_AUTHOR_FF_FILE_IO_WRAP* fp)
818 {
819     _pMovieExtendsAtom->writeMovieFragmentDuration(fp);
820 }
821 
822 void
SetMaxSampleSize(uint32 aTrackID,uint32 aSize)823 PVA_FF_MovieAtom::SetMaxSampleSize(uint32 aTrackID, uint32 aSize)
824 {
825     PVA_FF_TrackAtom *mediaTrack = NULL;
826     mediaTrack = getMediaTrack(aTrackID);
827     if (NULL != mediaTrack)
828         mediaTrack->SetMaxSampleSize(aSize);
829 }
830 
831 void
writeMaxSampleSize(MP4_AUTHOR_FF_FILE_IO_WRAP * _afp)832 PVA_FF_MovieAtom::writeMaxSampleSize(MP4_AUTHOR_FF_FILE_IO_WRAP *_afp)
833 {
834     for (uint32 i = 0; i < _pMediaTrackVec->size(); i++)
835     {
836         PVA_FF_TrackHeaderAtom *ptkhdr = NULL;
837         ptkhdr = (*_pMediaTrackVec)[i]->getTrackHeaderAtomPtr();
838         if (NULL != ptkhdr)
839         {
840             uint32 trackID = ptkhdr->getTrackID();
841             PVA_FF_TrackAtom *mediaTrack = NULL;
842             mediaTrack = getMediaTrack(trackID);
843             if (NULL != mediaTrack)
844                 mediaTrack->writeMaxSampleSize(_afp);
845         }
846     }
847 }
848