Home | History | Annotate | Download | only in src
      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
     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 
    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 
    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
    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 *
    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
    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
    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
    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 
    870 uint64 TrackFragmentAtom::getBaseDataOffset()
    871 {
    872     if (_pTrackFragmentHeaderAtom != NULL)
    873     {
    874         return _pTrackFragmentHeaderAtom->getBaseDataOffset();;
    875     }
    876     return 0;
    877 }
    878 
    879 uint32 TrackFragmentAtom::getSampleCount()
    880 {
    881     return 0;
    882 }
    883 Oscl_Vector<TFrunSampleTable*, OsclMemAllocator>* TrackFragmentAtom::getSampleTable()
    884 {
    885     return NULL;
    886 }
    887 
    888 uint32 TrackFragmentAtom::getSampleDescriptionIndex()
    889 {
    890     if (_pTrackFragmentHeaderAtom != NULL)
    891     {
    892         return _pTrackFragmentHeaderAtom->getSampleDescriptionIndex();
    893     }
    894     return 0;
    895 }
    896 uint32 TrackFragmentAtom::getDefaultSampleDuration()
    897 {
    898     if (_pTrackFragmentHeaderAtom != NULL)
    899     {
    900         return _pTrackFragmentHeaderAtom->getDefaultSampleDuration();
    901     }
    902     return 0;
    903 }
    904 uint32 TrackFragmentAtom::getDefaultSampleSize()
    905 {
    906     if (_pTrackFragmentHeaderAtom != NULL)
    907     {
    908         return _pTrackFragmentHeaderAtom->getDefaultSampleSize();
    909     }
    910     return 0;
    911 }
    912 uint32 TrackFragmentAtom::getDefaultSampleFlags()
    913 {
    914     if (_pTrackFragmentHeaderAtom != NULL)
    915     {
    916         return _pTrackFragmentHeaderAtom->getDefaultSampleFlag();
    917     }
    918     return 0;
    919 }
    920 
    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
    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
   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 
   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 
   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 }
   1219 void TrackFragmentAtom::resetPlayback()
   1220 {
   1221     _currentTrackFragmentRunSampleNumber = 0;
   1222     _peekPlaybackSampleNumber = 0;
   1223     _startTrackFragmentTSOffset = 0;
   1224     _currentPlaybackSampleTimestamp = _startTrackFragmentTSOffset;
   1225 }
   1226 
   1227 uint32 TrackFragmentAtom::getCurrentTrafDuration()
   1228 {
   1229     return Oscl_Int64_Utils::get_uint64_lower32(_trackEndDuration);
   1230 }
   1231 
   1232 int32
   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 
   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