• 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 Movie Fragment Atom Class                             */
21 /*     -------------------------------------------------------------------       */
22 /*********************************************************************************/
23 /*
24 */
25 
26 #define IMPLEMENT_MovieFragmentAtom
27 
28 #include "moviefragmentatom.h"
29 #include "moviefragmentheaderatom.h"
30 #include "trackfragmentatom.h"
31 #include "atomdefs.h"
32 #include "atomutils.h"
33 
34 typedef Oscl_Vector<TrackFragmentAtom*, OsclMemAllocator> trackFragmentAtomVecType;
35 // Constructor
MovieFragmentAtom(MP4_FF_FILE * fp,uint32 & size,uint32 type,TrackDurationContainer * trackDurationContainer,Oscl_Vector<TrackExtendsAtom *,OsclMemAllocator> * trackExtendAtomVec,bool & parseMoofCompletely,bool & moofParsingCompleted,uint32 & countOfTrunsParsed)36 MovieFragmentAtom::MovieFragmentAtom(MP4_FF_FILE *fp,
37                                      uint32 &size,
38                                      uint32 type,
39                                      TrackDurationContainer *trackDurationContainer,
40                                      Oscl_Vector<TrackExtendsAtom*, OsclMemAllocator> *trackExtendAtomVec,
41                                      bool &parseMoofCompletely,
42                                      bool &moofParsingCompleted,
43                                      uint32 &countOfTrunsParsed)
44 
45         : Atom(fp, size, type)
46 {
47     _pMovieFragmentHeaderAtom       = NULL;
48     _pTrackFragmentAtom             = NULL;
49     _pMovieFragmentCurrentOffset    = 0;
50     _pMovieFragmentBaseOffset       = 0;
51     _currentTrackFragmentOffset     = 0;
52     _trafIndex = 0;
53 
54     parseTrafCompletely = true;
55     trafParsingCompleted = true;
56     sizeRemaining = 0;
57     atomtype = UNKNOWN_ATOM;
58 
59     _pMovieFragmentBaseOffset = AtomUtils::getCurrentFilePosition(fp);
60     _pMovieFragmentCurrentOffset = _pMovieFragmentBaseOffset;
61 
62     iLogger = PVLogger::GetLoggerObject("mp4ffparser");
63     iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
64     iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
65 
66     uint32 count = size - DEFAULT_ATOM_SIZE;
67 
68     if (_success)
69     {
70         PV_MP4_FF_NEW(fp->auditCB, trackFragmentAtomVecType, (), _ptrackFragmentArray);
71 
72         while (count > 0)
73         {
74             uint32 atomType = UNKNOWN_ATOM;
75             uint32 atomSize = 0;
76 
77             AtomUtils::getNextAtomType(fp, atomSize, atomType);
78 
79             if (atomType == MOVIE_FRAGMENT_HEADER_ATOM)
80             {
81                 if (_pMovieFragmentHeaderAtom == NULL)
82                 {
83                     PV_MP4_FF_NEW(fp->auditCB, MovieFragmentHeaderAtom, (fp, atomSize, atomType), _pMovieFragmentHeaderAtom);
84                     if (!_pMovieFragmentHeaderAtom->MP4Success())
85                     {
86                         _success = false;
87                         _mp4ErrorCode = READ_MOVIE_FRAGMENT_HEADER_FAILED;
88                         return;
89                     }
90                     count -= _pMovieFragmentHeaderAtom->getSize();
91                 }
92                 else
93                 {
94                     //duplicate atom
95                     count -= atomSize;
96                     atomSize -= DEFAULT_ATOM_SIZE;
97                     AtomUtils::seekFromCurrPos(fp, atomSize);
98                 }
99             }
100             else if (atomType == TRACK_FRAGMENT_ATOM)
101             {
102                 if (!parseMoofCompletely)
103                 {
104                     parseTrafCompletely = false;
105                 }
106 
107                 PV_MP4_FF_NEW(fp->auditCB, TrackFragmentAtom, (fp, atomSize,
108                               atomType, _pMovieFragmentCurrentOffset,
109                               _pMovieFragmentBaseOffset,
110                               size, trackDurationContainer,
111                               trackExtendAtomVec,
112                               parseTrafCompletely,
113                               trafParsingCompleted,
114                               countOfTrunsParsed),
115                               _pTrackFragmentAtom);
116                 if (trafParsingCompleted)
117                 {
118                     if (!_pTrackFragmentAtom->MP4Success())
119                     {
120                         _success = false;
121                         _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
122                         return;
123                     }
124                     count -= _pTrackFragmentAtom->getSize();
125                     size = count;
126                     _ptrackFragmentArray->push_back(_pTrackFragmentAtom);
127                     _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
128                 }
129                 else
130                 {
131                     _ptrackFragmentArray->push_back(_pTrackFragmentAtom);
132                     size = count;
133                     sizeRemaining = atomSize;
134                     atomtype = atomType;
135 
136                     if (sizeRemaining == 0)
137                     {
138                         trafParsingCompleted = true;
139                         if (!_pTrackFragmentAtom->MP4Success())
140                         {
141                             _success = false;
142                             _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
143                             return;
144                         }
145                         count -= _pTrackFragmentAtom->getSize();
146                         size = count;
147                         _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
148                     }
149                 }
150 
151                 if (!parseMoofCompletely)
152                 {
153                     moofParsingCompleted = false;
154                     break;
155                 }
156             }
157             else
158             {
159                 count -= atomSize;
160                 atomSize -= DEFAULT_ATOM_SIZE;
161                 AtomUtils::seekFromCurrPos(fp, atomSize);
162             }
163         }
164         _trafIndex = _ptrackFragmentArray->size();
165 
166         if (count == 0)
167         {
168             moofParsingCompleted = true;
169         }
170     }
171     else
172     {
173         _mp4ErrorCode = READ_MOVIE_FRAGMENT_ATOM_FAILED;
174     }
175 }
176 
ParseMoofAtom(MP4_FF_FILE * fp,uint32 & size,uint32 type,TrackDurationContainer * trackDurationContainer,Oscl_Vector<TrackExtendsAtom *,OsclMemAllocator> * trackExtendAtomVec,bool & moofParsingCompleted,uint32 & countOfTrunsParsed)177 void MovieFragmentAtom::ParseMoofAtom(MP4_FF_FILE *fp,
178                                       uint32 &size,
179                                       uint32 type,
180                                       TrackDurationContainer *trackDurationContainer,
181                                       Oscl_Vector<TrackExtendsAtom*, OsclMemAllocator> *trackExtendAtomVec,
182                                       bool &moofParsingCompleted,
183                                       uint32 &countOfTrunsParsed)
184 {
185     OSCL_UNUSED_ARG(type);
186     uint32 count = size;
187 
188     if (_success)
189     {
190         if (count > 0)
191         {
192             if (!trafParsingCompleted)
193             {
194                 _pTrackFragmentAtom->ParseTrafAtom(fp, sizeRemaining,
195                                                    atomtype, _pMovieFragmentCurrentOffset,
196                                                    _pMovieFragmentBaseOffset,
197                                                    size, trackDurationContainer,
198                                                    trackExtendAtomVec,
199                                                    trafParsingCompleted,
200                                                    countOfTrunsParsed);
201                 if (trafParsingCompleted)
202                 {
203                     if (!_pTrackFragmentAtom->MP4Success())
204                     {
205                         _success = false;
206                         _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
207                         return;
208                     }
209                     count -= _pTrackFragmentAtom->getSize();
210                     size = count;
211                     _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
212                 }
213                 else
214                 {
215                     if (sizeRemaining == 0)
216                     {
217                         trafParsingCompleted = true;
218                         if (!_pTrackFragmentAtom->MP4Success())
219                         {
220                             _success = false;
221                             _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
222                             return;
223                         }
224                         count -= _pTrackFragmentAtom->getSize();
225                         size = count;
226                         _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
227                     }
228                 }
229             }
230             else if (count > 0)
231             {
232                 uint32 atomType = UNKNOWN_ATOM;
233                 uint32 atomSize = 0;
234 
235                 AtomUtils::getNextAtomType(fp, atomSize, atomType);
236 
237                 if (atomType == TRACK_FRAGMENT_ATOM)
238                 {
239                     PV_MP4_FF_NEW(fp->auditCB, TrackFragmentAtom, (fp, atomSize,
240                                   atomType, _pMovieFragmentCurrentOffset,
241                                   _pMovieFragmentBaseOffset,
242                                   size, trackDurationContainer,
243                                   trackExtendAtomVec,
244                                   parseTrafCompletely,
245                                   trafParsingCompleted,
246                                   countOfTrunsParsed),
247                                   _pTrackFragmentAtom);
248 
249                     if (trafParsingCompleted)
250                     {
251                         if (!_pTrackFragmentAtom->MP4Success())
252                         {
253                             _success = false;
254                             _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
255                             return;
256                         }
257                         count -= _pTrackFragmentAtom->getSize();
258                         size = count;
259                         _ptrackFragmentArray->push_back(_pTrackFragmentAtom);
260                         _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
261                     }
262                     else
263                     {
264                         _ptrackFragmentArray->push_back(_pTrackFragmentAtom);
265                         sizeRemaining = atomSize;
266                         atomtype = atomType;
267 
268                         if (sizeRemaining == 0)
269                         {
270                             trafParsingCompleted = true;
271                             if (!_pTrackFragmentAtom->MP4Success())
272                             {
273                                 _success = false;
274                                 _mp4ErrorCode = READ_TRACK_FRAGMENT_ATOM_FAILED;
275                                 return;
276                             }
277                             count -= _pTrackFragmentAtom->getSize();
278                             size = count;
279                             _pMovieFragmentCurrentOffset += _pTrackFragmentAtom->_trackFragmentEndOffset;
280                         }
281                     }
282                 }
283                 else
284                 {
285                     count -= atomSize;
286                     atomSize -= DEFAULT_ATOM_SIZE;
287                     AtomUtils::seekFromCurrPos(fp, atomSize);
288                 }
289             }
290             _trafIndex = _ptrackFragmentArray->size();
291         }
292         if (count == 0)
293         {
294             moofParsingCompleted = true;
295         }
296     }
297     else
298     {
299         _mp4ErrorCode = READ_MOVIE_FRAGMENT_ATOM_FAILED;
300     }
301 }
302 
303 
304 int32
getNextBundledAccessUnits(uint32 id,uint32 * n,uint32 totalSampleRead,GAU * pgau)305 MovieFragmentAtom::getNextBundledAccessUnits(uint32 id,
306         uint32 *n, uint32 totalSampleRead,
307         GAU    *pgau)
308 {
309     int32 nReturn = -1;
310 
311     TrackFragmentAtom *trackfragment = getTrackFragmentforID(id);
312 
313     if (trackfragment != NULL)
314     {
315         nReturn =  trackfragment->getNextBundledAccessUnits(n, totalSampleRead, pgau);
316     }
317     return (nReturn);
318 }
319 
320 int32
peekNextBundledAccessUnits(uint32 id,uint32 * n,uint32 totalSampleRead,MediaMetaInfo * mInfo)321 MovieFragmentAtom::peekNextBundledAccessUnits(uint32 id,
322         uint32 *n, uint32 totalSampleRead,
323         MediaMetaInfo *mInfo)
324 {
325     int32 nReturn = -1;
326 
327     TrackFragmentAtom *trackfragment = getTrackFragmentforID(id);
328 
329     if (trackfragment != NULL)
330     {
331         nReturn =  trackfragment->peekNextBundledAccessUnits(n, totalSampleRead, mInfo);
332     }
333     return (nReturn);
334 }
335 
resetPlayback(uint32 trackID,uint32 time,uint32 traf_number,uint32 trun_number,uint32 sample_num)336 int32 MovieFragmentAtom::resetPlayback(uint32 trackID, uint32 time, uint32 traf_number, uint32 trun_number, uint32 sample_num)
337 {
338     int32 nReturn = -1;
339 
340     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "MovieFragmentAtom::resetPlayback Called TrackID %d", trackID));
341     if (traf_number > 0)
342     {
343         TrackFragmentAtom *trackfragment = (*_ptrackFragmentArray)[traf_number-1];
344         if (trackfragment != NULL)
345         {
346             if (trackfragment->getTrackId() == trackID)
347             {
348                 nReturn =  trackfragment->resetPlayback(time, trun_number, sample_num);
349                 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "MovieFragmentAtom::resetPlayback Return Time %d", nReturn));
350             }
351         }
352     }
353     else
354     {
355         TrackFragmentAtom *trackfragment;
356         for (uint32 i = 0; i < _ptrackFragmentArray->size(); i++)
357         {
358             trackfragment = (*_ptrackFragmentArray)[i];
359             if (trackfragment != NULL)
360             {
361                 if (trackfragment->getTrackId() == trackID)
362                 {
363                     nReturn = trackfragment->resetPlayback(time);
364                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "MovieFragmentAtom::resetPlayback Return Time %d", nReturn));
365                     break;
366                 }
367             }
368         }
369     }
370     return (nReturn);
371 }
372 
resetPlayback()373 void MovieFragmentAtom::resetPlayback()
374 {
375     uint32 i;
376     TrackFragmentAtom *trackfragment;
377     for (i = 0; i < _ptrackFragmentArray->size(); i++)
378     {
379         trackfragment = (*_ptrackFragmentArray)[i];;
380 
381         if (trackfragment != NULL)
382         {
383             trackfragment->resetPlayback();
384         }
385     }
386 }
~MovieFragmentAtom()387 MovieFragmentAtom::~MovieFragmentAtom()
388 {
389     if (_pMovieFragmentHeaderAtom != NULL)
390     {
391         PV_MP4_FF_DELETE(NULL, MovieFragmentHeaderAtom, _pMovieFragmentHeaderAtom);
392         _pMovieFragmentHeaderAtom = NULL;
393     }
394     for (uint32 i = 0; i < _ptrackFragmentArray->size(); i++)
395     {
396         PV_MP4_FF_DELETE(NULL, TrackFragmentAtom, (*_ptrackFragmentArray)[i]);
397     }
398     PV_MP4_FF_TEMPLATED_DELETE(NULL, trackFragmentAtomVecType, Oscl_Vector, _ptrackFragmentArray);
399 
400 }
401 
402 uint32
getCurrentTrafDuration(uint32 id)403 MovieFragmentAtom::getCurrentTrafDuration(uint32 id)
404 {
405     int32 nReturn = 0;
406 
407     TrackFragmentAtom *trackfragment = getTrackFragmentforID(id);
408 
409     if (trackfragment != NULL)
410     {
411         nReturn =  trackfragment->getCurrentTrafDuration();
412     }
413     return (nReturn);
414 }
415 
416 uint32
getTotalSampleInTraf(uint32 id)417 MovieFragmentAtom::getTotalSampleInTraf(uint32 id)
418 {
419     int32 nTotalSamples = 0;
420 
421     TrackFragmentAtom *trackfragment = getTrackFragmentforID(id);
422 
423     if (trackfragment != NULL)
424     {
425         nTotalSamples =  trackfragment->getTotalNumSampleInTraf();
426     }
427     return (nTotalSamples);
428 }
429 
430 int32
getOffsetByTime(uint32 id,uint32 ts,int32 * sampleFileOffset)431 MovieFragmentAtom::getOffsetByTime(uint32 id, uint32 ts, int32* sampleFileOffset)
432 {
433     int32 nReturn = DEFAULT_ERROR;
434 
435     TrackFragmentAtom *trackfragment = getTrackFragmentforID(id);
436 
437     if (trackfragment != NULL)
438     {
439         nReturn =  trackfragment->getOffsetByTime(id, ts, sampleFileOffset);
440     }
441     return (nReturn);
442 }
443 
444 TrackFragmentAtom *
getTrackFragmentforID(uint32 id)445 MovieFragmentAtom::getTrackFragmentforID(uint32 id)
446 {
447     TrackFragmentAtom *trackFragmentAtom = NULL;
448 
449     uint32 numTrafs = _ptrackFragmentArray->size();
450     for (uint32 idx = 0; idx < numTrafs; idx++)
451     {
452         trackFragmentAtom = (*_ptrackFragmentArray)[idx];
453         if (trackFragmentAtom != NULL)
454         {
455             if (trackFragmentAtom->getTrackId() == id)
456             {
457                 return trackFragmentAtom;
458             }
459         }
460     }
461     return NULL;
462 }
463