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