• 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 Track Fragment Atom Class                   */
21 /*     -------------------------------------------------------------------       */
22 /*********************************************************************************/
23 /*
24 */
25 
26 #define IMPLEMENT_TrackFragmentAtom
27 
28 #include "trackfragmentatom.h"
29 #include "trackfragmentheaderatom.h"
30 #include "trackfragmentrunatom.h"
31 #include "atomdefs.h"
32 #include "atomutils.h"
33 #include "oscl_int64_utils.h"
34 
35 typedef Oscl_Vector<TrackFragmentRunAtom*, OsclMemAllocator> trackFragmentRunAtomVecType;
36 typedef Oscl_Vector<uint32, OsclMemAllocator> trackFragmentRunOffsetVecType;
37 typedef Oscl_Vector<uint32, OsclMemAllocator> fragmentptrOffsetVecType;
38 
39 // Constructor
TrackFragmentAtom(MP4_FF_FILE * fp,uint32 & size,uint32 type,uint32 movieFragmentCurrentOffset,uint32 movieFragmentBaseOffset,uint32 moofSize,TrackDurationContainer * trackDurationContainer,Oscl_Vector<TrackExtendsAtom *,OsclMemAllocator> * trackExtendAtomVec,bool & parseTrafCompletely,bool & trafParsingCompleted,uint32 & countOfTrunsParsed)40 TrackFragmentAtom::TrackFragmentAtom(MP4_FF_FILE *fp,
41                                      uint32 &size,
42                                      uint32 type,
43                                      uint32 movieFragmentCurrentOffset,
44                                      uint32 movieFragmentBaseOffset,
45                                      uint32 moofSize,
46                                      TrackDurationContainer *trackDurationContainer,
47                                      Oscl_Vector<TrackExtendsAtom*, OsclMemAllocator> *trackExtendAtomVec,
48                                      bool &parseTrafCompletely,
49                                      bool &trafParsingCompleted,
50                                      uint32 &countOfTrunsParsed)
51         : Atom(fp, size, type)
52 {
53     OSCL_UNUSED_ARG(movieFragmentCurrentOffset);
54 
55     _pTrackFragmentHeaderAtom       = NULL;
56     _pTrackFragmentRunAtom          = NULL;
57     _pinput = NULL;
58     _commonFilePtr = NULL;
59     _fileSize = 0;
60     _currentTrackFragmentRunSampleNumber = 0;
61     _currentPlaybackSampleTimestamp = 0;
62     _movieFragmentOffset = 0;
63     _prevSampleOffset = 0;
64     _trackEndDuration = 0;
65     _startTrackFragmentTSOffset = 0;
66     _pFragmentptrOffsetVec = NULL;
67     _peekPlaybackSampleNumber = 0;
68     _default_duration = 0;
69     _use_default_duratoin = false;
70     _pTrackDurationContainer = trackDurationContainer;
71 
72     tf_flags = 0;
73     trun_offset = 0;
74 
75     trunParsingCompleted = true;
76 
77     iLogger = PVLogger::GetLoggerObject("mp4ffparser_traf");
78     iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats_traf");
79     iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata_traf");
80 
81     OsclAny*ptr = oscl_malloc(sizeof(MP4_FF_FILE));
82     if (ptr == NULL)
83     {
84         _success = false;
85         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
86         return;
87     }
88     _pinput = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE(*fp));
89 
90     _pinput->_fileServSession = fp->_fileServSession;
91     _pinput->_pvfile.SetCPM(fp->_pvfile.GetCPM());
92     _pinput->_fileSize = fp->_fileSize;
93     _pinput->_pvfile.Copy(fp->_pvfile);
94 
95     uint32 trun_start = 0;
96     uint32 count = size - DEFAULT_ATOM_SIZE;
97 
98     uint32 _movieFragmentBaseOffset = movieFragmentBaseOffset - DEFAULT_ATOM_SIZE;
99     bool bdo_present = false;
100     uint32 base_data_offset = _movieFragmentBaseOffset;
101     trackId = 0;
102     trun_offset = moofSize + DEFAULT_ATOM_SIZE;
103 
104     if (_success)
105     {
106         PV_MP4_FF_NEW(fp->auditCB, trackFragmentRunAtomVecType, (), _pTrackFragmentRunAtomVec);
107         while (count > 0)
108         {
109             uint32 atomType = UNKNOWN_ATOM;
110             uint32 atomSize = 0;
111             AtomUtils::getNextAtomType(fp, atomSize, atomType);
112 
113             if (atomType == TRACK_FRAGMENT_HEADER_ATOM)
114             {
115                 if (_pTrackFragmentHeaderAtom == NULL)
116                 {
117                     PV_MP4_FF_NEW(fp->auditCB, TrackFragmentHeaderAtom, (fp, atomSize, atomType), _pTrackFragmentHeaderAtom);
118                     if (!_pTrackFragmentHeaderAtom->MP4Success())
119                     {
120                         _success = false;
121                         _mp4ErrorCode = READ_MOVIE_EXTENDS_HEADER_FAILED;
122                         return;
123                     }
124                     count -= _pTrackFragmentHeaderAtom->getSize();
125                     trackId = _pTrackFragmentHeaderAtom->getTrackId();
126                     tf_flags = _pTrackFragmentHeaderAtom->getFlags();
127                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "@@@@@@@@@@@@@@@****** Track ID= %d ********@@@@@@@@@@@@@@@@", trackId));
128                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "#### tf_flag =0x%x######", tf_flags));
129 
130                     if (tf_flags & 0x000001)
131                     {
132                         uint64 bdo = _pTrackFragmentHeaderAtom->getBaseDataOffset();
133                         base_data_offset = Oscl_Int64_Utils::get_uint64_lower32(bdo);
134                         bdo_present = true;
135                     }
136                     else
137                         base_data_offset = _movieFragmentBaseOffset;
138 
139                     trun_start = base_data_offset;
140                     if (trackDurationContainer != NULL)
141                     {
142                         for (int32 i = 0; i < trackDurationContainer->getNumTrackInfoVec(); i++)
143                         {
144                             TrackDurationInfo* trackInfo = trackDurationContainer->getTrackdurationInfoAt(i);
145                             if (trackInfo->trackId == trackId)
146                             {
147                                 _trackEndDuration = trackInfo->trackDuration;
148                                 _startTrackFragmentTSOffset = Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration);
149                             }
150                         }
151                     }
152                 }
153                 else
154                 {
155                     //duplicate atom
156                     count -= atomSize;
157                     atomSize -= DEFAULT_ATOM_SIZE;
158                     AtomUtils::seekFromCurrPos(fp, atomSize);
159                 }
160             }
161             else if (atomType == TRACK_FRAGMENT_RUN_ATOM)
162             {
163                 uint32 trunsParsed = countOfTrunsParsed;
164                 if (countOfTrunsParsed > COUNT_OF_TRUNS_PARSED_THRESHOLD)
165                 {
166                     countOfTrunsParsed = COUNT_OF_TRUNS_PARSED_THRESHOLD;
167                 }
168                 // here we want parser to parse complete TRUN atom.
169 
170                 PV_MP4_FF_NEW(fp->auditCB, TrackFragmentRunAtom, (fp, atomSize, atomType,
171                               base_data_offset,
172                               trun_start,
173                               trun_offset,
174                               _trackEndDuration,
175                               bdo_present,
176                               trunParsingCompleted,
177                               countOfTrunsParsed),
178                               _pTrackFragmentRunAtom);
179 
180                 countOfTrunsParsed = trunsParsed + 1;
181 
182                 if (!_pTrackFragmentRunAtom->MP4Success())
183                 {
184                     _success = false;
185                     _mp4ErrorCode = READ_TRACK_EXTENDS_ATOM_FAILED;
186                     return;
187                 }
188                 bdo_present = false;
189                 count -= _pTrackFragmentRunAtom->getSize();
190 
191                 size = count;
192                 uint32 trunFlags = _pTrackFragmentRunAtom->getFlags();
193                 if (!(trunFlags & 0x000100))
194                 {
195                     _use_default_duratoin = true;
196                     if (tf_flags & 0x000008)
197                     {
198                         _default_duration = _pTrackFragmentHeaderAtom->getDefaultSampleDuration();
199                         _pTrackFragmentRunAtom->setDefaultDuration(_default_duration);
200                     }
201                     else
202                     {
203                         for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
204                         {
205                             TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
206                             uint32 id = pTrackExtendAtom->getTrackId();
207                             if (id == trackId)
208                             {
209                                 uint32 trexDefaultDuration = pTrackExtendAtom->getDefaultSampleDuration();
210                                 _default_duration = trexDefaultDuration;
211                                 _pTrackFragmentRunAtom->setDefaultDuration(trexDefaultDuration);
212                             }
213                         }
214                     }
215                 }
216                 if (!(trunFlags & 0x000200))
217                 {
218                     if (tf_flags & 0x000010)
219                         _pTrackFragmentRunAtom->setDefaultSampleSize(_pTrackFragmentHeaderAtom->getDefaultSampleSize(), trun_offset);
220                     else
221                     {
222                         for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
223                         {
224                             TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
225                             uint32 id = pTrackExtendAtom->getTrackId();
226                             if (id == trackId)
227                             {
228                                 uint32 trexDefaultSampleSize = pTrackExtendAtom->getDefaultSampleSize();
229                                 _pTrackFragmentRunAtom->setDefaultSampleSize(trexDefaultSampleSize, trun_offset);
230                             }
231                         }
232                     }
233                 }
234                 _pTrackFragmentRunAtomVec->push_back(_pTrackFragmentRunAtom);
235                 _trackEndDuration = _pTrackFragmentRunAtom->_sampleTimeStamp;
236 
237                 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "****** tr_flag =0x%x ********", trunFlags));
238                 if (!parseTrafCompletely)
239                 {
240                     trafParsingCompleted = false;
241                     uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration);
242                     trackDurationContainer->updateTrackDurationForTrackId(trackId, duration);
243                     break;
244                 }
245             }
246             uint32 track_duration = Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration);
247             trackDurationContainer->updateTrackDurationForTrackId(trackId, track_duration);
248             trafParsingCompleted = true;
249         }
250     }
251     else
252     {
253         _mp4ErrorCode = READ_MOVIE_EXTENDS_ATOM_FAILED;
254     }
255 }
256 
ParseTrafAtom(MP4_FF_FILE * fp,uint32 & size,uint32 type,uint32 movieFragmentCurrentOffset,uint32 movieFragmentBaseOffset,uint32 moofSize,TrackDurationContainer * trackDurationContainer,Oscl_Vector<TrackExtendsAtom *,OsclMemAllocator> * trackExtendAtomVec,bool & trafParsingCompleted,uint32 & countOfTrunsParsed)257 void TrackFragmentAtom::ParseTrafAtom(MP4_FF_FILE *fp,
258                                       uint32 &size,
259                                       uint32 type,
260                                       uint32 movieFragmentCurrentOffset,
261                                       uint32 movieFragmentBaseOffset,
262                                       uint32 moofSize,
263                                       TrackDurationContainer *trackDurationContainer,
264                                       Oscl_Vector<TrackExtendsAtom*, OsclMemAllocator> *trackExtendAtomVec,
265                                       bool &trafParsingCompleted,
266                                       uint32 &countOfTrunsParsed)
267 {
268     OSCL_UNUSED_ARG(type);
269     OSCL_UNUSED_ARG(movieFragmentCurrentOffset);
270     OSCL_UNUSED_ARG(moofSize);
271     uint32 count = size;
272     uint32 trun_start = 0;
273     uint32 _movieFragmentBaseOffset = movieFragmentBaseOffset - DEFAULT_ATOM_SIZE;
274     bool bdo_present = false;
275     uint32 base_data_offset = _movieFragmentBaseOffset;
276 
277     if (tf_flags & 0x000001)
278     {
279         base_data_offset = Oscl_Int64_Utils::get_uint64_lower32(_pTrackFragmentHeaderAtom->getBaseDataOffset());
280         bdo_present = true;
281     }
282     else
283         base_data_offset = _movieFragmentBaseOffset;
284 
285     trun_start = base_data_offset;
286 
287     if (_success)
288     {
289         for (uint32 i = 0; i < 1; i++)
290         {
291             if (count > 0)
292             {
293                 if (trunParsingCompleted)
294                 {
295                     uint32 atomType = UNKNOWN_ATOM;
296                     uint32 atomSize = 0;
297                     AtomUtils::getNextAtomType(fp, atomSize, atomType);
298 
299                     if (atomType == TRACK_FRAGMENT_RUN_ATOM)
300                     {
301                         PV_MP4_FF_NEW(fp->auditCB, TrackFragmentRunAtom, (fp, atomSize, atomType,
302                                       base_data_offset,
303                                       trun_start,
304                                       trun_offset,
305                                       _trackEndDuration,
306                                       bdo_present,
307                                       trunParsingCompleted,
308                                       countOfTrunsParsed),
309                                       _pTrackFragmentRunAtom);
310 
311                         if (!_pTrackFragmentRunAtom->MP4Success())
312                         {
313                             _success = false;
314                             _mp4ErrorCode = READ_TRACK_EXTENDS_ATOM_FAILED;
315                             return;
316                         }
317                         _pTrackFragmentRunAtomVec->push_back(_pTrackFragmentRunAtom);
318                         if (trunParsingCompleted)
319                         {
320                             bdo_present = false;
321                             count -= _pTrackFragmentRunAtom->getSize();
322                             size = count;
323                             PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "count %d", count));
324                             uint32 trunFlags = _pTrackFragmentRunAtom->getFlags();
325                             if (!(trunFlags & 0x000100))
326                             {
327                                 _use_default_duratoin = true;
328                                 if (tf_flags & 0x000008)
329                                 {
330                                     _default_duration = _pTrackFragmentHeaderAtom->getDefaultSampleDuration();
331                                     _pTrackFragmentRunAtom->setDefaultDuration(_default_duration);
332                                 }
333                                 else
334                                 {
335                                     for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
336                                     {
337                                         TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
338                                         uint32 id = pTrackExtendAtom->getTrackId();
339                                         if (id == trackId)
340                                         {
341                                             uint32 trexDefaultDuration = pTrackExtendAtom->getDefaultSampleDuration();
342                                             _default_duration = trexDefaultDuration;
343                                             _pTrackFragmentRunAtom->setDefaultDuration(trexDefaultDuration);
344                                         }
345                                     }
346                                 }
347                             }
348                             if (!(trunFlags & 0x000200))
349                             {
350                                 if (tf_flags & 0x000010)
351                                     _pTrackFragmentRunAtom->setDefaultSampleSize(_pTrackFragmentHeaderAtom->getDefaultSampleSize(), trun_offset);
352                                 else
353                                 {
354                                     for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
355                                     {
356                                         TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
357                                         uint32 id = pTrackExtendAtom->getTrackId();
358                                         if (id == trackId)
359                                         {
360                                             uint32 trexDefaultSampleSize = pTrackExtendAtom->getDefaultSampleSize();
361                                             _pTrackFragmentRunAtom->setDefaultSampleSize(trexDefaultSampleSize, trun_offset);
362                                         }
363                                     }
364                                 }
365                             }
366                             _trackEndDuration = _pTrackFragmentRunAtom->_sampleTimeStamp;
367 
368                             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "****** tr_flag =0x%x ********", trunFlags));
369                         }
370                         trackDurationContainer->updateTrackDurationForTrackId(trackId,
371                                 Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration));
372                     }
373                     trafParsingCompleted = false;
374                 }
375                 else
376                 {
377                     _pTrackFragmentRunAtom->ParseTrunAtom(fp,
378                                                           trun_offset,
379                                                           trunParsingCompleted,
380                                                           countOfTrunsParsed);
381 
382                     if (!_pTrackFragmentRunAtom->MP4Success())
383                     {
384                         _success = false;
385                         _mp4ErrorCode = READ_TRACK_EXTENDS_ATOM_FAILED;
386                         return;
387                     }
388 
389                     if (trunParsingCompleted)
390                     {
391                         bdo_present = false;
392                         count -= _pTrackFragmentRunAtom->getSize();
393                         size = count;
394                         PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "count %d", count));
395                         uint32 trunFlags = _pTrackFragmentRunAtom->getFlags();
396                         if (!(trunFlags & 0x000100))
397                         {
398                             _use_default_duratoin = true;
399                             if (tf_flags & 0x000008)
400                             {
401                                 _default_duration = _pTrackFragmentHeaderAtom->getDefaultSampleDuration();
402                                 _pTrackFragmentRunAtom->setDefaultDuration(_default_duration);
403                             }
404                             else
405                             {
406                                 for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
407                                 {
408                                     TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
409                                     uint32 id = pTrackExtendAtom->getTrackId();
410                                     if (id == trackId)
411                                     {
412                                         uint32 trexDefaultDuration = pTrackExtendAtom->getDefaultSampleDuration();
413                                         _default_duration = trexDefaultDuration;
414                                         _pTrackFragmentRunAtom->setDefaultDuration(trexDefaultDuration);
415                                     }
416                                 }
417                             }
418                         }
419                         if (!(trunFlags & 0x000200))
420                         {
421                             if (tf_flags & 0x000010)
422                                 _pTrackFragmentRunAtom->setDefaultSampleSize(_pTrackFragmentHeaderAtom->getDefaultSampleSize(), trun_offset);
423                             else
424                             {
425                                 for (uint32 idx = 0; idx < trackExtendAtomVec->size(); idx++)
426                                 {
427                                     TrackExtendsAtom* pTrackExtendAtom = (*trackExtendAtomVec)[idx];
428                                     uint32 id = pTrackExtendAtom->getTrackId();
429                                     if (id == trackId)
430                                     {
431                                         uint32 trexDefaultSampleSize = pTrackExtendAtom->getDefaultSampleSize();
432                                         _pTrackFragmentRunAtom->setDefaultSampleSize(trexDefaultSampleSize, trun_offset);
433                                     }
434                                 }
435                             }
436                         }
437                         _trackEndDuration = _pTrackFragmentRunAtom->_sampleTimeStamp;
438 
439                         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "****** tr_flag =0x%x ********", trunFlags));
440                     }
441 
442                     trackDurationContainer->updateTrackDurationForTrackId(trackId,
443                             Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration));
444                     trafParsingCompleted = false;
445                 }
446             }
447             else if (count == 0)
448             {
449                 PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "TRAF END count %d", count));
450                 trafParsingCompleted = true;
451                 break;
452             }
453             else
454             {
455                 break;
456             }
457         }
458         if (count == 0)
459         {
460             PVMF_MP4FFPARSER_LOGPARSEDINFO((0, "TRAF END count %d", count));
461             trafParsingCompleted = true;
462         }
463     }
464     else
465     {
466         _mp4ErrorCode = READ_MOVIE_EXTENDS_ATOM_FAILED;
467     }
468 }
469 
~TrackFragmentAtom()470 TrackFragmentAtom::~TrackFragmentAtom()
471 {
472     if (_pTrackFragmentHeaderAtom != NULL)
473     {
474         PV_MP4_FF_DELETE(NULL, TrackFragmentHeaderAtom, _pTrackFragmentHeaderAtom);
475     }
476 
477     for (uint32 i = 0; i < _pTrackFragmentRunAtomVec->size(); i++)
478     {
479         PV_MP4_FF_DELETE(NULL, TrackFragmentRunAtom, (*_pTrackFragmentRunAtomVec)[i]);
480     }
481     PV_MP4_FF_TEMPLATED_DELETE(NULL, trackFragmentRunAtomVecType, Oscl_Vector, _pTrackFragmentRunAtomVec);
482 
483     if (_pinput != NULL)
484     {
485         oscl_free(_pinput);
486     }
487 }
488 
489 int32
getNextNSamples(uint32 startSampleNum,uint32 * n,uint32 totalSampleRead,GAU * pgau)490 TrackFragmentAtom::getNextNSamples(uint32 startSampleNum,
491                                    uint32 *n, uint32 totalSampleRead,
492                                    GAU    *pgau)
493 {
494     uint32  numSamplesInCurrentTrackFragmentRun = 0;
495     int32 currTSBase = 0;
496     uint32 samplesLeftInChunk = 0;
497     uint32 numSamples = 0;
498     _startTrackFragmentTSOffset = 0;
499 
500     uint32 samplesYetToBeRead = *n;
501     uint32 samplesReadBefore;
502     samplesReadBefore = *n;
503     uint32 sampleNum = startSampleNum;
504     uint32 sampleFileOffset = 0;
505 
506     int32 sampleBeforeGet = (int32)startSampleNum;
507 
508     uint32 s = 0;
509     uint32 end = 0;
510 
511     uint32 i = 0, k = 0;
512 
513     int32  _mp4ErrorCode = EVERYTHING_FINE;
514 
515     currTSBase = _currentPlaybackSampleTimestamp;
516     end = pgau->buf.num_fragments;
517 
518     uint32 start = 0;
519     uint32 gauIdx = 0;
520     uint32 frgptr = 0;
521     samplesReadBefore = totalSampleRead;
522     uint32 totalnumSamples = 0;
523 
524     totalnumSamples = getTotalNumSampleInTraf();
525     if (sampleNum >= totalnumSamples)
526     {
527         _currentTrackFragmentRunSampleNumber = 0;
528         *n = 0;
529         _mp4ErrorCode = END_OF_TRACK;
530         return (_mp4ErrorCode);
531     }
532 
533     PV_MP4_FF_NEW(fp->auditCB, fragmentptrOffsetVecType, (), _pFragmentptrOffsetVec);
534     for (i = 0; i < samplesReadBefore; i++)
535     {
536         frgptr +=  pgau->info[i].len;
537         if (pgau->info[i].len != 0)
538         {
539             gauIdx++;
540         }
541     }
542     s = samplesReadBefore;
543     for (k = start; k < end; k++)
544     {
545         _pFragmentptrOffsetVec->push_back(frgptr);
546     }
547 
548     GAU tempGau;
549     tempGau = *pgau;
550     GAU* tempgauPtr = &tempGau;
551 
552     k = 0;
553 
554     while (samplesYetToBeRead)
555     {
556         TrackFragmentRunAtom *tfRun;
557         uint32 sampleCount;
558         if (_mp4ErrorCode == END_OF_TRACK)
559         {
560             break;
561         }
562         tfRun = getTrackFragmentRunForSampleNum(_currentTrackFragmentRunSampleNumber, sampleCount);
563         if (tfRun != NULL)
564         {
565             numSamplesInCurrentTrackFragmentRun = tfRun->getSampleCount();
566         }
567         else
568         {
569             *n = 0;
570             _mp4ErrorCode = END_OF_TRACK;
571             PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
572                                        Oscl_Vector, _pFragmentptrOffsetVec);
573             return (_mp4ErrorCode);
574         }
575 
576         int32 tfrunoffset = 0;
577         tfrunoffset = Oscl_Int64_Utils::get_uint64_lower32(tfRun->getDataOffset());
578         int32 sampleSizeOffset = 0;
579 
580         uint32 sigmaSampleSize = 0, k = 0;
581         uint32 debugOffset = _prevSampleOffset + sampleSizeOffset;
582 
583         samplesLeftInChunk = ((sampleCount - _currentTrackFragmentRunSampleNumber));
584 
585         if (samplesLeftInChunk  >=  samplesYetToBeRead)
586         {
587             numSamples = samplesYetToBeRead;
588             samplesYetToBeRead = 0;
589         }
590         else
591         {
592             samplesYetToBeRead -= samplesLeftInChunk;
593             numSamples = samplesLeftInChunk;
594         }
595 
596         uint32 StartReadingFromSampleNum = numSamplesInCurrentTrackFragmentRun - samplesLeftInChunk;
597         uint32 sampleLeft = (numSamples + StartReadingFromSampleNum);
598 
599         uint32 baseSampleNum  = StartReadingFromSampleNum;
600         while (StartReadingFromSampleNum < sampleLeft)
601         {
602             if (StartReadingFromSampleNum >= numSamplesInCurrentTrackFragmentRun)
603             {
604                 if (sampleCount == totalnumSamples)
605                 {
606                     samplesYetToBeRead = sampleLeft - StartReadingFromSampleNum;
607                     _mp4ErrorCode = END_OF_TRACK;
608                     break;
609                 }
610                 tfRun = getTrackFragmentRunForSampleNum(StartReadingFromSampleNum, sampleCount);
611                 if (tfRun != NULL)
612                 {
613                     numSamplesInCurrentTrackFragmentRun = tfRun->getSampleCount();
614                 }
615                 else
616                 {
617                     *n = 0;
618                     _mp4ErrorCode = END_OF_TRACK;
619                     PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
620                                                Oscl_Vector, _pFragmentptrOffsetVec);
621                     return (_mp4ErrorCode);
622                 }
623 
624                 sampleLeft = sampleLeft - StartReadingFromSampleNum;
625                 StartReadingFromSampleNum = 0;
626                 baseSampleNum = 0;
627             }
628             k = StartReadingFromSampleNum;
629 
630             int32 tsDelta = 0;
631             int32 tempSize = 0;
632             Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* _tfRunSampleInfo = tfRun->getSampleTable();
633             if (_tfRunSampleInfo != NULL)
634             {
635 
636 
637                 currTSBase =  Oscl_Int64_Utils::get_uint64_lower32((*_tfRunSampleInfo)[k]->_sample_timestamp);
638                 tempSize = (*_tfRunSampleInfo)[k]->_sample_size;
639                 tsDelta = (*_tfRunSampleInfo)[k]->_sample_duration;
640 
641             }
642             if (_tfRunSampleInfo == NULL || tempSize == -1)  // doesnt seem like one can continue if no _tfRunSampleInfo
643             {
644                 *n = 0;
645                 _mp4ErrorCode =  INVALID_SAMPLE_SIZE;
646                 PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
647                                            Oscl_Vector, _pFragmentptrOffsetVec);
648 
649                 return (_mp4ErrorCode);
650             }
651             sigmaSampleSize += tempSize;
652             pgau->info[s].len = tempSize;
653             sampleFileOffset = (*_tfRunSampleInfo)[baseSampleNum]->_sample_offset;
654             pgau->info[s].ts_delta = tsDelta;
655             pgau->info[s].ts = currTSBase;
656             currTSBase += tsDelta;
657             debugOffset = sampleFileOffset;
658 
659             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::getNextNSamples- Track Fragment Run Offset[%d] =%d", s, tfrunoffset));
660             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::getNextNSamples- pgau->info[%d].len =%d", s, pgau->info[s].len));
661             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::getNextNSamples- pgau->info[%d].ts_delta =%d", s, pgau->info[s].ts_delta));
662             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::getNextNSamples- pgau->info[%d].ts =%d", s, pgau->info[s].ts));
663             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::getNextNSamples- Offset =%d", debugOffset));
664 
665             s++;
666             StartReadingFromSampleNum++;
667         }
668 
669 
670 
671         Oscl_Int64_Utils::set_uint64(pgau->SampleOffset, 0, (uint32)sampleFileOffset);
672 
673         AtomUtils::getCurrentFileSize(_pinput, _fileSize);
674         if ((sampleFileOffset + sigmaSampleSize) > _fileSize)
675         {
676             _mp4ErrorCode = INSUFFICIENT_DATA;
677             _currentTrackFragmentRunSampleNumber = startSampleNum;
678             *n = 0;
679             for (uint32 i = 0; i < pgau->numMediaSamples; i++)
680             {
681                 pgau->info[i].len         = 0;
682                 pgau->info[i].ts          = 0;
683                 pgau->info[i].sample_info = 0;
684             }
685             PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
686                                        Oscl_Vector, _pFragmentptrOffsetVec);
687 
688             return (_mp4ErrorCode);
689         }
690 
691         if (sampleFileOffset != 0)
692             AtomUtils::seekFromStart(_pinput, sampleFileOffset);
693 
694         for (k = start; k < end; k++)
695         {
696             uint8* read_fragment_ptr = NULL;
697             read_fragment_ptr = (uint8 *)(tempgauPtr->buf.fragments[k].ptr);
698             read_fragment_ptr += (*_pFragmentptrOffsetVec)[k];
699             (*_pFragmentptrOffsetVec)[k] = 0;
700             uint32 tmpSize =
701                 (tempgauPtr->buf.fragments[k].len > sigmaSampleSize) ? sigmaSampleSize : tempgauPtr->buf.fragments[k].len;
702             if (tmpSize)
703             {
704                 if (!AtomUtils::readByteData(_pinput, tmpSize,
705                                              (uint8 *)(read_fragment_ptr)))
706                 {
707                     *n = 0;
708 
709                     _mp4ErrorCode =  READ_FAILED;
710                     PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
711                                                Oscl_Vector, _pFragmentptrOffsetVec);
712 
713 
714                     return (_mp4ErrorCode);
715                 }
716                 tempgauPtr->buf.fragments[k].len -= tmpSize;
717                 read_fragment_ptr += tmpSize;
718                 tempgauPtr->buf.fragments[k].ptr = read_fragment_ptr;
719 
720                 sigmaSampleSize -= tmpSize;
721 
722             }
723 
724             if (sigmaSampleSize == 0)
725             {
726                 break;
727             }
728         }
729 
730         if (sigmaSampleSize > 0)
731         {
732             _currentTrackFragmentRunSampleNumber = startSampleNum;
733             _currentPlaybackSampleTimestamp = _startTrackFragmentTSOffset;
734             _mp4ErrorCode =  INSUFFICIENT_BUFFER_SIZE;
735             break;
736         }
737         sampleNum = sampleNum + numSamples;
738 
739         if (_currentTrackFragmentRunSampleNumber == (uint32)sampleBeforeGet)
740         {
741             _currentTrackFragmentRunSampleNumber += numSamples;
742             sampleBeforeGet += numSamples;
743         }
744         else
745         {
746             break;
747         }
748 
749         if (_currentTrackFragmentRunSampleNumber == totalnumSamples)
750         {
751             break;
752         }
753 
754         if (_currentTrackFragmentRunSampleNumber > totalnumSamples)
755         {
756             _mp4ErrorCode = END_OF_TRACK;
757             break;
758         }
759     }
760 
761     if (_currentTrackFragmentRunSampleNumber == (uint32)sampleBeforeGet)
762     {
763         _currentPlaybackSampleTimestamp = currTSBase;
764         *n = (*n - samplesYetToBeRead);
765     }
766     else
767     {
768         _currentPlaybackSampleTimestamp = _startTrackFragmentTSOffset;
769         *n = 0;
770         _mp4ErrorCode = READ_FAILED;
771     }
772 
773 
774     PV_MP4_FF_TEMPLATED_DELETE(NULL, fragmentptrOffsetVecType,
775                                Oscl_Vector, _pFragmentptrOffsetVec);
776 
777     return (_mp4ErrorCode);
778 
779 }
780 
781 TrackFragmentRunAtom *
getTrackFragmentRunForSampleNum(uint32 samplenum,uint32 & sampleCount)782 TrackFragmentAtom::getTrackFragmentRunForSampleNum(uint32 samplenum, uint32 &sampleCount)
783 {
784     if (_pTrackFragmentRunAtomVec != NULL)
785     {
786         uint32 samplecount = 0;
787         uint32 numTrackFragment =  _pTrackFragmentRunAtomVec->size();
788         for (uint32 idx = 0; idx < numTrackFragment; idx++)
789         {
790             samplecount += (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
791             if (samplenum < samplecount)
792             {
793                 sampleCount = samplecount;
794                 return (*_pTrackFragmentRunAtomVec)[idx];
795             }
796         }
797 
798     }
799     return NULL;
800 }
801 uint32
getSampleNumberFromTimestamp(uint32 time)802 TrackFragmentAtom::getSampleNumberFromTimestamp(uint32 time)
803 {
804     if (_pTrackFragmentRunAtomVec != NULL)
805     {
806         uint32 samplecount = 0;
807         uint32 samplenum = 0;
808         uint32 numTrackFragment =  _pTrackFragmentRunAtomVec->size();
809 
810         for (uint32 idx = 0; idx < numTrackFragment; idx++)
811         {
812             TrackFragmentRunAtom *tfrun = (*_pTrackFragmentRunAtomVec)[idx];
813             Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* trackFragmentRunSampleInfo = tfrun->getSampleTable();
814             samplecount = (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
815             for (uint32 idy = 0; idy < samplecount; idy++)
816             {
817                 if (time >= (uint32)(*trackFragmentRunSampleInfo)[idy]->_sample_timestamp)
818                 {
819                     return samplenum;
820                 }
821                 samplenum++;
822             }
823         }
824 
825     }
826     return 0;
827 }
828 
829 uint32
getTimestampForSampleNumber(uint32 sampleNumber)830 TrackFragmentAtom::getTimestampForSampleNumber(uint32 sampleNumber)
831 {
832     if (_pTrackFragmentRunAtomVec != NULL)
833     {
834         uint32 samplecount = 0;
835         uint32 numTrackFragment =  _pTrackFragmentRunAtomVec->size();
836 
837         for (uint32 idx = 0; idx < numTrackFragment; idx++)
838         {
839             TrackFragmentRunAtom *tfrun = (*_pTrackFragmentRunAtomVec)[idx];
840             Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* trackFragmentRunSampleInfo = tfrun->getSampleTable();
841             samplecount = (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
842             for (uint32 idy = 0; idy < samplecount; idy++)
843             {
844                 if (sampleNumber == idy + 1)
845                 {
846                     return Oscl_Int64_Utils::get_uint64_lower32(
847                                (*trackFragmentRunSampleInfo)[idy]->_sample_timestamp);
848                 }
849             }
850         }
851 
852     }
853     return 0;
854 }
855 
856 int32
getNextBundledAccessUnits(uint32 * n,uint32 totalSampleRead,GAU * pgau)857 TrackFragmentAtom::getNextBundledAccessUnits(uint32 *n, uint32 totalSampleRead,
858         GAU    *pgau)
859 {
860     int32 nReturn = -1;
861 
862     if (_currentTrackFragmentRunSampleNumber == 0)
863     {
864         _currentPlaybackSampleTimestamp =  _startTrackFragmentTSOffset;
865     }
866     nReturn = getNextNSamples(_currentTrackFragmentRunSampleNumber, n, totalSampleRead, pgau);
867     return nReturn;
868 }
869 
getBaseDataOffset()870 uint64 TrackFragmentAtom::getBaseDataOffset()
871 {
872     if (_pTrackFragmentHeaderAtom != NULL)
873     {
874         return _pTrackFragmentHeaderAtom->getBaseDataOffset();;
875     }
876     return 0;
877 }
878 
getSampleCount()879 uint32 TrackFragmentAtom::getSampleCount()
880 {
881     return 0;
882 }
getSampleTable()883 Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* TrackFragmentAtom::getSampleTable()
884 {
885     return NULL;
886 }
887 
getSampleDescriptionIndex()888 uint32 TrackFragmentAtom::getSampleDescriptionIndex()
889 {
890     if (_pTrackFragmentHeaderAtom != NULL)
891     {
892         return _pTrackFragmentHeaderAtom->getSampleDescriptionIndex();
893     }
894     return 0;
895 }
getDefaultSampleDuration()896 uint32 TrackFragmentAtom::getDefaultSampleDuration()
897 {
898     if (_pTrackFragmentHeaderAtom != NULL)
899     {
900         return _pTrackFragmentHeaderAtom->getDefaultSampleDuration();
901     }
902     return 0;
903 }
getDefaultSampleSize()904 uint32 TrackFragmentAtom::getDefaultSampleSize()
905 {
906     if (_pTrackFragmentHeaderAtom != NULL)
907     {
908         return _pTrackFragmentHeaderAtom->getDefaultSampleSize();
909     }
910     return 0;
911 }
getDefaultSampleFlags()912 uint32 TrackFragmentAtom::getDefaultSampleFlags()
913 {
914     if (_pTrackFragmentHeaderAtom != NULL)
915     {
916         return _pTrackFragmentHeaderAtom->getDefaultSampleFlag();
917     }
918     return 0;
919 }
920 
getTotalNumSampleInTraf()921 uint32 TrackFragmentAtom::getTotalNumSampleInTraf()
922 {
923     uint32 totalSampleNum = 0;
924     if (_pTrackFragmentRunAtomVec != NULL)
925     {
926         uint32 numTrackFragment =  _pTrackFragmentRunAtomVec->size();
927         for (uint32 idx = 0; idx < numTrackFragment; idx++)
928         {
929             uint32 samplecount = (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
930             totalSampleNum += samplecount;
931         }
932     }
933     return totalSampleNum;
934 }
935 
936 
937 int32
peekNextNSamples(uint32 startSampleNum,uint32 * n,uint32 totalSampleRead,MediaMetaInfo * mInfo)938 TrackFragmentAtom::peekNextNSamples(uint32 startSampleNum,
939                                     uint32 *n, uint32 totalSampleRead,
940                                     MediaMetaInfo *mInfo)
941 {
942     uint32  numSamplesInCurrentTrackFragmentRun = 0;
943     int32 currTSBase = 0;
944     uint32 samplesLeftInChunk = 0;
945     uint32 numSamples = 0;
946     _startTrackFragmentTSOffset = 0;
947 
948     uint32 samplesToBePeek = *n;
949     uint32 sampleNum = startSampleNum;
950     int32 sampleFileOffset = 0;
951     int32 sampleBeforeGet = (int32)startSampleNum;
952     uint32 s = totalSampleRead;
953 
954     int32  _mp4ErrorCode = EVERYTHING_FINE;
955     currTSBase = _currentPlaybackSampleTimestamp;
956 
957     uint32 totalnumSamples = 0;
958     totalnumSamples = getTotalNumSampleInTraf();
959 
960     if (sampleNum >= totalnumSamples)
961     {
962         _peekPlaybackSampleNumber = 0;
963         *n = 0;
964         _mp4ErrorCode = END_OF_TRACK;
965         return (_mp4ErrorCode);
966     }
967 
968     while (samplesToBePeek)
969     {
970         TrackFragmentRunAtom *tfRun;
971         uint32 sampleCount;
972         if (_mp4ErrorCode == END_OF_TRACK)
973         {
974             break;
975         }
976         tfRun = getTrackFragmentRunForSampleNum(_peekPlaybackSampleNumber, sampleCount);
977         if (tfRun != NULL)
978         {
979             numSamplesInCurrentTrackFragmentRun = tfRun->getSampleCount();
980         }
981         else
982         {
983             *n = 0;
984             _mp4ErrorCode = END_OF_TRACK;
985             return (_mp4ErrorCode);
986         }
987 
988         int32 tfrunoffset = 0;
989         tfrunoffset = Oscl_Int64_Utils::get_uint64_lower32(tfRun->getDataOffset());
990         int32 sampleSizeOffset = 0;
991 
992         uint32 sigmaSampleSize = 0, k = 0;
993         uint32 debugOffset = _prevSampleOffset + sampleSizeOffset;
994 
995         samplesLeftInChunk = ((sampleCount - _peekPlaybackSampleNumber));
996 
997         if (samplesLeftInChunk  >=  samplesToBePeek)
998         {
999             numSamples = samplesToBePeek;
1000             samplesToBePeek = 0;
1001         }
1002         else
1003         {
1004             samplesToBePeek -= samplesLeftInChunk;
1005             numSamples = samplesLeftInChunk;
1006         }
1007 
1008         uint32 StartPeekFromSampleNum = numSamplesInCurrentTrackFragmentRun - samplesLeftInChunk;
1009         uint32 sampleLeft = (numSamples + StartPeekFromSampleNum);
1010 
1011         uint32 baseSampleNum  = StartPeekFromSampleNum;
1012         while (StartPeekFromSampleNum < sampleLeft)
1013         {
1014             if (StartPeekFromSampleNum >= numSamplesInCurrentTrackFragmentRun)
1015             {
1016                 if (sampleCount == totalnumSamples)
1017                 {
1018                     samplesToBePeek = sampleLeft - StartPeekFromSampleNum;
1019                     _mp4ErrorCode = END_OF_TRACK;
1020                     break;
1021                 }
1022                 tfRun = getTrackFragmentRunForSampleNum(StartPeekFromSampleNum, sampleCount);
1023                 if (tfRun != NULL)
1024                 {
1025                     numSamplesInCurrentTrackFragmentRun = tfRun->getSampleCount();
1026                 }
1027                 else
1028                 {
1029                     *n = 0;
1030                     _mp4ErrorCode = END_OF_TRACK;
1031                     return (_mp4ErrorCode);
1032                 }
1033 
1034                 sampleLeft = sampleLeft - StartPeekFromSampleNum;
1035                 StartPeekFromSampleNum = 0;
1036                 baseSampleNum = 0;
1037             }
1038             k = StartPeekFromSampleNum;
1039 
1040             int32 tsDelta = 0;
1041             int32 tempSize = 0;
1042             Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* _tfRunSampleInfo = tfRun->getSampleTable();
1043             if (_tfRunSampleInfo != NULL)
1044             {
1045                 currTSBase =  Oscl_Int64_Utils::get_uint64_lower32((*_tfRunSampleInfo)[k]->_sample_timestamp);
1046                 tempSize = (*_tfRunSampleInfo)[k]->_sample_size;
1047                 tsDelta = (*_tfRunSampleInfo)[k]->_sample_duration;
1048             }
1049             if (tempSize == 0)
1050                 tempSize = getDefaultSampleSize();
1051 
1052             if (tsDelta == 0)
1053                 tsDelta = getDefaultSampleDuration();
1054 
1055             if (_tfRunSampleInfo == NULL || tempSize == -1)  // doesn't seem like one can continue if no _tfRunSampleInfo
1056             {
1057                 *n = 0;
1058                 _mp4ErrorCode =  INVALID_SAMPLE_SIZE;
1059                 return (_mp4ErrorCode);
1060             }
1061             sigmaSampleSize += tempSize;
1062             mInfo[s].len = tempSize;
1063             sampleFileOffset = (*_tfRunSampleInfo)[baseSampleNum]->_sample_offset;
1064             mInfo[s].ts_delta = tsDelta;
1065             mInfo[s].ts = currTSBase;
1066             currTSBase += tsDelta;
1067             debugOffset = sampleFileOffset;
1068 
1069             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::peekNextNSamples- Track Fragment Run Offset[%d] =%d", s, tfrunoffset));
1070             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::peekNextNSamples- pgau->info[%d].len =%d", s, mInfo[s].len));
1071             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::peekNextNSamples- pgau->info[%d].ts_delta =%d", s, mInfo[s].ts_delta));
1072             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::peekNextNSamples- pgau->info[%d].ts =%d", s, mInfo[s].ts));
1073             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::peekNextNSamples- Offset =%d", debugOffset));
1074 
1075             s++;
1076             StartPeekFromSampleNum++;
1077         }
1078 
1079         if (_peekPlaybackSampleNumber == (uint32)sampleBeforeGet)
1080         {
1081             _peekPlaybackSampleNumber += numSamples;
1082             sampleBeforeGet += numSamples;
1083         }
1084         else
1085         {
1086             break;
1087         }
1088 
1089         if (_peekPlaybackSampleNumber == totalnumSamples)
1090         {
1091             break;
1092         }
1093 
1094         if (_peekPlaybackSampleNumber > totalnumSamples)
1095         {
1096             _mp4ErrorCode = END_OF_TRACK;
1097             break;
1098         }
1099     }
1100 
1101     if (_peekPlaybackSampleNumber == (uint32) sampleBeforeGet)
1102     {
1103         *n = (*n - samplesToBePeek);
1104     }
1105     else
1106     {
1107         *n = 0;
1108         _mp4ErrorCode = READ_FAILED;
1109     }
1110 
1111     return (_mp4ErrorCode);
1112 
1113 }
1114 
1115 int32
peekNextBundledAccessUnits(uint32 * n,uint32 totalSampleRead,MediaMetaInfo * mInfo)1116 TrackFragmentAtom::peekNextBundledAccessUnits(uint32 *n, uint32 totalSampleRead,
1117         MediaMetaInfo *mInfo)
1118 {
1119     int32 nReturn = -1;
1120     nReturn = peekNextNSamples(_peekPlaybackSampleNumber, n, totalSampleRead , mInfo);
1121     return nReturn;
1122 }
1123 
1124 
resetPlayback(uint32 time,uint32 trun_number,uint32 sample_num)1125 int32 TrackFragmentAtom::resetPlayback(uint32 time, uint32 trun_number, uint32 sample_num)
1126 {
1127     int32 Return = -1;
1128     uint32 samplesInPrevTrun = 0;
1129 
1130     for (uint32 idx = 0; idx < trun_number - 1; idx++)
1131     {
1132         samplesInPrevTrun += (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
1133     }
1134     TrackFragmentRunAtom *trackFragmentRunAtom = (*_pTrackFragmentRunAtomVec)[trun_number-1];
1135     if (trackFragmentRunAtom != NULL)
1136     {
1137         trackFragmentRunAtom->setSampleDurationAndTimeStampFromSampleNum(sample_num - 1, time, _default_duration);
1138         Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* _tfRunSampleInfo = trackFragmentRunAtom->getSampleTable();
1139         if (_tfRunSampleInfo != NULL)
1140         {
1141             uint32 TimeStamp = Oscl_Int64_Utils::get_uint64_lower32(
1142                                    (*_tfRunSampleInfo)[sample_num-1]->_sample_timestamp);
1143             if (time >= TimeStamp)
1144             {
1145                 _currentTrackFragmentRunSampleNumber = samplesInPrevTrun + (sample_num - 1);
1146                 _currentPlaybackSampleTimestamp = time;
1147                 _peekPlaybackSampleNumber = samplesInPrevTrun + (sample_num - 1);
1148                 Return = time;
1149             }
1150         }
1151         _trackEndDuration = trackFragmentRunAtom->_sampleTimeStamp;
1152         for (uint32 idx = trun_number; idx < _pTrackFragmentRunAtomVec->size(); idx++)
1153         {
1154             trackFragmentRunAtom = (*_pTrackFragmentRunAtomVec)[idx];
1155             trackFragmentRunAtom->setSampleDurationAndTimeStampFromSampleNum(0,
1156                     Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration),
1157                     _default_duration);
1158             _trackEndDuration = trackFragmentRunAtom->_sampleTimeStamp;
1159         }
1160 
1161         _pTrackDurationContainer->updateTrackDurationForTrackId(trackId,
1162                 Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration));
1163     }
1164     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::Return TS =%d", Return));
1165 
1166     return Return;
1167 
1168 }
1169 
resetPlayback(uint32 time)1170 int32 TrackFragmentAtom::resetPlayback(uint32 time)
1171 {
1172     int32 Return = -1;
1173     if (_pTrackFragmentRunAtomVec != NULL)
1174     {
1175         uint32 samplecount = 0;
1176         uint32 numTrackFragmentRun =  _pTrackFragmentRunAtomVec->size();
1177 
1178         for (uint32 idx = 0; idx < numTrackFragmentRun; idx++)
1179         {
1180             TrackFragmentRunAtom *tfrun = (*_pTrackFragmentRunAtomVec)[idx];
1181             tfrun->setSampleDurationAndTimeStampFromSampleNum(0, time, _default_duration);
1182 
1183             Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* trackFragmentRunSampleInfo = tfrun->getSampleTable();
1184             samplecount = (*_pTrackFragmentRunAtomVec)[idx]->getSampleCount();
1185             for (uint32 idy = 0; idy < samplecount; idy++)
1186             {
1187                 uint32 TimeStamp = Oscl_Int64_Utils::get_uint64_lower32((*trackFragmentRunSampleInfo)[idy]->_sample_timestamp);
1188                 if (time >= TimeStamp)
1189                 {
1190                     _currentTrackFragmentRunSampleNumber = idy;
1191                     _currentPlaybackSampleTimestamp = time;
1192                     _peekPlaybackSampleNumber = idy;
1193                     Return = time;
1194                     break;
1195                 }
1196 
1197             }
1198             _trackEndDuration = tfrun->_sampleTimeStamp;
1199             for (uint32 idx = 1; idx < _pTrackFragmentRunAtomVec->size(); idx++)
1200             {
1201                 tfrun = (*_pTrackFragmentRunAtomVec)[idx];
1202                 tfrun->setSampleDurationAndTimeStampFromSampleNum(0,
1203                         Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration),
1204                         _default_duration);
1205                 _trackEndDuration = tfrun->_sampleTimeStamp;
1206             }
1207             _pTrackDurationContainer->updateTrackDurationForTrackId(trackId,
1208                     Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration));
1209 
1210             if (Return != -1)
1211             {
1212                 break;
1213             }
1214         }
1215     }
1216     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "TrackFragmentAtom::Return TS =%d", Return));
1217     return Return;
1218 }
resetPlayback()1219 void TrackFragmentAtom::resetPlayback()
1220 {
1221     _currentTrackFragmentRunSampleNumber = 0;
1222     _peekPlaybackSampleNumber = 0;
1223     _startTrackFragmentTSOffset = 0;
1224     _currentPlaybackSampleTimestamp = _startTrackFragmentTSOffset;
1225 }
1226 
getCurrentTrafDuration()1227 uint32 TrackFragmentAtom::getCurrentTrafDuration()
1228 {
1229     return Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration);
1230 }
1231 
1232 int32
getOffsetByTime(uint32 id,uint32 ts,int32 * sampleFileOffset)1233 TrackFragmentAtom::getOffsetByTime(uint32 id, uint32 ts, int32* sampleFileOffset)
1234 {
1235     OSCL_UNUSED_ARG(id);
1236     uint32 time = ts;
1237     uint32 prevTime = 0, prevOffset = 0;
1238     if (_pTrackFragmentRunAtomVec != NULL)
1239     {
1240         for (uint32 idx = 0; idx < _pTrackFragmentRunAtomVec->size(); idx++)
1241         {
1242             TrackFragmentRunAtom *trackFragmentRunAtom = (*_pTrackFragmentRunAtomVec)[idx];
1243             if (trackFragmentRunAtom != NULL)
1244             {
1245                 Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* _tfRunSampleInfo = trackFragmentRunAtom->getSampleTable();
1246                 if (_tfRunSampleInfo != NULL)
1247                 {
1248 
1249                     for (uint32 i = 0; i < _tfRunSampleInfo->size(); i++)
1250                     {
1251                         if (time < Oscl_Int64_Utils::get_uint64_lower32((*_tfRunSampleInfo)[i]->_sample_timestamp))
1252                         {
1253                             uint32 tmp = Oscl_Int64_Utils::get_uint64_lower32((*_tfRunSampleInfo)[i]->_sample_timestamp);
1254                             uint32 diffwithbeforeTS = time - prevTime;
1255                             uint32 diffwithafterTS = tmp - time;
1256                             if (diffwithbeforeTS > diffwithafterTS)
1257                             {
1258                                 *sampleFileOffset = (*_tfRunSampleInfo)[i]->_sample_offset;;
1259                                 return EVERYTHING_FINE;
1260                             }
1261                             else
1262                             {
1263                                 *sampleFileOffset = prevOffset;
1264                                 return EVERYTHING_FINE;
1265                             }
1266                         }
1267                         prevTime = Oscl_Int64_Utils::get_uint64_lower32((*_tfRunSampleInfo)[i]->_sample_timestamp);
1268                         prevOffset = (*_tfRunSampleInfo)[i]->_sample_offset;
1269                     }
1270                 }
1271 
1272             }
1273         }
1274     }
1275     return EVERYTHING_FINE;
1276 }
1277 
1278 
updateTrackDurationForTrackId(int32 id,uint32 duration)1279 void TrackDurationContainer::updateTrackDurationForTrackId(int32 id, uint32 duration)
1280 {
1281     if (_pTrackdurationInfoVec != NULL)
1282     {
1283         for (uint32 i = 0; i < _pTrackdurationInfoVec->size(); i++)
1284         {
1285             if ((int32)((*_pTrackdurationInfoVec)[i]->trackId) == id)
1286             {
1287                 (*_pTrackdurationInfoVec)[i]->trackDuration = duration;
1288             }
1289         }
1290     }
1291 }
1292