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 /*     -------------------------------------------------------------------       */
     21 /*                            MPEG-4 Mpeg4File Class                             */
     22 /*     -------------------------------------------------------------------       */
     23 /*********************************************************************************/
     24 /*
     25     The Mpeg4File Class is the class that will construct and maintain all the
     26     mecessary data structures to be able to render a valid MP4 file to disk.
     27     Format.
     28 */
     29 
     30 
     31 #define IMPLEMENT_Mpeg4File
     32 
     33 #include "oscl_int64_utils.h"
     34 
     35 #ifndef MPEG4FILE_H_INCLUDED
     36 #include "mpeg4file.h"
     37 #endif
     38 
     39 #include "atomdefs.h"
     40 #include "atomutils.h"
     41 #include "filetypeatom.h"
     42 #include "oscl_utf8conv.h"
     43 #include "oscl_string.h"
     44 #include "oscl_snprintf.h"
     45 #include "amrdecoderspecificinfo.h"
     46 #include "h263decoderspecificinfo.h"
     47 #include "media_clock_converter.h"
     48 
     49 typedef Oscl_Vector<TrackAtom*, OsclMemAllocator> trackAtomVecType;
     50 typedef Oscl_Vector<MovieFragmentAtom*, OsclMemAllocator> movieFragmentAtomVecType;
     51 typedef Oscl_Vector<uint32, OsclMemAllocator> movieFragmentOffsetVecType;
     52 typedef Oscl_Vector<TrackDurationInfo*, OsclMemAllocator> trackDurationInfoVecType;
     53 typedef Oscl_Vector<MovieFragmentRandomAccessAtom*, OsclMemAllocator> movieFragmentRandomAccessAtomVecType;
     54 
     55 // Stream-in Constructor
     56 Mpeg4File::Mpeg4File(MP4_FF_FILE *fp,
     57                      OSCL_wString& filename,
     58                      uint32 parsingMode)
     59 {
     60 
     61     _pmovieAtom = NULL;
     62     _puserDataAtom = NULL;
     63     _pFileTypeAtom = NULL;
     64     _pMovieFragmentAtom = NULL;
     65     _mp4ErrorCode = EVERYTHING_FINE;
     66     _isMovieFragmentsPresent = false;
     67     _pointerMovieAtomEnd = 0;
     68     _movieFragmentFilePtr = NULL;
     69     _pMovieFragmentAtomVec = NULL;
     70     _pMfraOffsetAtom = NULL;
     71     _pMovieFragmentRandomAccessAtomVec = NULL;
     72     _pTrackExtendsAtomVec = NULL;
     73     _pMoofOffsetVec = NULL;
     74     _ptrMoofEnds = 0;
     75     _parsing_mode = parsingMode;
     76     _pTrackDurationContainer = NULL;
     77     oMfraFound = false;
     78     _oVideoTrackPresent = false;
     79     parseMoofCompletely = true;
     80     isResetPlayBackCalled = false;
     81 
     82     parseMoofCompletely = true;
     83     moofParsingCompleted = true;
     84     moofSize = 0;
     85     moofType = UNKNOWN_ATOM;
     86     moofCount = 0;
     87     moofPtrPos = 0;
     88     currMoofNum = 0;
     89     countOfTrunsParsed = 0;
     90 
     91     // Create miscellaneous vector of atoms
     92     PV_MP4_FF_NEW(fp->auditCB, trackAtomVecType, (), _pTrackAtomVec);
     93     PV_MP4_FF_NEW(fp->auditCB, movieFragmentAtomVecType, (), _pMovieFragmentAtomVec);
     94     PV_MP4_FF_NEW(fp->auditCB, movieFragmentOffsetVecType, (), _pMoofOffsetVec);
     95     PV_MP4_FF_NEW(fp->auditCB, movieFragmentRandomAccessAtomVecType, (), _pMovieFragmentRandomAccessAtomVec);
     96     PV_MP4_FF_NEW(fp->auditCB, PVID3ParCom, (), _pID3Parser);
     97 
     98 
     99     iLogger = PVLogger::GetLoggerObject("mp4ffparser");
    100     iStateVarLogger = PVLogger::GetLoggerObject("mp4ffparser_mediasamplestats");
    101     iParsedDataLogger = PVLogger::GetLoggerObject("mp4ffparser_parseddata");
    102 
    103     _success = true; // Initial state
    104 
    105     int32 fileSize;
    106     int32 filePointer;
    107     filePointer = AtomUtils::getCurrentFilePosition(fp);
    108     uint32 fsize = 0;
    109     AtomUtils::getCurrentFileSize(fp, fsize);
    110     fileSize = (int32)fsize;
    111 
    112     _oPVContent = false;
    113     _oPVContentDownloadable = false;
    114     _commonFilePtr = NULL;
    115     _fileSize = fsize;
    116 
    117     int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
    118 
    119     //top level moov, mdat, udat
    120     while (count > 0)
    121     {
    122         // Read in atoms until reach end of file
    123         //there is a case that next atom is valid, but not in top level
    124         //so only check top level now
    125         uint32 atomType = UNKNOWN_ATOM;
    126         uint32 atomSize = 0;
    127 
    128         AtomUtils::getNextAtomType(fp, atomSize, atomType);
    129 
    130         if ((atomType == SKIP_ATOM)
    131                 || (atomType == FREE_SPACE_ATOM)
    132                 || (atomType == UUID_ATOM)
    133                 || (atomType == UNKNOWN_ATOM)
    134                 || (atomType == MEDIA_DATA_ATOM))
    135         {
    136             if (atomSize == 1)
    137             {
    138                 uint64 largeSize = 0;
    139                 AtomUtils::read64(fp, largeSize);
    140                 uint32 size =
    141                     Oscl_Int64_Utils::get_uint64_lower32(largeSize);
    142                 count -= size;
    143                 size -= 8; //for large size
    144                 size -= DEFAULT_ATOM_SIZE;
    145                 AtomUtils::seekFromCurrPos(fp, size);
    146             }
    147             else
    148             {
    149                 if (atomSize < DEFAULT_ATOM_SIZE)
    150                 {
    151                     _success = false;
    152                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
    153                     break;
    154                 }
    155                 if (count < (int32)atomSize)
    156                 {
    157                     _success = false;
    158                     _mp4ErrorCode = READ_FAILED;
    159                     break;
    160                 }
    161                 count -= atomSize;
    162                 atomSize -= DEFAULT_ATOM_SIZE;
    163                 AtomUtils::seekFromCurrPos(fp, atomSize);
    164             }
    165         }
    166         else if (atomType == USER_DATA_ATOM)
    167         {
    168             //"udta"
    169             // Check for 'pvmm' to see if it is "our" 'udta' atom
    170 
    171             uint32 isPVMMAtom = AtomUtils::peekNextNthBytes(fp, 2);
    172 
    173             if (isPVMMAtom == PVUSER_DATA_ATOM)
    174             {
    175                 if (_puserDataAtom == NULL)
    176                 {
    177                     PV_MP4_FF_NEW(fp->auditCB, UserDataAtom, (fp, atomSize, atomType), _puserDataAtom);
    178                     _oPVContent = true;
    179                     uint32 contentType = getContentType();
    180                     if (contentType == DEFAULT_AUTHORING_MODE)
    181                     {
    182                         _oPVContentDownloadable = true;
    183                     }
    184                     count -= _puserDataAtom->getSize();
    185                 }
    186                 else
    187                 {
    188                     _success = false;
    189                     _mp4ErrorCode = READ_USER_DATA_ATOM_FAILED;
    190                     break;
    191                 }
    192             }
    193             else
    194             {
    195                 // Skip third party user data atom
    196                 if (atomSize < DEFAULT_ATOM_SIZE)
    197                 {
    198                     _success = false;
    199                     _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
    200                     break;
    201                 }
    202                 if (count < (int32)atomSize)
    203                 {
    204                     _success = false;
    205                     _mp4ErrorCode = READ_FAILED;
    206                     break;
    207                 }
    208                 count -= atomSize;
    209                 atomSize -= DEFAULT_ATOM_SIZE;
    210                 AtomUtils::seekFromCurrPos(fp, atomSize);
    211             }
    212 
    213 
    214         }
    215         else if (atomType == FILE_TYPE_ATOM)
    216         {
    217             if (_pFileTypeAtom == NULL)
    218             {
    219                 //"ftyp"
    220                 PV_MP4_FF_NEW(fp->auditCB, FileTypeAtom, (fp, atomSize, atomType), _pFileTypeAtom);
    221 
    222                 if (!_pFileTypeAtom->MP4Success())
    223                 {
    224                     _success = false;
    225                     _mp4ErrorCode = READ_FILE_TYPE_ATOM_FAILED;
    226                     break;
    227                 }
    228 
    229                 uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
    230                 uint32  majorBrandInfo = ENoFileType;
    231                 uint32  compatibleBrandInfo = ENoFileType;
    232 
    233 
    234                 switch (majorBrand)
    235                 {
    236                     case WMF_BRAND:
    237                         majorBrandInfo |= EWMF;
    238                         break;
    239 
    240                     case BRAND_3GPP4:
    241                         majorBrandInfo |= E3GP4;
    242                         break;
    243 
    244                     case BRAND_3GPP5:
    245                         majorBrandInfo |= E3GP5;
    246                         break;
    247 
    248                     case MOBILE_MP4:
    249                         majorBrandInfo |= EMMP4;
    250                         break;
    251 
    252                     case BRAND_MP41:
    253                         majorBrandInfo |= EMP41;
    254                         break;
    255 
    256                     case BRAND_MP42:
    257                         majorBrandInfo |= EMP42;
    258                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    259                         break;
    260 
    261                     case BRAND_ISOM:
    262                         majorBrandInfo |= EISOM;
    263                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    264                         break;
    265 
    266                     default:
    267                         majorBrandInfo |= EUNKNOWN_TYPE;
    268                         _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    269                         break;
    270                 }
    271 
    272                 Oscl_Vector<uint32, OsclMemAllocator> *compatibleBrandArray =
    273                     _pFileTypeAtom->getCompatibleBrand();
    274 
    275                 if (compatibleBrandArray != NULL)
    276                 {
    277                     for (uint32 i = 0; i < compatibleBrandArray->size(); i++)
    278                     {
    279                         uint32 compatibleBrand = (*compatibleBrandArray)[i];
    280 
    281                         switch (compatibleBrand)
    282                         {
    283                             case WMF_BRAND:
    284                                 compatibleBrandInfo |= EWMF;
    285                                 break;
    286 
    287                             case BRAND_3GPP4:
    288                                 compatibleBrandInfo |= E3GP4;
    289                                 break;
    290 
    291                             case BRAND_3GPP5:
    292                                 compatibleBrandInfo |= E3GP5;
    293                                 break;
    294 
    295                             case MOBILE_MP4:
    296                                 compatibleBrandInfo |= EMMP4;
    297                                 break;
    298 
    299                             case BRAND_MP41:
    300                                 compatibleBrandInfo |= EMP41;
    301                                 break;
    302 
    303                             case BRAND_MP42:
    304                                 compatibleBrandInfo |= EMP42;
    305                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    306                                 break;
    307 
    308                             case BRAND_ISOM:
    309                                 compatibleBrandInfo |= EISOM;
    310                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    311                                 break;
    312 
    313                             default:
    314                                 compatibleBrandInfo |= EUNKNOWN_TYPE;
    315                                 _mp4ErrorCode = UNSUPPORTED_FILE_TYPE;
    316                                 break;
    317                         }
    318                     }
    319                 }
    320 
    321                 count -= _pFileTypeAtom->getSize();
    322             }
    323             else
    324             {
    325                 //multiple "ftyp" atom not allowed.skipping
    326                 count -= atomSize;
    327                 atomSize -= DEFAULT_ATOM_SIZE;
    328                 AtomUtils::seekFromCurrPos(fp, atomSize);
    329             }
    330         }
    331         else if (atomType == MOVIE_ATOM)
    332         {
    333 
    334 
    335             //"moov"
    336             if (_pmovieAtom == NULL)
    337             {
    338                 // Only 1 movie atom allowed!
    339                 PV_MP4_FF_NEW(fp->auditCB, MovieAtom,
    340                               (fp,
    341                                filename,
    342                                atomSize,
    343                                atomType,
    344                                _oPVContent,
    345                                _oPVContentDownloadable,
    346                                parsingMode
    347                               ),
    348                               _pmovieAtom);
    349 
    350                 if (!_pmovieAtom->MP4Success())
    351                 {
    352                     _success = false;
    353                     _mp4ErrorCode = _pmovieAtom->GetMP4Error();
    354                     break;
    355                 }
    356                 _isMovieFragmentsPresent = _pmovieAtom->IsMovieFragmentPresent();
    357                 populateTrackDurationVec();
    358                 _pTrackExtendsAtomVec = _pmovieAtom->getTrackExtendsAtomVec();
    359 
    360                 if (_isMovieFragmentsPresent)
    361                 {
    362                     atomSize -= DEFAULT_ATOM_SIZE;
    363                     _pointerMovieAtomEnd =  AtomUtils::getCurrentFilePosition(fp);
    364                     _ptrMoofEnds = _pointerMovieAtomEnd;
    365                     OsclAny*ptr = oscl_malloc(sizeof(MP4_FF_FILE));
    366                     if (ptr == NULL)
    367                     {
    368                         _success = false;
    369                         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
    370                         return;
    371                     }
    372                     _movieFragmentFilePtr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE(*fp));
    373                     _movieFragmentFilePtr ->_pvfile.Copy(fp->_pvfile);
    374                     _movieFragmentFilePtr ->_pvfile.SetCPM(fp->_pvfile.GetCPM());
    375                 }
    376                 count -= _pmovieAtom->getSize();
    377                 _scalability = _pmovieAtom->getScalability();
    378                 _fileType    = _pmovieAtom->getFileType();
    379 
    380                 if (parsingMode != 0)
    381                 {
    382                     if (_isMovieFragmentsPresent)
    383                     {
    384                         parseMFRA();
    385                     }
    386                     break;
    387                 }
    388                 if (!_isMovieFragmentsPresent)
    389                 {
    390                     //no moofs, exit the parsing loop since
    391                     //we are done parsing the moov atom
    392                     break;
    393                 }
    394 
    395 
    396             }
    397             else
    398             { //after the change above, we will never hit here.
    399                 _success = false;
    400                 _mp4ErrorCode = DUPLICATE_MOVIE_ATOMS;
    401                 break;
    402             }
    403         }
    404         else if (atomType == MOVIE_FRAGMENT_ATOM)
    405         {
    406             uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(fp);
    407             moofStartOffset -= DEFAULT_ATOM_SIZE;
    408             _pMoofOffsetVec->push_back(moofStartOffset);
    409 
    410             MovieFragmentAtom *pMovieFragmentAtom = NULL;
    411             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentAtom, (fp, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), pMovieFragmentAtom);
    412 
    413             if (!pMovieFragmentAtom->MP4Success())
    414             {
    415                 _success = false;
    416                 _mp4ErrorCode = pMovieFragmentAtom->GetMP4Error();
    417                 break;
    418             }
    419             pMovieFragmentAtom->setParent(this);
    420             count -= pMovieFragmentAtom->getSize();
    421             _ptrMoofEnds = AtomUtils::getCurrentFilePosition(fp);
    422             _pMovieFragmentAtomVec->push_back(pMovieFragmentAtom);
    423         }
    424         else if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_ATOM)
    425         {
    426             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = NULL;
    427             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentRandomAccessAtom, (fp, atomSize, atomType), pMovieFragmentRandomAccessAtom);
    428 
    429             if (!pMovieFragmentRandomAccessAtom->MP4Success())
    430             {
    431                 _success = false;
    432                 _mp4ErrorCode = pMovieFragmentRandomAccessAtom->GetMP4Error();
    433                 break;
    434             }
    435             pMovieFragmentRandomAccessAtom->setParent(this);
    436             count -= pMovieFragmentRandomAccessAtom->getSize();
    437             _pMovieFragmentRandomAccessAtomVec->push_back(pMovieFragmentRandomAccessAtom);
    438             oMfraFound = true;
    439         }
    440         else
    441         {
    442             if (count > 0)
    443             {
    444                 _mp4ErrorCode = READ_UNKNOWN_ATOM;
    445                 _success = false;
    446             }
    447             break;
    448         }
    449     }
    450 
    451     if (_success)
    452     {
    453         // Check that the movie atom was in fact read in
    454         if (_pmovieAtom == NULL)
    455         {
    456             _success = false;
    457             _mp4ErrorCode = NO_MOVIE_ATOM_PRESENT;
    458         }
    459         else
    460         {
    461             // CHECK IF THERE ARE ANY VALID MEDIA TRACKS IN THE FILE
    462             int32 numMediaTracks = getNumTracks();
    463             if (numMediaTracks == 0)
    464             {
    465                 _success = false;
    466                 _mp4ErrorCode = NO_META_DATA_FOR_MEDIA_TRACKS;
    467             }
    468             if (_success)
    469             {
    470                 uint32 bufferCapacity = AtomUtils::getFileBufferingCapacity(fp);
    471                 if (0 != bufferCapacity)
    472                 {
    473                     // progressive playback
    474                     int32* offsetList = (int32 *)oscl_malloc(sizeof(int32) * numMediaTracks);
    475                     if (NULL == offsetList)
    476                     {
    477                         _success = false;
    478                         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
    479                     }
    480                     else
    481                     {
    482                         // get the list of track ids
    483                         uint32* idList = (uint32 *)oscl_malloc(sizeof(uint32) * numMediaTracks);
    484                         _pmovieAtom->getTrackIDList(idList, numMediaTracks);
    485 
    486                         // get the first sample file offset of each track
    487                         for (int32 i = 0; i < numMediaTracks; i++)
    488                         {
    489                             int32 retVal = _pmovieAtom->getOffsetByTime(idList[i], 0, &offsetList[i]);
    490                             if (EVERYTHING_FINE != retVal)
    491                             {
    492                                 _success = false;
    493                                 _mp4ErrorCode = retVal;
    494                                 break;
    495                             }
    496                         }
    497                         // check if any of the two offsets are too far apart
    498                         // to coexist in the cache at the same time
    499                         if (_success)
    500                         {
    501                             uint32 largest = 0, temp = 0;
    502                             for (int i = 0; i < numMediaTracks; i++)
    503                             {
    504                                 for (int j = 0; j < numMediaTracks; j++)
    505                                 {
    506                                     // same as abs()
    507                                     if (offsetList[i] > offsetList[j])
    508                                     {
    509                                         temp = offsetList[i] - offsetList[j];
    510                                     }
    511                                     else
    512                                     {
    513                                         temp = offsetList[j] - offsetList[i];
    514                                     }
    515 
    516                                     if (temp > largest)
    517                                     {
    518                                         largest = temp;
    519                                     }
    520                                 }
    521                             }
    522 
    523                             if (largest > bufferCapacity)
    524                             {
    525                                 // the samples are not interleaved properly
    526                                 // this clip is not authored for progressive playback
    527                                 _success = false;
    528                                 _mp4ErrorCode = INSUFFICIENT_BUFFER_SIZE;
    529                             }
    530                         }
    531 
    532                         oscl_free(idList);
    533                     }
    534 
    535                     oscl_free(offsetList);
    536                 }
    537             }
    538         }
    539     }
    540 
    541 
    542     // Check for any atoms that may have read past the EOF that were not
    543     // already caught by any earlier error handling
    544 
    545     if (filePointer > fileSize)
    546     {
    547         _mp4ErrorCode = READ_FAILED; // Read past EOF
    548         _success = false;
    549     }
    550 
    551     // skip ID3 tag parsing for progressive playback for now
    552     uint32 bufferCapacity = AtomUtils::getFileBufferingCapacity(fp);
    553     if (0 == bufferCapacity)
    554     {
    555         parseID3Header(fp);
    556     }
    557     //Populate the title vector with all the title metadata values.
    558     if (!populateMetadataVectors())
    559     {
    560         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::populateTitleVector() Failed"));
    561     }
    562 
    563 }
    564 
    565 
    566 PVMFStatus Mpeg4File::populateMetadataVectors()
    567 {
    568     if ((!populateTitleVector()) || (!populateAuthorVector() ||
    569                                      (!populateAlbumVector()) ||
    570                                      (!populateArtistVector()) || (!populateGenreVector()) ||
    571                                      (!populateYearVector()) || (!populateCopyrightVector()) ||
    572                                      (!populateCommentVector()) || (!populateDescriptionVector()) ||
    573                                      (!populateRatingVector()))
    574        )
    575     {
    576         return PVMFFailure;
    577     }
    578 
    579     return PVMFSuccess;
    580 }
    581 
    582 uint32 Mpeg4File::getNumTitle()
    583 {
    584     uint32 numTitle = 0;
    585     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
    586     numTitle = getNumAssetInfoTitleAtoms();
    587     if (getPVTitle(chartype).get_size() > 0)
    588     {
    589         numTitle++;
    590     }
    591     if (getITunesTitle().get_size() > 0)
    592     {
    593         numTitle++;
    594     }
    595     PvmiKvpSharedPtrVector framevector;
    596     GetID3MetaData(framevector);
    597     uint32 num_frames = framevector.size();
    598     for (uint32 i = 0; i < num_frames; i++)
    599     {
    600         if (framevector.size() > 0)
    601         {
    602             if (oscl_strstr(framevector[i]->key, "title") != 0)
    603             {
    604                 numTitle++;
    605                 break;
    606             }
    607         }
    608     }
    609     return numTitle;
    610 }
    611 
    612 //This function populates the Title Vector with values from Asset Info, Itunes, FullMusic and PV Proprietary Atoms.
    613 PVMFStatus Mpeg4File::populateTitleVector()
    614 {
    615     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
    616     int32 numTitle = getNumTitle();
    617     ReserveMemoryForValuesVector(titleValues, numTitle, leavecode);
    618     ReserveMemoryForLangCodeVector(iTitleLangCode, numTitle, leavecode1);
    619     OSCL_TRY(leavecode2, iTitleCharType.reserve(numTitle));
    620     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    621     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
    622     {
    623         return PVMFFailure;
    624     }
    625     int32 numAssetInfoTitle = getNumAssetInfoTitleAtoms();
    626 
    627 
    628     if (numAssetInfoTitle > 0)
    629     {
    630         for (int32 i = 0; i < numAssetInfoTitle; i++)
    631         {
    632             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoTitleNotice(charType, i);
    633 
    634             titleValues.push_front(valuestring);
    635             iTitleLangCode.push_front(getAssetInfoTitleLangCode(i));
    636             iTitleCharType.push_front(charType);
    637         }
    638     }
    639     if (getPVTitle(charType).get_size() > 0)
    640     {
    641         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVTitle(charType);
    642         titleValues.push_front(valuestring);
    643         iTitleLangCode.push_front(0);
    644         iTitleCharType.push_front(charType);
    645     }
    646     if (getITunesTitle().get_size() > 0)
    647     {
    648         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesTitle();
    649         titleValues.push_front(valuestring);
    650         iTitleLangCode.push_front(0);
    651         iTitleCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    652     }
    653     PvmiKvpSharedPtrVector framevector;
    654     GetID3MetaData(framevector);
    655     uint32 num_frames = framevector.size();
    656     for (uint32 i = 0; i < num_frames; i++)
    657     {
    658         if (framevector.size() > 0)
    659         {
    660             if (oscl_strstr(framevector[i]->key, "title") != 0)
    661             {
    662                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
    663                 oscl_memset(_id3v1Title, 0, ID3V1_STR_MAX_SIZE);
    664                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Title, len*2 + 2);
    665                 titleValues.push_front(_id3v1Title);
    666                 iTitleLangCode.push_front(0);
    667                 iTitleCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    668                 break;
    669             }
    670         }
    671     }
    672     return PVMFSuccess;
    673 }
    674 
    675 // This function returns the titles based on index value, to the parser node.
    676 PVMFStatus Mpeg4File::getTitle(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
    677 {
    678     if (index < titleValues.size())
    679     {
    680         aVal = NULL;
    681         aLangCode = 0;
    682         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    683         aVal = titleValues[index].get_cstr();
    684         aLangCode = iTitleLangCode[index];
    685         aCharEncType = iTitleCharType[index];
    686         return PVMFSuccess;
    687     }
    688     return PVMFErrArgument;
    689 }
    690 
    691 uint32 Mpeg4File::getNumAuthor()
    692 {
    693     uint32 numAuthor = 0;
    694     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
    695     numAuthor = getNumAssetInfoAuthorAtoms();
    696 
    697     if (getPVAuthor(chartype).get_size() > 0)
    698     {
    699         numAuthor++;
    700     }
    701     return numAuthor;
    702 }
    703 
    704 //This function populates the Author Vector with values from Asset Info and PV Proprietary Atoms.
    705 PVMFStatus Mpeg4File::populateAuthorVector()
    706 {
    707     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
    708     int32 numAuthor = getNumAuthor();
    709     ReserveMemoryForValuesVector(authorValues, numAuthor, leavecode);
    710     ReserveMemoryForLangCodeVector(iAuthorLangCode, numAuthor, leavecode1);
    711     OSCL_TRY(leavecode2, iAuthorCharType.reserve(numAuthor));
    712     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    713     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
    714     {
    715         return PVMFFailure;
    716     }
    717     int32 numAssetInfoAuthor = getNumAssetInfoAuthorAtoms();
    718     if (numAssetInfoAuthor > 0)
    719     {
    720         for (int32 i = 0; i < numAssetInfoAuthor; i++)
    721         {
    722             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoAuthorNotice(charType, i);
    723             authorValues.push_front(valuestring);
    724             iAuthorLangCode.push_front(getAssetInfoAuthorLangCode(i));
    725             iAuthorCharType.push_front(charType);
    726         }
    727     }
    728     if (getPVAuthor(charType).get_size() > 0)
    729     {
    730         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVAuthor(charType);
    731         authorValues.push_front(valuestring);
    732         iAuthorLangCode.push_front(0);
    733         iAuthorCharType.push_front(charType);
    734     }
    735     return PVMFSuccess;
    736 }
    737 
    738 // This function returns the Author based on index value, to the parser node.
    739 PVMFStatus Mpeg4File::getAuthor(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
    740 {
    741     if (index < authorValues.size())
    742     {
    743         aVal = NULL;
    744         aLangCode = 0;
    745         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    746         aVal = authorValues[index].get_cstr();
    747         aLangCode = iAuthorLangCode[index];
    748         aCharEncType = iAuthorCharType[index];
    749         return PVMFSuccess;
    750     }
    751     return PVMFErrArgument;
    752 }
    753 
    754 uint32 Mpeg4File::getNumAlbum()
    755 {
    756     uint32 numAlbum = 0;
    757     numAlbum = getNumAssetInfoAlbumAtoms();
    758     if (getITunesAlbum().get_size() > 0)
    759     {
    760         numAlbum++;
    761     }
    762     PvmiKvpSharedPtrVector framevector;
    763     GetID3MetaData(framevector);
    764     uint32 num_frames = framevector.size();
    765     for (uint32 i = 0; i < num_frames; i++)
    766     {
    767         if (framevector.size() > 0)
    768         {
    769             if (oscl_strstr(framevector[i]->key, "album") != 0)
    770             {
    771                 numAlbum++;
    772                 break;
    773             }
    774         }
    775     }
    776     return numAlbum;
    777 }
    778 
    779 //This function populates the Album Vector with values from Asset Info, Itunes, FullMusic Atoms.
    780 PVMFStatus Mpeg4File::populateAlbumVector()
    781 {
    782     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
    783     int32 numAlbum = getNumAlbum();
    784     ReserveMemoryForValuesVector(albumValues, numAlbum, leavecode);
    785     ReserveMemoryForLangCodeVector(iAlbumLangCode, numAlbum, leavecode1);
    786     OSCL_TRY(leavecode2, iAlbumCharType.reserve(numAlbum));
    787     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    788     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
    789     {
    790         return PVMFFailure;
    791     }
    792     int32 numAssetInfoAlbum = getNumAssetInfoAlbumAtoms();
    793     if (numAssetInfoAlbum > 0)
    794     {
    795         for (int32 i = 0; i < numAssetInfoAlbum; i++)
    796         {
    797             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoAlbumNotice(charType, i);
    798             albumValues.push_front(valuestring);
    799             iAlbumLangCode.push_front(getAssetInfoAlbumLangCode(i));
    800             iAlbumCharType.push_front(charType);
    801         }
    802     }
    803     if (getITunesAlbum().get_size() > 0)
    804     {
    805         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesAlbum();
    806         albumValues.push_front(valuestring);
    807         iAlbumLangCode.push_front(0);
    808         iAlbumCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    809     }
    810     PvmiKvpSharedPtrVector framevector;
    811     GetID3MetaData(framevector);
    812     uint32 num_frames = framevector.size();
    813     for (uint32 i = 0; i < num_frames; i++)
    814     {
    815         if (framevector.size() > 0)
    816         {
    817             if (oscl_strstr(framevector[i]->key, "album") != 0)
    818             {
    819                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
    820                 oscl_memset(_id3v1Album, 0, ID3V1_STR_MAX_SIZE);
    821                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Album, len*2 + 2);
    822                 albumValues.push_front(_id3v1Album);
    823                 iAlbumLangCode.push_front(0);
    824                 iAlbumCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    825                 break;
    826             }
    827         }
    828     }
    829 
    830     return PVMFSuccess;
    831 }
    832 
    833 // This function returns the Album based on index value, to the parser node.
    834 PVMFStatus Mpeg4File::getAlbum(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
    835 {
    836     if (index < albumValues.size())
    837     {
    838         aVal = NULL;
    839         aLangCode = 0;
    840         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    841         aVal = albumValues[index].get_cstr();
    842         aLangCode = iAlbumLangCode[index];
    843         aCharEncType = iAlbumCharType[index];
    844         return PVMFSuccess;
    845     }
    846     return PVMFErrArgument;
    847 }
    848 
    849 uint32 Mpeg4File::getNumArtist()
    850 {
    851     uint32 numArtist = 0;
    852     numArtist = getNumAssetInfoPerformerAtoms();
    853 
    854     if (getITunesArtist().get_size() > 0)
    855     {
    856         numArtist++;
    857     }
    858     if (getITunesAlbumArtist().get_size() > 0) //AlbumArtist
    859     {
    860         numArtist++;
    861     }
    862 
    863     PvmiKvpSharedPtrVector framevector;
    864     GetID3MetaData(framevector);
    865     uint32 num_frames = framevector.size();
    866     for (uint32 i = 0; i < num_frames; i++)
    867     {
    868         if (framevector.size() > 0)
    869         {
    870             if (oscl_strstr(framevector[i]->key, "artist") != 0)
    871             {
    872                 numArtist++;
    873                 break;
    874             }
    875         }
    876     }
    877     return numArtist;
    878 }
    879 
    880 
    881 //This function populates the Artist Vector with values from Asset Info, Itunes, FullMusic Atoms.
    882 PVMFStatus Mpeg4File::populateArtistVector()
    883 {
    884     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
    885     int32 numArtist = getNumArtist();
    886     ReserveMemoryForValuesVector(artistValues, numArtist, leavecode);
    887     ReserveMemoryForLangCodeVector(iArtistLangCode, numArtist, leavecode1);
    888     OSCL_TRY(leavecode2, iArtistCharType.reserve(numArtist));
    889     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    890     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
    891     {
    892         return PVMFFailure;
    893     }
    894     int32 numAssetInfoPerformer = getNumAssetInfoPerformerAtoms();
    895     if (numAssetInfoPerformer > 0)
    896     {
    897         for (int32 i = 0; i < numAssetInfoPerformer; i++)
    898         {
    899             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoPerformerNotice(charType, i);
    900             artistValues.push_front(valuestring);
    901             iArtistLangCode.push_front(getAssetInfoPerformerLangCode(i));
    902             iArtistCharType.push_front(charType);
    903         }
    904     }
    905     if (getITunesArtist().get_size() > 0)
    906     {
    907         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesArtist();
    908         artistValues.push_front(valuestring);
    909         iArtistLangCode.push_front(0);
    910         iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    911     }
    912     if (getITunesAlbumArtist().get_size() > 0) //AlbumArtist
    913     {
    914         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesAlbumArtist();
    915         artistValues.push_front(valuestring);
    916         iArtistLangCode.push_front(0);
    917         iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    918     }
    919     PvmiKvpSharedPtrVector framevector;
    920     GetID3MetaData(framevector);
    921     uint32 num_frames = framevector.size();
    922     for (uint32 i = 0; i < num_frames; i++)
    923     {
    924         if (framevector.size() > 0)
    925         {
    926             if (oscl_strstr(framevector[i]->key, "artist") != 0)
    927             {
    928                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
    929                 oscl_memset(_id3v1Artist, 0, ID3V1_STR_MAX_SIZE);
    930                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Artist, len*2 + 2);
    931                 artistValues.push_front(_id3v1Artist);
    932                 iArtistLangCode.push_front(0);
    933                 iArtistCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
    934                 break;
    935             }
    936         }
    937     }
    938     return PVMFSuccess;
    939 }
    940 
    941 // This function returns the Artists based on index value, to the parser node.
    942 PVMFStatus Mpeg4File::getArtist(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
    943 {
    944     if (index < artistValues.size())
    945     {
    946         aVal = NULL;
    947         aLangCode = 0;
    948         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    949         aVal = artistValues[index].get_cstr();
    950         aLangCode = iArtistLangCode[index];
    951         aCharEncType = iArtistCharType[index];
    952         return PVMFSuccess;
    953     }
    954     return PVMFErrArgument;
    955 }
    956 
    957 uint32 Mpeg4File::getNumGenre()
    958 {
    959     uint32 numGenre = 0;
    960     numGenre = getNumAssetInfoGenreAtoms();
    961 
    962     if (getITunesGnreString().get_size() > 0)
    963     {
    964         numGenre++;
    965     }
    966     if (getITunesGnreID() > 0)
    967     {
    968         numGenre++;
    969     }
    970     return numGenre;
    971 }
    972 
    973 //This function populates the Genre Vector with values from Asset Info, Itunes, FullMusic Atoms.
    974 PVMFStatus Mpeg4File::populateGenreVector()
    975 {
    976     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
    977     int32 numGenre = getNumGenre();
    978     ReserveMemoryForValuesVector(genreValues, numGenre, leavecode);
    979     ReserveMemoryForLangCodeVector(iGenreLangCode, numGenre, leavecode1);
    980     OSCL_TRY(leavecode2, iGenreCharType.reserve(numGenre));
    981     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
    982     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
    983     {
    984         return PVMFFailure;
    985     }
    986     int32 numAssetInfoGenre = getNumAssetInfoGenreAtoms();
    987     if (numAssetInfoGenre > 0)
    988     {
    989         for (int32 i = 0; i < numAssetInfoGenre; i++)
    990         {
    991             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoGenreNotice(charType, i);
    992             genreValues.push_front(valuestring);
    993             iGenreLangCode.push_front(getAssetInfoGenreLangCode(i));
    994             iGenreCharType.push_front(charType);
    995         }
    996     }
    997     if (getITunesGnreString().get_size() > 0)
    998     {
    999         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesGnreString();
   1000         genreValues.push_front(valuestring);
   1001         iGenreLangCode.push_front(0);
   1002         iGenreCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
   1003     }
   1004     return PVMFSuccess;
   1005 }
   1006 
   1007 // This function returns the Genres based on index value, to the parser node.
   1008 PVMFStatus Mpeg4File::getGenre(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
   1009 {
   1010     if (index < genreValues.size())
   1011     {
   1012         aVal = NULL;
   1013         aLangCode = 0;
   1014         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1015         aVal = genreValues[index].get_cstr();
   1016         aLangCode = iGenreLangCode[index];
   1017         aCharEncType = iGenreCharType[index];
   1018         return PVMFSuccess;
   1019     }
   1020     return PVMFErrArgument;
   1021 }
   1022 
   1023 
   1024 uint32 Mpeg4File::getNumCopyright()
   1025 {
   1026     uint32 numCopyright = 0;
   1027     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1028     numCopyright = getNumCopyRightAtoms();
   1029     if (getPVCopyright(chartype).get_size() > 0)
   1030     {
   1031         numCopyright++;
   1032     }
   1033     if (getITunesCopyright().get_size() > 0)
   1034     {
   1035         numCopyright++;
   1036     }
   1037     return numCopyright;
   1038 }
   1039 
   1040 
   1041 //This function populates the Copyright Vector with values from Asset Info, Itunes and PV Proprietary Atoms.
   1042 PVMFStatus Mpeg4File::populateCopyrightVector()
   1043 {
   1044     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
   1045     int32 numCopyright = getNumCopyright();
   1046     ReserveMemoryForValuesVector(copyrightValues, numCopyright, leavecode);
   1047     ReserveMemoryForLangCodeVector(iCopyrightLangCode, numCopyright, leavecode1);
   1048     OSCL_TRY(leavecode2, iCopyrightCharType.reserve(numCopyright));
   1049     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1050     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
   1051     {
   1052         return PVMFFailure;
   1053     }
   1054     int32 numAssetInfoCopyright = getNumCopyRightAtoms();
   1055     if (numAssetInfoCopyright > 0)
   1056     {
   1057         for (int32 i = 0; i < numAssetInfoCopyright; i++)
   1058         {
   1059             OSCL_wHeapString<OsclMemAllocator> valuestring = getCopyRightString(charType, i);
   1060             copyrightValues.push_front(valuestring);
   1061             iCopyrightLangCode.push_front(getCopyRightLanguageCode(i));
   1062             iCopyrightCharType.push_front(charType);
   1063         }
   1064     }
   1065     if (getPVCopyright(charType).get_size() > 0)
   1066     {
   1067         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVCopyright(charType);
   1068         copyrightValues.push_front(valuestring);
   1069         iCopyrightLangCode.push_front(0);
   1070         iCopyrightCharType.push_front(charType);
   1071     }
   1072     if (getITunesCopyright().get_size() > 0)
   1073     {
   1074         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesCopyright();
   1075         copyrightValues.push_front(valuestring);
   1076         iCopyrightLangCode.push_front(0);
   1077         iCopyrightCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
   1078     }
   1079     return PVMFSuccess;
   1080 }
   1081 
   1082 // This function returns the Copyrights based on index value, to the parser node.
   1083 PVMFStatus Mpeg4File::getCopyright(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
   1084 {
   1085     if (index < copyrightValues.size())
   1086     {
   1087         aVal = NULL;
   1088         aLangCode = 0;
   1089         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1090         aVal = copyrightValues[index].get_cstr();
   1091         aLangCode = iCopyrightLangCode[index];
   1092         aCharEncType = iCopyrightCharType[index];
   1093         return PVMFSuccess;
   1094     }
   1095     return PVMFErrArgument;
   1096 }
   1097 
   1098 
   1099 uint32 Mpeg4File::getNumComment()
   1100 {
   1101     uint32 numComment = 0;
   1102 
   1103 
   1104     if (getITunesComment().get_size() > 0)
   1105     {
   1106         numComment++;
   1107     }
   1108     PvmiKvpSharedPtrVector framevector;
   1109     GetID3MetaData(framevector);
   1110     uint32 num_frames = framevector.size();
   1111     for (uint32 i = 0; i < num_frames; i++)
   1112     {
   1113         if (framevector.size() > 0)
   1114         {
   1115             if (oscl_strstr(framevector[i]->key, "comment") != 0)
   1116             {
   1117                 numComment++;
   1118                 break;
   1119             }
   1120         }
   1121     }
   1122 
   1123     return numComment;
   1124 }
   1125 
   1126 
   1127 //This function populates the Comment Vector with values from Itunes, FullMusic Atoms.
   1128 PVMFStatus Mpeg4File::populateCommentVector()
   1129 {
   1130     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
   1131     int32 numComment = getNumComment();
   1132     ReserveMemoryForValuesVector(commentValues, numComment, leavecode);
   1133     ReserveMemoryForLangCodeVector(iCommentLangCode, numComment, leavecode1);
   1134     OSCL_TRY(leavecode2, iCommentCharType.reserve(numComment));
   1135     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
   1136     {
   1137         return PVMFFailure;
   1138     }
   1139 
   1140     if (getITunesComment().get_size() > 0)
   1141     {
   1142         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesComment();
   1143         commentValues.push_front(valuestring);
   1144         iCommentLangCode.push_front(0);
   1145         iCommentCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
   1146     }
   1147     PvmiKvpSharedPtrVector framevector;
   1148     GetID3MetaData(framevector);
   1149     uint32 num_frames = framevector.size();
   1150     for (uint32 i = 0; i < num_frames; i++)
   1151     {
   1152         if (framevector.size() > 0)
   1153         {
   1154             if (oscl_strstr(framevector[i]->key, "comment") != 0)
   1155             {
   1156                 uint32 len = oscl_strlen(framevector[i]->value.pChar_value);
   1157                 oscl_memset(_id3v1Comment, 0, ID3V1_STR_MAX_SIZE);
   1158                 oscl_UTF8ToUnicode(framevector[i]->value.pChar_value, len, _id3v1Comment, len*2 + 2);
   1159                 commentValues.push_front(_id3v1Comment);
   1160                 iCommentLangCode.push_front(0);
   1161                 iCommentCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
   1162                 break;
   1163             }
   1164         }
   1165     }
   1166 
   1167     return PVMFSuccess;
   1168 }
   1169 
   1170 // This function returns the Comments based on index value, to the parser node.
   1171 PVMFStatus Mpeg4File::getComment(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc& aCharEncType)
   1172 {
   1173     if (index < commentValues.size())
   1174     {
   1175         aVal = NULL;
   1176         aLangCode = 0;
   1177         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1178         aVal = commentValues[index].get_cstr();
   1179         aLangCode = iCommentLangCode[index];
   1180         aCharEncType = iCommentCharType[index];
   1181         return PVMFSuccess;
   1182     }
   1183     return PVMFErrArgument;
   1184 }
   1185 
   1186 
   1187 uint32 Mpeg4File::getNumDescription()
   1188 {
   1189     uint32 numDescription = 0;
   1190     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1191     numDescription = getNumAssetInfoDescAtoms();
   1192     if (getPVDescription(chartype).get_size() > 0)
   1193     {
   1194         numDescription++;
   1195     }
   1196     if (getITunesDescription().get_size() > 0)
   1197     {
   1198         numDescription++;
   1199     }
   1200 
   1201     return numDescription;
   1202 }
   1203 
   1204 
   1205 //This function populates the Description Vector with values from Asset Info, Itunes and PV Proprietary Atoms.
   1206 PVMFStatus Mpeg4File::populateDescriptionVector()
   1207 {
   1208     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
   1209     int32 numDescription = getNumDescription();
   1210     ReserveMemoryForValuesVector(descriptionValues, numDescription, leavecode);
   1211     ReserveMemoryForLangCodeVector(iDescriptionLangCode, numDescription, leavecode1);
   1212     OSCL_TRY(leavecode2, iDescriptionCharType.reserve(numDescription));
   1213     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1214     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
   1215     {
   1216         return PVMFFailure;
   1217     }
   1218     int32 numAssetInfoDescription = getNumAssetInfoDescAtoms();
   1219     if (numAssetInfoDescription > 0)
   1220     {
   1221         for (int32 i = 0; i < numAssetInfoDescription; i++)
   1222         {
   1223             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoDescNotice(charType, i);
   1224             descriptionValues.push_front(valuestring);
   1225             iDescriptionLangCode.push_front(getAssetInfoDescLangCode(i));
   1226             iDescriptionCharType.push_front(charType);
   1227         }
   1228     }
   1229     if (getPVDescription(charType).get_size() > 0)
   1230     {
   1231         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVDescription(charType);
   1232         descriptionValues.push_front(valuestring);
   1233         iDescriptionLangCode.push_front(0);
   1234         iDescriptionCharType.push_front(charType);
   1235     }
   1236 
   1237     if (getITunesDescription().get_size() > 0)
   1238     {
   1239         OSCL_wHeapString<OsclMemAllocator> valuestring = getITunesDescription();
   1240         descriptionValues.push_front(valuestring);
   1241         iDescriptionLangCode.push_front(0);
   1242         iDescriptionCharType.push_front(ORIGINAL_CHAR_TYPE_UNKNOWN);
   1243     }
   1244 
   1245     return PVMFSuccess;
   1246 }
   1247 
   1248 // This function returns the Descriptions based on index value, to the parser node.
   1249 PVMFStatus Mpeg4File::getDescription(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc&
   1250                                      aCharEncType)
   1251 {
   1252     if (index < descriptionValues.size())
   1253     {
   1254         aVal = NULL;
   1255         aLangCode = 0;
   1256         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1257         aVal = descriptionValues[index].get_cstr();
   1258         aLangCode = iDescriptionLangCode[index];
   1259         aCharEncType = iDescriptionCharType[index];
   1260         return PVMFSuccess;
   1261     }
   1262     return PVMFErrArgument;
   1263 }
   1264 
   1265 
   1266 uint32 Mpeg4File::getNumRating()
   1267 {
   1268     uint32 numRating = 0;
   1269     MP4FFParserOriginalCharEnc chartype = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1270     numRating = getNumAssetInfoRatingAtoms();
   1271 
   1272     if (getPVRating(chartype).get_size() > 0)
   1273     {
   1274         numRating++;
   1275     }
   1276     return numRating;
   1277 }
   1278 
   1279 
   1280 //This function populates the Rating Vector with values from Asset Info and PV Proprietary Atoms.
   1281 PVMFStatus Mpeg4File::populateRatingVector()
   1282 {
   1283     int32 leavecode = 0, leavecode1 = 0, leavecode2 = 0;
   1284     int32 numRating = getNumRating();
   1285     ReserveMemoryForValuesVector(ratingValues, numRating, leavecode);
   1286     ReserveMemoryForLangCodeVector(iRatingLangCode, numRating, leavecode1);
   1287     OSCL_TRY(leavecode2, iRatingCharType.reserve(numRating));
   1288     MP4FFParserOriginalCharEnc charType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1289     if (leavecode != 0 || leavecode1 != 0 || leavecode2 != 0)
   1290     {
   1291         return PVMFFailure;
   1292     }
   1293     int32 numAssetInfoRating = getNumAssetInfoRatingAtoms();
   1294     if (numAssetInfoRating > 0)
   1295     {
   1296         for (int32 i = 0; i < numAssetInfoRating; i++)
   1297         {
   1298             OSCL_wHeapString<OsclMemAllocator> valuestring = getAssetInfoRatingNotice(charType, i);
   1299             ratingValues.push_front(valuestring);
   1300             iRatingLangCode.push_front(getAssetInfoRatingLangCode(i));
   1301             iRatingCharType.push_front(charType);
   1302         }
   1303     }
   1304     if (getPVRating(charType).get_size() > 0)
   1305     {
   1306         OSCL_wHeapString<OsclMemAllocator> valuestring = getPVRating(charType);
   1307         ratingValues.push_front(valuestring);
   1308         iRatingLangCode.push_front(0);
   1309         iRatingCharType.push_front(charType);
   1310     }
   1311 
   1312     return PVMFSuccess;
   1313 }
   1314 
   1315 // This function returns the Ratings based on index value, to the parser node.
   1316 PVMFStatus Mpeg4File::getRating(uint32 index, OSCL_wString& aVal, uint16& aLangCode, MP4FFParserOriginalCharEnc&
   1317                                 aCharEncType)
   1318 {
   1319     if (index < ratingValues.size())
   1320     {
   1321         aVal = NULL;
   1322         aLangCode = 0;
   1323         aCharEncType = ORIGINAL_CHAR_TYPE_UNKNOWN;
   1324         aVal = ratingValues[index].get_cstr();
   1325         aLangCode = iRatingLangCode[index];
   1326         aCharEncType = iRatingCharType[index];
   1327         return PVMFSuccess;
   1328     }
   1329     return PVMFErrArgument;
   1330 }
   1331 
   1332 
   1333 uint32 Mpeg4File::getNumYear()
   1334 {
   1335     uint32 numYear = 0;
   1336     numYear = getNumAssetInfoRecordingYearAtoms();
   1337     if (getITunesYear().get_size() > 0)
   1338     {
   1339         numYear++;
   1340     }
   1341 
   1342     PvmiKvpSharedPtrVector framevector;
   1343     GetID3MetaData(framevector);
   1344     uint32 num_frames = framevector.size();
   1345     for (uint32 i = 0; i < num_frames; i++)
   1346     {
   1347         if (framevector.size() > 0)
   1348         {
   1349             if (oscl_strstr(framevector[i]->key, "year") != 0)
   1350             {
   1351                 numYear++;
   1352                 break;
   1353             }
   1354         }
   1355     }
   1356     return numYear;
   1357 }
   1358 
   1359 
   1360 //This function populates the Year Vector with values from Asset Info, Itunes, FullMusic and PV Proprietary Atoms.
   1361 PVMFStatus Mpeg4File::populateYearVector()
   1362 {
   1363     int32 leavecode = 0;
   1364     int32 numYear = getNumYear();
   1365     OSCL_TRY(leavecode, yearValues.reserve(numYear));
   1366 
   1367     if (leavecode != 0)
   1368     {
   1369         return PVMFFailure;
   1370     }
   1371     int32 numAssetInfoRecordingYear = getNumAssetInfoRecordingYearAtoms();
   1372     if (numAssetInfoRecordingYear > 0)
   1373     {
   1374         for (int32 i = 0; i < numAssetInfoRecordingYear; i++)
   1375         {
   1376             uint16 valuestring = getAssetInfoRecordingYear(i);
   1377             yearValues.push_front(valuestring);
   1378         }
   1379     }
   1380     if (getITunesYear().get_size() > 0)
   1381     {
   1382         uint32 value, i;
   1383         OSCL_wHeapString<OsclMemAllocator> values1 = getITunesYear();
   1384         char valuestring[256];
   1385         oscl_UnicodeToUTF8(values1.get_cstr(), values1.get_size(), valuestring, 256);
   1386         i = PV_atoi(valuestring, 'd', value);
   1387         yearValues.push_front(value);
   1388     }
   1389     PvmiKvpSharedPtrVector framevector;
   1390     GetID3MetaData(framevector);
   1391     uint32 num_frames = framevector.size();
   1392     for (uint32 i = 0; i < num_frames; i++)
   1393     {
   1394         if (framevector.size() > 0)
   1395         {
   1396             if (oscl_strstr(framevector[i]->key, "year") != 0)
   1397             {
   1398                 PV_atoi(framevector[i]->value.pChar_value, 'd', _id3v1Year);
   1399                 yearValues.push_front(_id3v1Year);
   1400                 break;
   1401             }
   1402         }
   1403     }
   1404 
   1405     return PVMFSuccess;
   1406 }
   1407 
   1408 // This function returns the Years based on index value, to the parser node.
   1409 PVMFStatus Mpeg4File::getYear(uint32 index, uint32& aVal)
   1410 {
   1411     if (index < yearValues.size())
   1412     {
   1413         aVal = 0;
   1414         aVal = yearValues[index];
   1415 
   1416         return PVMFSuccess;
   1417     }
   1418     return PVMFErrArgument;
   1419 }
   1420 OSCL_wString& Mpeg4File::getPVTitle(MP4FFParserOriginalCharEnc &charType)
   1421 {
   1422     PVUserDataAtom *patom = NULL;
   1423     if (_puserDataAtom != NULL)
   1424     {
   1425         patom =
   1426             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1427     }
   1428     else
   1429     {
   1430         return _emptyString;
   1431     }
   1432 
   1433     if (patom != NULL)
   1434     {
   1435         return patom->getPVTitle(charType);
   1436     }
   1437     else
   1438     {
   1439         return _emptyString;
   1440     }
   1441 }
   1442 
   1443 OSCL_wString& Mpeg4File::getPVAuthor(MP4FFParserOriginalCharEnc &charType)
   1444 {
   1445     PVUserDataAtom *patom = NULL;
   1446     if (_puserDataAtom != NULL)
   1447     {
   1448         patom =
   1449             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1450     }
   1451     else
   1452     {
   1453         return _emptyString;
   1454     }
   1455 
   1456     if (patom != NULL)
   1457     {
   1458         return patom->getPVAuthor(charType);
   1459     }
   1460     else
   1461     {
   1462         return _emptyString;
   1463     }
   1464 }
   1465 
   1466 OSCL_wString& Mpeg4File::getPVVersion(MP4FFParserOriginalCharEnc &charType)
   1467 {
   1468     OSCL_UNUSED_ARG(charType);
   1469 
   1470     PVUserDataAtom *patom = NULL;
   1471     if (_puserDataAtom != NULL)
   1472     {
   1473         patom =
   1474             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1475     }
   1476     else
   1477     {
   1478         return _emptyString;
   1479     }
   1480 
   1481     if (patom != NULL)
   1482     {
   1483         return patom->getPVVersion();
   1484     }
   1485     else
   1486     {
   1487         return _emptyString;
   1488     }
   1489 }
   1490 
   1491 OSCL_wString& Mpeg4File::getPVCopyright(MP4FFParserOriginalCharEnc &charType)
   1492 {
   1493     PVUserDataAtom *patom = NULL;
   1494     if (_puserDataAtom != NULL)
   1495     {
   1496         patom =
   1497             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1498     }
   1499     else
   1500     {
   1501         return _emptyString;
   1502     }
   1503 
   1504     if (patom != NULL)
   1505     {
   1506         return patom->getPVCopyright(charType);
   1507     }
   1508     else
   1509     {
   1510         return _emptyString;
   1511     }
   1512 }
   1513 
   1514 OSCL_wString& Mpeg4File::getPVDescription(MP4FFParserOriginalCharEnc &charType)
   1515 {
   1516     PVUserDataAtom *patom = NULL;
   1517     if (_puserDataAtom != NULL)
   1518     {
   1519         patom =
   1520             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1521     }
   1522     else
   1523     {
   1524         return _emptyString;
   1525     }
   1526 
   1527     if (patom != NULL)
   1528     {
   1529         return patom->getPVDescription(charType);
   1530     }
   1531     else
   1532     {
   1533         return _emptyString;
   1534     }
   1535 }
   1536 
   1537 OSCL_wString& Mpeg4File::getPVRating(MP4FFParserOriginalCharEnc &charType)
   1538 {
   1539     PVUserDataAtom *patom = NULL;
   1540     if (_puserDataAtom != NULL)
   1541     {
   1542         patom =
   1543             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1544     }
   1545     else
   1546     {
   1547         return _emptyString;
   1548     }
   1549 
   1550     if (patom != NULL)
   1551     {
   1552         return patom->getPVRating(charType);
   1553     }
   1554     else
   1555     {
   1556         return _emptyString;
   1557     }
   1558 }
   1559 
   1560 OSCL_wHeapString<OsclMemAllocator> Mpeg4File::getCreationDate(MP4FFParserOriginalCharEnc &charType)
   1561 {
   1562     PVUserDataAtom *patom = NULL;
   1563     if (_puserDataAtom != NULL)
   1564     {
   1565         patom =
   1566             (PVUserDataAtom*) _puserDataAtom->getAtomOfType(FourCharConstToUint32('p', 'v', 'm', 'm'));
   1567         if (patom != NULL)
   1568         {
   1569             return patom->getPVCreationDate(charType);
   1570         }
   1571         else
   1572         {
   1573             return _emptyString;
   1574         }
   1575     }
   1576     else
   1577     {
   1578         return (_pmovieAtom->getCreationDate());
   1579     }
   1580 }
   1581 
   1582 // Destructor
   1583 Mpeg4File::~Mpeg4File()
   1584 {
   1585     uint32 i;
   1586     // Clean up atoms
   1587     if (_pmovieAtom != NULL)
   1588     {
   1589         PV_MP4_FF_DELETE(NULL, MovieAtom, _pmovieAtom);
   1590     }
   1591 
   1592     //Delete all the track atoms in the vec
   1593     for (i = 0; i < _pTrackAtomVec->size(); i++)
   1594     {
   1595         PV_MP4_FF_DELETE(NULL, TrackAtom, (*_pTrackAtomVec)[i]);
   1596     }
   1597 
   1598     // Delete the vectors themselves
   1599     PV_MP4_FF_TEMPLATED_DELETE(NULL, trackAtomVecType, Oscl_Vector, _pTrackAtomVec);
   1600 
   1601 
   1602     titleValues.destroy();
   1603     iTitleLangCode.destroy();
   1604     iTitleCharType.destroy();
   1605 
   1606     authorValues.destroy();
   1607     iAuthorLangCode.destroy();
   1608     iAuthorCharType.destroy();
   1609 
   1610 
   1611     albumValues.destroy();
   1612     iAlbumLangCode.destroy();
   1613     iAlbumCharType.destroy();
   1614 
   1615 
   1616     artistValues.destroy();
   1617     iArtistLangCode.destroy();
   1618     iArtistCharType.destroy();
   1619 
   1620 
   1621     genreValues.destroy();
   1622     iGenreLangCode.destroy();
   1623     iGenreCharType.destroy();
   1624 
   1625 
   1626     yearValues.destroy();
   1627 
   1628 
   1629     copyrightValues.destroy();
   1630     iCopyrightLangCode.destroy();
   1631     iCopyrightCharType.destroy();
   1632 
   1633 
   1634     commentValues.destroy();
   1635     iCommentLangCode.destroy();
   1636     iCommentCharType.destroy();
   1637 
   1638 
   1639     descriptionValues.destroy();
   1640     iDescriptionLangCode.destroy();
   1641     iDescriptionCharType.destroy();
   1642 
   1643 
   1644     ratingValues.destroy();
   1645     iRatingLangCode.destroy();
   1646     iRatingCharType.destroy()   ;
   1647 
   1648 
   1649     //delete all movie fragments
   1650     for (i = 0; i < _pMovieFragmentAtomVec->size(); i++)
   1651     {
   1652         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom, (*_pMovieFragmentAtomVec)[i]);
   1653     }
   1654     PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentAtomVecType, Oscl_Vector, _pMovieFragmentAtomVec);
   1655     //delete all movie fragments randomm access box
   1656     for (i = 0; i < _pMovieFragmentRandomAccessAtomVec->size(); i++)
   1657     {
   1658         PV_MP4_FF_DELETE(NULL, MovieFragmentRandomAccessAtom, (*_pMovieFragmentRandomAccessAtomVec)[i]);
   1659     }
   1660     // Delete the vectors themselves
   1661     PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentRandomAccessAtomVecType, Oscl_Vector, _pMovieFragmentRandomAccessAtomVec);
   1662 
   1663     if (_pMoofOffsetVec != NULL)
   1664         PV_MP4_FF_TEMPLATED_DELETE(NULL, movieFragmentOffsetVecType, Oscl_Vector, _pMoofOffsetVec);
   1665 
   1666 
   1667     if (_pMfraOffsetAtom != NULL)
   1668     {
   1669         PV_MP4_FF_DELETE(NULL, MfraOffsetAtom, _pMfraOffsetAtom);
   1670     }
   1671 
   1672     if (_pTrackDurationContainer != NULL)
   1673     {
   1674         for (i = 0; i < _pTrackDurationContainer->_pTrackdurationInfoVec->size(); i++)
   1675         {
   1676             PV_MP4_FF_DELETE(NULL, TrackDurationInfo, (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i]);
   1677         }
   1678         PV_MP4_FF_TEMPLATED_DELETE(NULL, trackDurationInfoVecType, Oscl_Vector, _pTrackDurationContainer->_pTrackdurationInfoVec);
   1679 
   1680         PV_MP4_FF_DELETE(NULL, TrackDurationContainer, _pTrackDurationContainer);
   1681     }
   1682 
   1683     // Delete user data if present
   1684     if (_puserDataAtom != NULL)
   1685     {
   1686         PV_MP4_FF_DELETE(NULL, UserDataAtom, _puserDataAtom);
   1687     }
   1688 
   1689     if (_pFileTypeAtom != NULL)
   1690     {
   1691         PV_MP4_FF_DELETE(NULL, FileTypeAtom, _pFileTypeAtom);
   1692     }
   1693 
   1694     if (_movieFragmentFilePtr != NULL)
   1695     {
   1696         if (_movieFragmentFilePtr->IsOpen())
   1697         {
   1698             AtomUtils::CloseMP4File(_movieFragmentFilePtr);
   1699         }
   1700         oscl_free(_movieFragmentFilePtr);
   1701     }
   1702     if (_pID3Parser)
   1703     {
   1704         PV_MP4_FF_DELETE(null, PVID3ParCom, _pID3Parser);
   1705         _pID3Parser = NULL;
   1706     }
   1707 }
   1708 
   1709 
   1710 uint64 Mpeg4File::getMovieDuration() const
   1711 {
   1712     uint64 overallMovieDuration = 0;
   1713     uint32 id = 0;
   1714     if (_isMovieFragmentsPresent)
   1715     {
   1716         overallMovieDuration = _pmovieAtom->getMovieFragmentDuration();
   1717         if (Oscl_Int64_Utils::get_uint64_lower32(overallMovieDuration) != 0)
   1718         {
   1719             return overallMovieDuration;
   1720         }
   1721         else if (_parsing_mode == 0)
   1722         {
   1723             uint numTracks = _pmovieAtom->getNumTracks();
   1724             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
   1725             if (! trackList)
   1726                 return 0;   // malloc failure
   1727             _pmovieAtom->getTrackWholeIDList(trackList);
   1728             uint32 prevtrackDuration = 0, trackduration = 0;
   1729             for (uint32 i = 0; i < numTracks; i++)
   1730             {
   1731                 TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
   1732                 trackduration = pTrackDurationInfo->trackDuration;
   1733                 if (prevtrackDuration > trackduration)
   1734                 {
   1735                     trackduration = prevtrackDuration;
   1736                 }
   1737                 else
   1738                 {
   1739                     prevtrackDuration = trackduration;
   1740                     id = trackList[i];
   1741                 }
   1742             }
   1743             Oscl_Int64_Utils::set_uint64(overallMovieDuration, 0, trackduration);
   1744 
   1745             TrackAtom *trackAtom = NULL;
   1746             uint32 mediaTimeScale = 0xFFFFFFFE;
   1747 
   1748             if (_pmovieAtom != NULL)
   1749             {
   1750                 trackAtom = _pmovieAtom->getTrackForID(id);
   1751             }
   1752             if (trackAtom != NULL)
   1753             {
   1754                 mediaTimeScale = trackAtom->getMediaTimescale();
   1755                 if (mediaTimeScale == 0)
   1756                 {
   1757                     // unlikely : getMediaTimescale can return 0
   1758                     mediaTimeScale = 0xFFFFFFFE;
   1759                 }
   1760             }
   1761 
   1762             overallMovieDuration  = (overallMovieDuration / (uint64)mediaTimeScale) * (uint64)getMovieTimescale();
   1763             oscl_free(trackList);
   1764             return overallMovieDuration;
   1765         }
   1766         else
   1767         {
   1768             return overallMovieDuration;
   1769         }
   1770     }
   1771     else if (_pmovieAtom != NULL)
   1772     {
   1773         // Get the overall duration of the Mpeg-4 presentation
   1774         return _pmovieAtom->getDuration();
   1775     }
   1776     return 0;
   1777 }
   1778 
   1779 uint64 Mpeg4File::getMovieFragmentDuration() const
   1780 {
   1781     if (_pmovieAtom != NULL)
   1782     {
   1783         return _pmovieAtom->getMovieFragmentDuration();
   1784     }
   1785     else
   1786         return 0;
   1787 }
   1788 
   1789 uint32 Mpeg4File::getTimestampForSampleNumber(uint32 id, uint32 sampleNumber)
   1790 {
   1791     TrackAtom *trackAtom;
   1792 
   1793     if (_pmovieAtom != NULL)
   1794     {
   1795         trackAtom =  _pmovieAtom->getTrackForID(id);
   1796 
   1797         if (trackAtom != NULL)
   1798         {
   1799             return trackAtom->getTimestampForSampleNumber(sampleNumber);
   1800         }
   1801         else
   1802         {
   1803             return 0;
   1804         }
   1805     }
   1806     else
   1807     {
   1808         return 0;
   1809     }
   1810 }
   1811 
   1812 int32 Mpeg4File::getSampleSizeAt(uint32 id, int32 sampleNum)
   1813 {
   1814     TrackAtom *trackAtom;
   1815 
   1816     if (_pmovieAtom != NULL)
   1817     {
   1818         trackAtom =  _pmovieAtom->getTrackForID(id);
   1819 
   1820         if (trackAtom != NULL)
   1821         {
   1822             return (trackAtom->getSampleSizeAt(sampleNum));
   1823         }
   1824         else
   1825         {
   1826             return 0;
   1827         }
   1828     }
   1829     else
   1830     {
   1831         return 0;
   1832     }
   1833 }
   1834 
   1835 uint64 Mpeg4File::getTrackMediaDurationForMovie(uint32 id)
   1836 {
   1837     TrackAtom *trackAtom;
   1838     if (_pmovieAtom != NULL)
   1839     {
   1840         trackAtom = _pmovieAtom->getTrackForID(id);
   1841     }
   1842     else
   1843     {
   1844         return 0;
   1845     }
   1846     if (trackAtom != NULL)
   1847     {
   1848         return trackAtom->getTrackDuration();
   1849     }
   1850     else
   1851     {
   1852         return 0;
   1853     }
   1854 
   1855 }
   1856 // From TrackHeader
   1857 uint64 Mpeg4File::getTrackDuration(uint32 id)
   1858 {
   1859     TrackAtom *trackAtom;
   1860     if (_pmovieAtom != NULL)
   1861     {
   1862         trackAtom = _pmovieAtom->getTrackForID(id);
   1863     }
   1864     else
   1865     {
   1866         return 0;
   1867     }
   1868     if (_isMovieFragmentsPresent)
   1869     {
   1870         if (_parsing_mode)
   1871             return _pmovieAtom->getMovieFragmentDuration();
   1872         else
   1873         {
   1874             int32 numTracks = _pmovieAtom->getNumTracks();
   1875             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
   1876             if (!trackList)
   1877                 return 0;   // malloc failed
   1878             _pmovieAtom->getTrackWholeIDList(trackList);
   1879             uint64 trackduration = 0;
   1880             for (int32 i = 0; i < numTracks; i++)
   1881             {
   1882                 if (trackList[i] == id)
   1883                 {
   1884                     TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
   1885                     oscl_free(trackList);
   1886                     return trackduration = pTrackDurationInfo->trackDuration;
   1887                 }
   1888             }
   1889             oscl_free(trackList);
   1890         }
   1891     }
   1892     if (trackAtom != NULL)
   1893     {
   1894         return trackAtom->getTrackDuration();
   1895     }
   1896     else
   1897     {
   1898         return 0;
   1899     }
   1900 }
   1901 
   1902 // From TrackReference
   1903 uint32  Mpeg4File::trackDependsOn(uint32 id)
   1904 {
   1905     TrackAtom *trackAtom;
   1906     if (_pmovieAtom != NULL)
   1907     {
   1908         trackAtom = _pmovieAtom->getTrackForID(id);
   1909     }
   1910     else
   1911     {
   1912         return 0;
   1913     }
   1914 
   1915     if (trackAtom != NULL)
   1916     {
   1917         return trackAtom->dependsOn();
   1918     }
   1919     else
   1920     {
   1921         return 0;
   1922     }
   1923 
   1924 }
   1925 
   1926 // From MediaHeader
   1927 uint64 Mpeg4File::getTrackMediaDuration(uint32 id)
   1928 {
   1929     TrackAtom *trackAtom;
   1930     if (_pmovieAtom != NULL)
   1931     {
   1932         trackAtom = _pmovieAtom->getTrackForID(id);
   1933     }
   1934     else
   1935     {
   1936         return 0;
   1937     }
   1938     if (_isMovieFragmentsPresent)
   1939     {
   1940         if (_parsing_mode)
   1941             return _pmovieAtom->getMovieFragmentDuration();
   1942         else
   1943         {
   1944             int numTracks = _pmovieAtom->getNumTracks();
   1945             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
   1946             if (!trackList)
   1947                 return 0;   // malloc failed
   1948             _pmovieAtom->getTrackWholeIDList(trackList);
   1949             uint32 trackduration = 0;
   1950             for (int32 i = 0; i < numTracks; i++)
   1951             {
   1952                 if (trackList[i] == id)
   1953                 {
   1954                     TrackDurationInfo* pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
   1955                     oscl_free(trackList);
   1956                     return trackduration = pTrackDurationInfo->trackDuration;
   1957                 }
   1958             }
   1959             oscl_free(trackList);
   1960         }
   1961     }
   1962 
   1963     if (trackAtom != NULL)
   1964     {
   1965         return trackAtom->getMediaDuration();
   1966     }
   1967     else
   1968     {
   1969         return 0;
   1970     }
   1971 }
   1972 
   1973 uint32 Mpeg4File::getTrackMediaTimescale(uint32 id)
   1974 {
   1975     TrackAtom *trackAtom;
   1976     if (_pmovieAtom != NULL)
   1977     {
   1978         trackAtom = _pmovieAtom->getTrackForID(id);
   1979     }
   1980     else
   1981     {
   1982         // RETURN UNDEFINED VALUE
   1983         return (0xFFFFFFFF);
   1984     }
   1985 
   1986     if (trackAtom != NULL)
   1987     {
   1988         return trackAtom->getMediaTimescale();
   1989     }
   1990     else
   1991     {
   1992         // RETURN UNDEFINED VALUE
   1993         return (0xFFFFFFFF);
   1994     }
   1995 }
   1996 
   1997 uint16 Mpeg4File::getTrackLangCode(uint32 id)
   1998 {
   1999 
   2000     TrackAtom *trackAtom;
   2001     if (_pmovieAtom != NULL)
   2002     {
   2003         trackAtom = _pmovieAtom->getTrackForID(id);
   2004     }
   2005     else
   2006     {
   2007         // RETURN UNDEFINED VALUE
   2008         return (0xFFFF);
   2009     }
   2010 
   2011     if (trackAtom != NULL)
   2012     {
   2013         return trackAtom->getLanguageCode();
   2014     }
   2015     else
   2016     {
   2017         // RETURN UNDEFINED VALUE
   2018         return (0xFFFF);
   2019     }
   2020 }
   2021 
   2022 // From Handler
   2023 uint32 Mpeg4File::getTrackMediaType(uint32 id)
   2024 {
   2025     TrackAtom *trackAtom;
   2026     if (_pmovieAtom != NULL)
   2027     {
   2028         trackAtom = _pmovieAtom->getTrackForID(id);
   2029     }
   2030     else
   2031     {
   2032         // RETURN UNDEFINED VALUE
   2033         return (0xFFFFFFFF);
   2034     }
   2035 
   2036     if (trackAtom != NULL)
   2037     {
   2038         return trackAtom->getMediaType();
   2039     }
   2040     else
   2041     {
   2042         // RETURN UNDEFINED VALUE
   2043         return (0xFFFFFFFF);
   2044     }
   2045 
   2046 }
   2047 
   2048 // From SampleDescription
   2049 int32 Mpeg4File::getTrackNumSampleEntries(uint32 id)
   2050 {
   2051     TrackAtom *trackAtom;
   2052 
   2053     if (_pmovieAtom != NULL)
   2054     {
   2055         trackAtom = _pmovieAtom->getTrackForID(id);
   2056     }
   2057     else
   2058     {
   2059         return 0;
   2060     }
   2061 
   2062     if (trackAtom != NULL)
   2063     {
   2064         return trackAtom->getNumSampleEntries();
   2065     }
   2066     else
   2067     {
   2068         return 0;
   2069     }
   2070 }
   2071 
   2072 // From DecoderConfigDescriptor
   2073 DecoderSpecificInfo *Mpeg4File::getTrackDecoderSpecificInfo(uint32 id)
   2074 {
   2075     TrackAtom *trackAtom;
   2076     if (_pmovieAtom != NULL)
   2077     {
   2078         trackAtom = _pmovieAtom->getTrackForID(id);
   2079     }
   2080     else
   2081     {
   2082         return NULL;
   2083     }
   2084 
   2085     if (trackAtom != NULL)
   2086     {
   2087         return trackAtom->getDecoderSpecificInfo();
   2088     }
   2089     else
   2090     {
   2091         return NULL;
   2092     }
   2093 
   2094 }
   2095 
   2096 // From DecoderConfigDescriptor
   2097 DecoderSpecificInfo *
   2098 Mpeg4File::getTrackDecoderSpecificInfoAtSDI(uint32 trackID, uint32 index)
   2099 {
   2100     if (_pmovieAtom != NULL)
   2101     {
   2102         return (_pmovieAtom->getTrackDecoderSpecificInfoAtSDI(trackID, index));
   2103     }
   2104     else
   2105     {
   2106         return NULL;
   2107     }
   2108 }
   2109 
   2110 uint8 *Mpeg4File::getTrackDecoderSpecificInfoContent(uint32 id)
   2111 {
   2112     DecoderSpecificInfo *decoderSpecificInfo;
   2113     decoderSpecificInfo = getTrackDecoderSpecificInfo(id);
   2114 
   2115     if (decoderSpecificInfo != NULL)
   2116     {
   2117         return decoderSpecificInfo->getInfo();
   2118     }
   2119     else
   2120     {
   2121         return NULL;
   2122     }
   2123 }
   2124 
   2125 uint32 Mpeg4File::getTrackDecoderSpecificInfoSize(uint32 id)
   2126 {
   2127     DecoderSpecificInfo *decoderSpecificInfo;
   2128     decoderSpecificInfo = getTrackDecoderSpecificInfo(id);
   2129 
   2130     if (decoderSpecificInfo != NULL)
   2131     {
   2132         return decoderSpecificInfo->getInfoSize();
   2133     }
   2134     else
   2135     {
   2136         return 0;
   2137     }
   2138 }
   2139 
   2140 
   2141 void Mpeg4File::getTrackMIMEType(uint32 id, OSCL_String& aMimeType) // Based on OTI value
   2142 {
   2143     TrackAtom *trackAtom = NULL;
   2144 
   2145     if (_pmovieAtom != NULL)
   2146     {
   2147         trackAtom =  _pmovieAtom->getTrackForID(id);
   2148     }
   2149 
   2150     if (trackAtom != NULL)
   2151     {
   2152         trackAtom->getMIMEType(aMimeType);
   2153     }
   2154 }
   2155 
   2156 
   2157 int32 Mpeg4File::getTrackMaxBufferSizeDB(uint32 id)
   2158 {
   2159     TrackAtom *trackAtom;
   2160 
   2161     if (_pmovieAtom != NULL)
   2162     {
   2163         trackAtom =  _pmovieAtom->getTrackForID(id);
   2164     }
   2165     else
   2166     {
   2167         return 0;
   2168     }
   2169 
   2170     if (trackAtom != NULL)
   2171     {
   2172         return trackAtom->getMaxBufferSizeDB();
   2173     }
   2174     else
   2175     {
   2176         return 0;
   2177     }
   2178 }
   2179 
   2180 int32 Mpeg4File::getTrackAverageBitrate(uint32 id)
   2181 {
   2182     TrackAtom *trackAtom;
   2183 
   2184     if (_pmovieAtom != NULL)
   2185     {
   2186         trackAtom =  _pmovieAtom->getTrackForID(id);
   2187     }
   2188     else
   2189     {
   2190         return 0;
   2191     }
   2192 
   2193     if (trackAtom != NULL)
   2194     {
   2195         return trackAtom->getAverageBitrate();
   2196     }
   2197     else
   2198     {
   2199         return 0;
   2200     }
   2201 }
   2202 
   2203 // PASP Box
   2204 //Hspacing
   2205 uint32 Mpeg4File::getHspacing(uint32 id)
   2206 {
   2207 
   2208     TrackAtom *trackAtom;
   2209 
   2210     if (_pmovieAtom != NULL)
   2211     {
   2212         trackAtom =  _pmovieAtom->getTrackForID(id);
   2213     }
   2214     else
   2215     {
   2216         return 0;
   2217     }
   2218 
   2219     if (trackAtom != NULL)
   2220     {
   2221         return trackAtom->getHspacing();
   2222     }
   2223     else
   2224     {
   2225         return 0;
   2226     }
   2227 }
   2228 
   2229 //Vspacing
   2230 uint32 Mpeg4File::getVspacing(uint32 id)
   2231 {
   2232 
   2233     TrackAtom *trackAtom;
   2234 
   2235     if (_pmovieAtom != NULL)
   2236     {
   2237         trackAtom =  _pmovieAtom->getTrackForID(id);
   2238     }
   2239     else
   2240     {
   2241         return 0;
   2242     }
   2243 
   2244     if (trackAtom != NULL)
   2245     {
   2246         return trackAtom->getVspacing();
   2247     }
   2248     else
   2249     {
   2250         return 0;
   2251     }
   2252 }
   2253 
   2254 
   2255 uint32
   2256 Mpeg4File::getMovieTimescale() const
   2257 {
   2258     if (_pmovieAtom != NULL)
   2259     {
   2260         // Set the overall timescale of the Mpeg-4 presentation
   2261         return _pmovieAtom->getTimeScale();
   2262     }
   2263     else
   2264     {
   2265         // RETURN UNDEFINED VALUE
   2266         return (0xFFFFFFFF);
   2267     }
   2268 }
   2269 
   2270 /* ======================================================================== */
   2271 bool
   2272 Mpeg4File::IsMobileMP4()
   2273 {
   2274     bool oMMP4 = false;
   2275 
   2276     if (_pFileTypeAtom != NULL)
   2277     {
   2278         uint32 majorBrand = _pFileTypeAtom->getMajorBrand();
   2279 
   2280         if (majorBrand != MOBILE_MP4)
   2281         {
   2282             Oscl_Vector<uint32, OsclMemAllocator> *_compatibleBrand =
   2283                 _pFileTypeAtom->getCompatibleBrand();
   2284             if (_compatibleBrand != NULL)
   2285             {
   2286                 for (uint32 i = 0; i < _compatibleBrand->size(); i++)
   2287                 {
   2288                     uint32 brand = (*_compatibleBrand)[i];
   2289 
   2290                     if (brand == MOBILE_MP4)
   2291                     {
   2292                         oMMP4 = true;
   2293                     }
   2294                 }
   2295             }
   2296             else
   2297             {
   2298                 return false;
   2299             }
   2300         }
   2301         else
   2302         {
   2303             oMMP4 = true;
   2304         }
   2305     }
   2306     else
   2307     {
   2308         return false;
   2309     }
   2310 
   2311     if (oMMP4 == true)
   2312     {
   2313         if (!(_pmovieAtom->checkMMP4()))
   2314         {
   2315             return false;
   2316         }
   2317     }
   2318 
   2319     return (oMMP4);
   2320 }
   2321 
   2322 uint8
   2323 Mpeg4File::parseBufferAndGetNumAMRFrames(uint8* buffer, uint32 size)
   2324 {
   2325     uint32 inputBufferSize = size;
   2326     uint8* inputPtr = buffer;
   2327     uint8 numArmFrames = 0;
   2328 
   2329     if (((int32)(size) <= 0) ||
   2330             (buffer == NULL))
   2331     {
   2332         return 0;
   2333     }
   2334 
   2335     uint8 aFrameSizes[16] = {12, 13, 15, 17, 19, 20, 26, 31,
   2336                              5,  0,  0,  0,  0,  0,  0,  0
   2337                             };
   2338 
   2339     while (inputBufferSize > 0)
   2340     {
   2341         uint8 toc_byte = *(inputPtr);
   2342 
   2343         uint8 frame_type = (uint8)((toc_byte >> 3) & 0x0F);
   2344 
   2345         inputPtr        += 1;
   2346         inputBufferSize -= 1;
   2347 
   2348         if ((frame_type > 8) && (frame_type != 15))
   2349         {
   2350             return 0;
   2351         }
   2352 
   2353         numArmFrames++;
   2354         inputPtr        += aFrameSizes[(uint16)frame_type];
   2355         inputBufferSize -= aFrameSizes[(uint16)frame_type];
   2356     }
   2357     return (numArmFrames);
   2358 }
   2359 
   2360 
   2361 uint32 Mpeg4File::getTrackLevelOMA2DRMInfoSize(uint32 trackID)
   2362 {
   2363     TrackAtom *trackAtom;
   2364 
   2365     if (_pmovieAtom != NULL)
   2366     {
   2367         trackAtom =  _pmovieAtom->getTrackForID(trackID);
   2368     }
   2369     else
   2370     {
   2371         return 0;
   2372     }
   2373 
   2374     if (trackAtom != NULL)
   2375     {
   2376         return trackAtom->getTrackLevelOMA2DRMInfoSize();
   2377     }
   2378     else
   2379     {
   2380         return 0;
   2381     }
   2382 }
   2383 
   2384 uint8* Mpeg4File::getTrackLevelOMA2DRMInfo(uint32 trackID)
   2385 {
   2386     TrackAtom *trackAtom;
   2387 
   2388     if (_pmovieAtom != NULL)
   2389     {
   2390         trackAtom =  _pmovieAtom->getTrackForID(trackID);
   2391     }
   2392     else
   2393     {
   2394         return NULL;
   2395     }
   2396 
   2397     if (trackAtom != NULL)
   2398     {
   2399         return trackAtom->getTrackLevelOMA2DRMInfo();
   2400     }
   2401     else
   2402     {
   2403         return NULL;
   2404     }
   2405 }
   2406 
   2407 
   2408 MP4_ERROR_CODE
   2409 Mpeg4File::RequestReadCapacityNotification(PvmiDataStreamObserver& aObserver,
   2410         uint32 aFileOffset,
   2411         OsclAny* aContextData)
   2412 {
   2413     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::RequestReadCapacityNotification In Offset %d", aFileOffset));
   2414     uint32 capacity = 0;
   2415     if (_commonFilePtr != NULL)
   2416     {
   2417         uint32 currPos = (uint32)(AtomUtils::getCurrentFilePosition(_commonFilePtr));
   2418         if (aFileOffset > currPos)
   2419         {
   2420             capacity = (aFileOffset - currPos);
   2421             bool retVal =
   2422                 _commonFilePtr->_pvfile.RequestReadCapacityNotification(aObserver,
   2423                         capacity,
   2424                         aContextData);
   2425             if (retVal)
   2426             {
   2427                 return EVERYTHING_FINE;
   2428             }
   2429             else
   2430             {
   2431                 return DEFAULT_ERROR;
   2432             }
   2433         }
   2434         return SUFFICIENT_DATA_IN_FILE;
   2435     }
   2436     return DEFAULT_ERROR;
   2437 }
   2438 
   2439 
   2440 MP4_ERROR_CODE
   2441 Mpeg4File::GetCurrentFileSize(uint32& aFileSize)
   2442 {
   2443     aFileSize = 0;
   2444     if (AtomUtils::getCurrentFileSize(_commonFilePtr, aFileSize) == true)
   2445     {
   2446         return EVERYTHING_FINE;
   2447     }
   2448     if (_commonFilePtr == NULL && _fileSize != 0)
   2449     {
   2450         aFileSize = _fileSize;
   2451         return EVERYTHING_FINE;
   2452     }
   2453     return DEFAULT_ERROR;
   2454 }
   2455 
   2456 int32 Mpeg4File::getNextBundledAccessUnits(const uint32 trackID,
   2457         uint32 *n,
   2458         GAU    *pgau)
   2459 {
   2460     uint32 samplesTobeRead;
   2461     samplesTobeRead = *n;
   2462     uint32 totalSampleRead = 0;
   2463     if (getNumTracks() == 0)
   2464     {
   2465         return -1;
   2466     }
   2467 
   2468     if (_pmovieAtom != NULL)
   2469     {
   2470         int32 ret = _pmovieAtom->getNextBundledAccessUnits(trackID, n, pgau);
   2471         if (ret == END_OF_TRACK)
   2472         {
   2473             if (!_isMovieFragmentsPresent)
   2474                 return ret;
   2475 
   2476             totalSampleRead += *n;
   2477             bool oAllMoofExhausted = false;
   2478             bool oAllMoofParsed = false;
   2479 
   2480             if (_parsing_mode == 0)
   2481             {
   2482                 if (_pMovieFragmentAtomVec != NULL && _isMovieFragmentsPresent)
   2483                 {
   2484                     if (samplesTobeRead >= *n)
   2485                         *n = samplesTobeRead - *n;
   2486                 }
   2487                 else
   2488                     return ret;
   2489 
   2490                 int32 return1 = 0;
   2491                 while (_movieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
   2492                 {
   2493                     uint32 movieFragmentIdx = _movieFragmentIdx[trackID];
   2494                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
   2495                     if (pMovieFragmentAtom != NULL)
   2496                     {
   2497                         if ((uint32)pMovieFragmentAtom->getSequenceNumber() == _movieFragmentSeqIdx[trackID])
   2498                         {
   2499                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
   2500                             if (trackfragment != NULL)
   2501                             {
   2502                                 if (trackfragment->getTrackId() == trackID)
   2503                                 {
   2504                                     return1 = pMovieFragmentAtom->getNextBundledAccessUnits(trackID, n, totalSampleRead, pgau);
   2505                                     totalSampleRead += *n;
   2506                                     if (return1 != END_OF_TRACK)
   2507                                     {
   2508                                         *n = totalSampleRead;
   2509                                         return return1;
   2510                                     }
   2511                                     else
   2512                                     {
   2513                                         _movieFragmentSeqIdx[trackID]++;
   2514                                         if (samplesTobeRead >= *n)
   2515                                         {
   2516                                             samplesTobeRead = samplesTobeRead - *n;
   2517                                             *n = samplesTobeRead;
   2518                                         }
   2519                                     }
   2520                                 }
   2521                             }
   2522                         }
   2523                     }
   2524                     _movieFragmentIdx[trackID]++;
   2525                 }
   2526                 if (return1 == END_OF_TRACK)
   2527                 {
   2528                     *n = totalSampleRead;
   2529                     _movieFragmentIdx[trackID] = 0;
   2530                     return return1;
   2531                 }
   2532             }
   2533             else
   2534             {
   2535                 int32 return1 = 0;
   2536                 while (!oAllMoofExhausted)
   2537                 {
   2538                     if (oAllMoofParsed && (_pMovieFragmentAtomVec->size() < _movieFragmentIdx[trackID]))
   2539                     {
   2540                         oAllMoofExhausted = true;
   2541                         *n = 0;
   2542                         break;
   2543                     }
   2544 
   2545                     while (!oAllMoofParsed)
   2546                     {
   2547                         if (moofParsingCompleted)
   2548                         {
   2549                             uint32 moofIndex = 0;
   2550                             bool moofToBeParsed = false;
   2551                             if (_pMovieFragmentAtomVec->size() > _movieFragmentIdx[trackID])
   2552                             {
   2553                                 MovieFragmentAtom *pMovieFragmentAtom = NULL;
   2554                                 uint32 idx = _movieFragmentIdx[trackID];
   2555                                 pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[_movieFragmentIdx[trackID]];
   2556                                 if (pMovieFragmentAtom == NULL)
   2557                                 {
   2558                                     isResetPlayBackCalled = true;
   2559                                     moofToBeParsed = true;
   2560                                     moofIndex = _movieFragmentIdx[trackID];
   2561                                 }
   2562                                 else if (isResetPlayBackCalled)
   2563                                 {
   2564                                     isResetPlayBackCalled = false;
   2565 
   2566                                     // if moofs are already parsed, so go to the end of MOOF Vector.
   2567 
   2568                                     uint32 currFilePos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2569                                     if (currFilePos < _ptrMoofEnds)
   2570                                     {
   2571                                         uint32 offset = (_ptrMoofEnds - currFilePos);
   2572                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
   2573                                     }
   2574                                     else if (currFilePos == _ptrMoofEnds)
   2575                                     {
   2576                                         // no need to seek the File Pointer
   2577                                     }
   2578                                     else
   2579                                     {
   2580                                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   2581                                     }
   2582 
   2583                                     idx = currMoofNum - 1;
   2584                                     uint32 i = idx + 1;
   2585                                     while (i < _pMovieFragmentAtomVec->size())
   2586                                     {
   2587                                         idx++;
   2588                                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   2589                                         if (pMovieFragmentAtom == NULL)
   2590                                         {
   2591                                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx-1];
   2592                                             AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_start_offset);
   2593                                             uint32 atomType = UNKNOWN_ATOM;
   2594                                             uint32 atomSize = 0;
   2595                                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   2596                                             if (atomType == MOVIE_FRAGMENT_ATOM)
   2597                                             {
   2598                                                 atomSize -= DEFAULT_ATOM_SIZE;
   2599                                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   2600                                                 _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2601                                             }
   2602                                             isResetPlayBackCalled = true;
   2603                                             moofToBeParsed = true;
   2604                                             moofIndex = idx;
   2605                                             break;
   2606                                         }
   2607                                         pMovieFragmentAtom->resetPlayback();
   2608                                         i++;
   2609                                     }
   2610                                     uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
   2611                                     AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_start_offset);
   2612                                     uint32 atomType = UNKNOWN_ATOM;
   2613                                     uint32 atomSize = 0;
   2614                                     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   2615                                     if (atomType == MOVIE_FRAGMENT_ATOM)
   2616                                     {
   2617                                         atomSize -= DEFAULT_ATOM_SIZE;
   2618                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   2619                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2620                                     }
   2621                                 }
   2622                             }
   2623 
   2624                             uint32 fileSize = 0;
   2625                             AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   2626                             uint32 currFilePos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2627                             if (currFilePos < _ptrMoofEnds)
   2628                             {
   2629                                 uint32 offset = (_ptrMoofEnds - currFilePos);
   2630                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
   2631                             }
   2632                             else
   2633                             {
   2634                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   2635                             }
   2636                             uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2637                             int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
   2638 
   2639                             while (count > 0)
   2640                             {
   2641                                 uint32 atomType = UNKNOWN_ATOM;
   2642                                 uint32 atomSize = 0;
   2643                                 uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2644                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   2645                                 if ((currPos + atomSize) > fileSize)
   2646                                 {
   2647                                     AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
   2648                                     if (_movieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
   2649                                     {
   2650                                         // dont report insufficient data as we still have a moof/moofs to
   2651                                         // retrieve data. So just go and retrieve the data.
   2652                                         break;
   2653                                     }
   2654                                     else
   2655                                     {
   2656                                         // We have run out of MOOF atoms so report insufficient data.
   2657                                         return  INSUFFICIENT_DATA;
   2658                                     }
   2659                                 }
   2660 
   2661                                 if (atomType == MOVIE_FRAGMENT_ATOM)
   2662                                 {
   2663                                     uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2664                                     moofStartOffset -= DEFAULT_ATOM_SIZE;
   2665                                     parseMoofCompletely = false;
   2666                                     moofSize = atomSize;
   2667                                     moofType = atomType;
   2668                                     moofCount = count;
   2669                                     _ptrMoofEnds = moofStartOffset + atomSize;
   2670 
   2671                                     PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
   2672                                     moofSize = atomSize;
   2673                                     moofPtrPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2674 
   2675                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   2676                                     if (moofToBeParsed)
   2677                                     {
   2678                                         (*_pMovieFragmentAtomVec)[moofIndex] = _pMovieFragmentAtom;
   2679                                         (*_pMoofOffsetVec)[moofIndex] = moofStartOffset;
   2680                                     }
   2681                                     else
   2682                                     {
   2683                                         _pMoofOffsetVec->push_back(moofStartOffset);
   2684                                         _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
   2685                                     }
   2686 
   2687                                     if (moofParsingCompleted)
   2688                                     {
   2689                                         if (!_pMovieFragmentAtom->MP4Success())
   2690                                         {
   2691                                             _success = false;
   2692                                             _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   2693                                             oAllMoofExhausted = true;
   2694                                             break;
   2695                                         }
   2696                                         _pMovieFragmentAtom->setParent(this);
   2697                                         count -= _pMovieFragmentAtom->getSize();
   2698 
   2699                                         break;
   2700                                     }
   2701 
   2702                                     break;
   2703                                 }
   2704                                 else if (atomType == MEDIA_DATA_ATOM)
   2705                                 {
   2706                                     if (atomSize == 1)
   2707                                     {
   2708                                         uint64 largeSize = 0;
   2709                                         AtomUtils::read64(_movieFragmentFilePtr, largeSize);
   2710                                         uint32 size =
   2711                                             Oscl_Int64_Utils::get_uint64_lower32(largeSize);
   2712                                         count -= size;
   2713                                         size -= 8; //for large size
   2714                                         size -= DEFAULT_ATOM_SIZE;
   2715                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
   2716                                     }
   2717                                     else
   2718                                     {
   2719                                         if (atomSize < DEFAULT_ATOM_SIZE)
   2720                                         {
   2721                                             _success = false;
   2722                                             _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
   2723                                             oAllMoofExhausted = true;
   2724                                             break;
   2725                                         }
   2726                                         if (count < (int32)atomSize)
   2727                                         {
   2728                                             _success = false;
   2729                                             _mp4ErrorCode = INSUFFICIENT_DATA;
   2730                                             ret = _mp4ErrorCode;
   2731                                             oAllMoofExhausted = true;
   2732                                             AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
   2733                                             break;
   2734                                         }
   2735                                         count -= atomSize;
   2736                                         atomSize -= DEFAULT_ATOM_SIZE;
   2737                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   2738                                     }
   2739                                 }
   2740 
   2741                                 else
   2742                                 {
   2743                                     if (count > 0)
   2744                                     {
   2745                                         count -= atomSize;
   2746                                         atomSize -= DEFAULT_ATOM_SIZE;
   2747                                         AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   2748                                     }
   2749 
   2750                                 }
   2751                             }
   2752                             if (count <= 0)
   2753                             {
   2754                                 oAllMoofParsed = true;
   2755                                 break;
   2756                             }
   2757                             break;
   2758                         }
   2759                         else if (!moofParsingCompleted)
   2760                         {
   2761                             if (currMoofNum != (uint32) _pMovieFragmentAtom->getSequenceNumber())
   2762                             {
   2763                                 uint32 size = _pMovieFragmentAtomVec->size();
   2764                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[size - 1];
   2765                             }
   2766                             uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2767                             if (currPos > moofPtrPos)
   2768                             {
   2769                                 uint32 offset = (currPos - moofPtrPos);
   2770                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, -((int32)offset));
   2771                             }
   2772                             else
   2773                             {
   2774                                 uint32 offset = (moofPtrPos - currPos);
   2775                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
   2776                             }
   2777 
   2778                             _pMovieFragmentAtom->ParseMoofAtom(_movieFragmentFilePtr, moofSize, moofType, _pTrackDurationContainer, _pTrackExtendsAtomVec, moofParsingCompleted, countOfTrunsParsed);
   2779                             moofPtrPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   2780                             if (moofParsingCompleted)
   2781                             {
   2782                                 if (!_pMovieFragmentAtom->MP4Success())
   2783                                 {
   2784                                     _success = false;
   2785                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   2786                                     oAllMoofExhausted = true;
   2787                                     break;
   2788                                 }
   2789                                 _pMovieFragmentAtom->setParent(this);
   2790                                 moofCount -= _pMovieFragmentAtom->getSize();
   2791                             }
   2792 
   2793                             if (currPos > moofPtrPos)
   2794                             {
   2795                                 uint32 offset = (currPos - moofPtrPos);
   2796                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, offset);
   2797                             }
   2798                             else
   2799                             {
   2800                                 uint32 offset = (moofPtrPos - currPos);
   2801                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, -((int32)offset));
   2802                             }
   2803 
   2804                             if (moofCount <= 0)
   2805                             {
   2806                                 oAllMoofParsed = true;
   2807                                 break;
   2808                             }
   2809                             break;
   2810                         }
   2811                     }
   2812 
   2813                     if (return1 != END_OF_TRACK)
   2814                     {
   2815                         if (samplesTobeRead >= *n)
   2816                             *n = samplesTobeRead - *n;
   2817                     }
   2818 
   2819                     uint32 movieFragmentIdx = _movieFragmentIdx[trackID];
   2820                     MovieFragmentAtom *pMovieFragmentAtom = NULL;
   2821 
   2822                     if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
   2823                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
   2824 
   2825                     if (pMovieFragmentAtom != NULL)
   2826                     {
   2827                         uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
   2828                         if (seqNum == _movieFragmentSeqIdx[trackID])
   2829                         {
   2830                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
   2831                             if (trackfragment != NULL)
   2832                             {
   2833                                 if (trackfragment->getTrackId() == trackID)
   2834                                 {
   2835                                     return1 = pMovieFragmentAtom->getNextBundledAccessUnits(trackID, n, totalSampleRead, pgau);
   2836                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::getNextBundledAccessUnits return %d", return1));
   2837                                     totalSampleRead += *n;
   2838                                     if (return1 != END_OF_TRACK)
   2839                                     {
   2840                                         *n = totalSampleRead;
   2841                                         return return1;
   2842                                     }
   2843                                     else
   2844                                     {
   2845                                         _movieFragmentSeqIdx[trackID]++;
   2846                                         if (samplesTobeRead >= *n)
   2847                                         {
   2848                                             samplesTobeRead = samplesTobeRead - *n;
   2849                                             *n = samplesTobeRead;
   2850                                             if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
   2851                                             {
   2852                                                 _movieFragmentIdx[trackID]++;
   2853                                             }
   2854                                         }
   2855                                     }
   2856                                 }
   2857                             }
   2858                             else
   2859                             {
   2860                                 uint32 movieFragmentIdx2 = _movieFragmentIdx[trackID];
   2861 
   2862                                 if (oAllMoofParsed)
   2863                                 {
   2864                                     // look for all moofs
   2865                                     if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
   2866                                     {
   2867                                         _movieFragmentIdx[trackID]++;
   2868                                         _movieFragmentSeqIdx[trackID]++;
   2869                                     }
   2870                                     else
   2871                                     {
   2872                                         return END_OF_TRACK;
   2873                                     }
   2874 
   2875                                 }
   2876                                 else
   2877                                 {
   2878                                     if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
   2879                                     {
   2880                                         if ((movieFragmentIdx2 == (_pMovieFragmentAtomVec->size() - 1)) && moofParsingCompleted)
   2881                                         {
   2882                                             _movieFragmentIdx[trackID]++;
   2883                                             _movieFragmentSeqIdx[trackID]++;
   2884                                         }
   2885                                         else if (movieFragmentIdx2 < (_pMovieFragmentAtomVec->size() - 1))
   2886                                         {
   2887                                             _movieFragmentIdx[trackID]++;
   2888                                             _movieFragmentSeqIdx[trackID]++;
   2889                                             *n = 0;
   2890                                             return NO_SAMPLE_IN_CURRENT_MOOF;
   2891                                         }
   2892                                     }
   2893                                 }
   2894                             }
   2895                         }
   2896                         else
   2897                         {
   2898                             uint32 movieFragmentIdx2 = _movieFragmentIdx[trackID];
   2899 
   2900                             if (oAllMoofParsed)
   2901                             {
   2902                                 // look for all moofs
   2903                                 if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
   2904                                 {
   2905                                     _movieFragmentIdx[trackID]++;
   2906                                     _movieFragmentSeqIdx[trackID]++;
   2907                                 }
   2908                                 else
   2909                                 {
   2910                                     return END_OF_TRACK;
   2911                                 }
   2912 
   2913                             }
   2914                             else
   2915                             {
   2916                                 if (movieFragmentIdx2 < _pMovieFragmentAtomVec->size())
   2917                                 {
   2918                                     if ((movieFragmentIdx2 == (_pMovieFragmentAtomVec->size() - 1)) && moofParsingCompleted)
   2919                                     {
   2920                                         _movieFragmentIdx[trackID]++;
   2921                                         _movieFragmentSeqIdx[trackID]++;
   2922                                     }
   2923                                     else if (movieFragmentIdx2 < (_pMovieFragmentAtomVec->size() - 1))
   2924                                     {
   2925                                         _movieFragmentIdx[trackID]++;
   2926                                         _movieFragmentSeqIdx[trackID]++;
   2927                                         *n = 0;
   2928                                         return NO_SAMPLE_IN_CURRENT_MOOF;
   2929                                     }
   2930                                 }
   2931                             }
   2932                         }
   2933                     }
   2934                     else
   2935                     {
   2936                         if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
   2937                         {
   2938                             _movieFragmentIdx[trackID]++;
   2939                             _movieFragmentSeqIdx[trackID]++;
   2940                         }
   2941                         else if (oAllMoofParsed)
   2942                         {
   2943                             _movieFragmentIdx[trackID]++;
   2944                             _movieFragmentSeqIdx[trackID]++;
   2945                         }
   2946 
   2947                     }
   2948                 }
   2949             }
   2950         }
   2951         return ret;
   2952     }
   2953     return -1;
   2954 }
   2955 
   2956 MovieFragmentAtom * Mpeg4File::getMovieFragmentForTrackId(uint32 id)
   2957 {
   2958     MovieFragmentAtom *movieFragmentAtom = NULL;
   2959     uint32 i = 0;
   2960 
   2961     if (_pMovieFragmentAtomVec == NULL)
   2962         return NULL;
   2963 
   2964     while (i < _pMovieFragmentAtomVec->size())
   2965     {
   2966         movieFragmentAtom = (*_pMovieFragmentAtomVec)[i];
   2967         if (movieFragmentAtom != NULL)
   2968         {
   2969             TrackFragmentAtom *trackfragment = movieFragmentAtom->getTrackFragmentforID(id);
   2970             if (trackfragment != NULL)
   2971             {
   2972                 if (trackfragment->getTrackId() == id)
   2973                 {
   2974                     return movieFragmentAtom;
   2975                 }
   2976             }
   2977         }
   2978         i++;
   2979     }
   2980     return NULL;
   2981 }
   2982 
   2983 void Mpeg4File::populateTrackDurationVec()
   2984 {
   2985     uint32 trackDuration = 0;
   2986     if (_pmovieAtom != NULL)
   2987     {
   2988         uint32 ids[256];
   2989         uint32 size = 256;
   2990         _pmovieAtom->getTrackIDList(ids, size);
   2991         int32 numtracks = _pmovieAtom->getNumTracks();
   2992         PV_MP4_FF_NEW(fp->auditCB, TrackDurationContainer, (), _pTrackDurationContainer);
   2993         PV_MP4_FF_NEW(fp->auditCB, trackDurationInfoVecType, (), _pTrackDurationContainer->_pTrackdurationInfoVec);
   2994         for (int32 i = 0; i < numtracks; i++)
   2995         {
   2996             uint32 trackID = ids[i];
   2997             TrackDurationInfo *trackinfo = NULL;
   2998             trackDuration = Oscl_Int64_Utils::get_uint64_lower32(_pmovieAtom->getTrackMediaDuration(trackID));
   2999             PV_MP4_FF_NEW(fp->auditCB, TrackDurationInfo, (trackDuration, trackID), trackinfo);
   3000             (*_pTrackDurationContainer->_pTrackdurationInfoVec).push_back(trackinfo);
   3001             _movieFragmentIdx[trackID] = 0;
   3002             _peekMovieFragmentIdx[trackID] = 0;
   3003             _movieFragmentSeqIdx[trackID] = 1;
   3004             _peekMovieFragmentSeqIdx[trackID] = 1;
   3005         }
   3006     }
   3007 }
   3008 
   3009 uint32 Mpeg4File::GetByteOffsetToStartOfAudioFrames()
   3010 {
   3011     return _pID3Parser->GetByteOffsetToStartOfAudioFrames();
   3012 
   3013 }
   3014 
   3015 void Mpeg4File::GetID3MetaData(PvmiKvpSharedPtrVector &id3Frames)
   3016 {
   3017     _pID3Parser->GetID3Frames(id3Frames);
   3018 
   3019 }
   3020 
   3021 bool Mpeg4File::IsID3Frame(const OSCL_String& frameType)
   3022 {
   3023     return _pID3Parser->IsID3FrameAvailable(frameType);
   3024 }
   3025 
   3026 void Mpeg4File::GetID3Frame(const OSCL_String& aFrameType, PvmiKvpSharedPtrVector& aFrame)
   3027 {
   3028     _pID3Parser->GetID3Frame(aFrameType, aFrame);
   3029 }
   3030 
   3031 PVID3Version Mpeg4File::GetID3Version() const
   3032 {
   3033     return _pID3Parser->GetID3Version();
   3034 }
   3035 
   3036 void Mpeg4File::parseID3Header(MP4_FF_FILE *aFile)
   3037 {
   3038     int32 curpos = AtomUtils::getCurrentFilePosition(aFile);
   3039     AtomUtils::seekFromStart(aFile, 0);
   3040     _pID3Parser->ParseID3Tag(&aFile->_pvfile);
   3041     AtomUtils::seekFromStart(aFile, curpos);
   3042 }
   3043 
   3044 uint32 Mpeg4File::getContentType()
   3045 {
   3046     PVContentTypeAtom *pAtom = NULL;
   3047 
   3048     if (_puserDataAtom != NULL)
   3049     {
   3050         pAtom =
   3051             (PVContentTypeAtom*) _puserDataAtom->getAtomOfType(PV_CONTENT_TYPE_ATOM);
   3052 
   3053         if (pAtom != NULL)
   3054         {
   3055             return pAtom->getContentType();
   3056         }
   3057         else
   3058         {
   3059             if (_oPVContent)
   3060             {
   3061                 //Old PV Content, that doesnt have this atom
   3062                 //All such content is non-interleaved, with meta data
   3063                 //towards the very end
   3064                 return (DEFAULT_AUTHORING_MODE);
   3065             }
   3066         }
   3067     }
   3068 
   3069     //Third party content
   3070     return (0xFFFFFFFF);
   3071 }
   3072 
   3073 
   3074 MP4_ERROR_CODE Mpeg4File::getKeyMediaSampleNumAt(uint32 aTrackId,
   3075         uint32 aKeySampleNum,
   3076         GAU    *pgau)
   3077 {
   3078     if (_pmovieAtom == NULL)
   3079     {
   3080         return READ_SAMPLE_TABLE_ATOM_FAILED;
   3081     }
   3082     MP4_ERROR_CODE ret = _pmovieAtom->getKeyMediaSampleNumAt(aTrackId, aKeySampleNum, pgau);
   3083     if (ret == READ_FAILED)
   3084     {
   3085         uint32 totalSampleRead = 0;
   3086         if (_isMovieFragmentsPresent)
   3087         {
   3088             uint32 n = 1;
   3089             uint32 movieFragmentIdx = _movieFragmentIdx[aTrackId];
   3090             MovieFragmentAtom *pMovieFragmentAtom = NULL;
   3091 
   3092             if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
   3093                 pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
   3094 
   3095             if (pMovieFragmentAtom != NULL)
   3096             {
   3097                 uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
   3098                 if (seqNum == _movieFragmentSeqIdx[aTrackId])
   3099                 {
   3100                     TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(aTrackId);
   3101                     if (trackfragment != NULL)
   3102                     {
   3103                         if (trackfragment->getTrackId() == aTrackId)
   3104                         {
   3105                             return (MP4_ERROR_CODE)pMovieFragmentAtom->getNextBundledAccessUnits(aTrackId, &n, totalSampleRead, pgau);
   3106                         }
   3107                     }
   3108                 }
   3109             }
   3110         }
   3111         return READ_FAILED;
   3112     }
   3113     else
   3114     {
   3115         return ret;
   3116     }
   3117 }
   3118 
   3119 
   3120 
   3121 int32 Mpeg4File::getOffsetByTime(uint32 id, uint32 ts, int32* sampleFileOffset , uint32 jitterbuffertimeinmillisec)
   3122 {
   3123     int32 ret =  DEFAULT_ERROR;
   3124     uint32 sigmaAtomSize = 0;
   3125     if (_pmovieAtom != NULL)
   3126     {
   3127         ret = _pmovieAtom->getOffsetByTime(id, ts, sampleFileOffset);
   3128         if (ret == DEFAULT_ERROR || ret == LAST_SAMPLE_IN_MOOV)
   3129         {
   3130             if (_isMovieFragmentsPresent)
   3131             {
   3132                 uint32 sigmaTrafDuration = 0;
   3133 
   3134                 for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
   3135                 {
   3136                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   3137                     if (pMovieFragmentAtom != NULL)
   3138                     {
   3139                         uint32 currTrafDuration = pMovieFragmentAtom->getCurrentTrafDuration(id);
   3140                         if (currTrafDuration >= ts)
   3141                         {
   3142                             pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   3143                             return pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
   3144                         }
   3145                         sigmaTrafDuration += currTrafDuration;
   3146                     }
   3147                 }
   3148 
   3149                 if (_parsing_mode == 1)
   3150                 {
   3151                     if (moofParsingCompleted)
   3152                     {
   3153                         // do nothing
   3154                     }
   3155                     else
   3156                     {
   3157                         if ((uint32)_pMovieFragmentAtom->getSequenceNumber() == _movieFragmentSeqIdx[id])
   3158                         {
   3159                             AtomUtils::seekFromStart(_movieFragmentFilePtr, moofPtrPos);
   3160 
   3161                             while (!moofParsingCompleted)
   3162                             {
   3163                                 _pMovieFragmentAtom->ParseMoofAtom(_movieFragmentFilePtr, moofSize, moofType, _pTrackDurationContainer, _pTrackExtendsAtomVec, moofParsingCompleted, countOfTrunsParsed);
   3164                             }
   3165 
   3166                             if (moofParsingCompleted)
   3167                             {
   3168                                 if (!_pMovieFragmentAtom->MP4Success())
   3169                                 {
   3170                                     _success = false;
   3171                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   3172                                 }
   3173                                 _pMovieFragmentAtom->setParent(this);
   3174                                 moofSize = _pMovieFragmentAtom->getSize();
   3175                                 moofCount -= _pMovieFragmentAtom->getSize();
   3176                             }
   3177 
   3178                             uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(id);
   3179 
   3180                             if (currTrafDuration >= ts)
   3181                             {
   3182                                 ret = _pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
   3183                                 if (*sampleFileOffset == 0)
   3184                                 {
   3185                                     // do nothing, continue parsing
   3186                                 }
   3187                                 else
   3188                                 {
   3189                                     return ret;
   3190                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: ret Sample Offset=> Sample Offset= %d ret %d********@@@@@@@@@@@@@@@@", *sampleFileOffset, ret));
   3191                                 }
   3192                             }
   3193                             sigmaTrafDuration += currTrafDuration;
   3194                         }
   3195                         else
   3196                         {
   3197                             // This condition will only happen when the MovieFragmentAtomVec size is
   3198                             // greater than 1.
   3199                             uint32 i = _pMovieFragmentAtomVec->size();
   3200                             _ptrMoofEnds = (*_pMoofOffsetVec)[i-2] + (*_pMovieFragmentAtomVec)[i-2]->getSize();
   3201                             _pMoofOffsetVec->pop_back();
   3202                             _pMovieFragmentAtomVec->pop_back();
   3203                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3204                             parseMoofCompletely = true;
   3205                             moofParsingCompleted = true;
   3206                             moofSize = 0;
   3207                             moofType = UNKNOWN_ATOM;
   3208                             moofCount = 0;
   3209                             moofPtrPos = 0;
   3210                         }
   3211                     }
   3212 
   3213                     uint32 fileSize = 0;
   3214                     uint32 currfptr = 0;
   3215 
   3216                     AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   3217                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime::FileSize %d Track ID %d ********@@@@@@@@@@@@@@@@", fileSize, id));
   3218 
   3219                     AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   3220                     uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3221                     int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
   3222                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: TS= %d ********@@@@@@@@@@@@@@@@, count=%d, filePointer=%d", ts, count, filePointer));
   3223 
   3224                     while (count > 0)
   3225                     {
   3226                         uint32 atomType = UNKNOWN_ATOM;
   3227                         uint32 atomSize = 0;
   3228                         AtomUtils::Flush(_movieFragmentFilePtr);
   3229                         AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   3230                         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: count=%d, AtomSize=%d, atomtype=%d", count, atomSize, atomType));
   3231                         if (atomSize < DEFAULT_ATOM_SIZE)
   3232                         {
   3233 
   3234                             ret = DEFAULT_ERROR;
   3235                             break;
   3236                         }
   3237                         sigmaAtomSize += atomSize;
   3238                         if (atomType == MOVIE_FRAGMENT_ATOM)
   3239                         {
   3240                             uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3241                             moofStartOffset -= DEFAULT_ATOM_SIZE;
   3242                             PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: MovieFragmentAtom moofStartOffset=%d", moofStartOffset));
   3243 
   3244                             moofSize = atomSize;
   3245 
   3246                             if ((moofStartOffset + atomSize) > fileSize)
   3247                             {
   3248                                 uint32 timeScale = _pmovieAtom->getTrackMediaTimescale(id);
   3249                                 if ((timeScale == 0) || (timeScale == 0xFFFFFFFF))
   3250                                 {
   3251                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Invalid timeScale %d for Id %d", timeScale, id));
   3252                                     return DEFAULT_ERROR;
   3253                                 }
   3254 
   3255                                 uint32 trackPlayedSoFarInSec = ts / timeScale - jitterbuffertimeinmillisec / 1000;
   3256                                 uint32 rateOfDataUsageKbPerSec = 0;
   3257                                 if (trackPlayedSoFarInSec != 0)
   3258                                 {
   3259                                     rateOfDataUsageKbPerSec = fileSize / trackPlayedSoFarInSec;
   3260                                 }
   3261                                 // estimate data for PVMF_MP4FFPARSER_PSEUDO_STREAMING_DURATION_IN_SEC
   3262                                 uint32 dataNeededAhead = (rateOfDataUsageKbPerSec * jitterbuffertimeinmillisec) / 1000;
   3263 
   3264                                 *sampleFileOffset = moofStartOffset + atomSize + DEFAULT_ATOM_SIZE + dataNeededAhead;
   3265                                 PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Insufficient data ot get Sample Offset= %d ********@@@@@@@@@@@@@@@@", *sampleFileOffset));
   3266                                 ret =  EVERYTHING_FINE;
   3267                                 break;
   3268                             }
   3269 
   3270                             _pMoofOffsetVec->push_back(moofStartOffset);
   3271                             parseMoofCompletely = true;
   3272 
   3273                             PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
   3274 
   3275                             if (!_pMovieFragmentAtom->MP4Success())
   3276                             {
   3277 
   3278                                 _success = false;
   3279                                 _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   3280                                 break;
   3281                             }
   3282                             count -= _pMovieFragmentAtom->getSize();
   3283                             _pMovieFragmentAtom->setParent(this);
   3284 
   3285                             _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
   3286                             _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3287 
   3288                             uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(id);
   3289 
   3290                             if (currTrafDuration >= ts)
   3291                             {
   3292                                 ret = _pMovieFragmentAtom->getOffsetByTime(id, ts, sampleFileOffset);
   3293                                 if (*sampleFileOffset == 0)
   3294                                 {
   3295                                     // do nothing, continue parsing
   3296                                 }
   3297                                 else
   3298                                 {
   3299                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: ret Sample Offset=> Sample Offset= %d ret %d********@@@@@@@@@@@@@@@@", *sampleFileOffset, ret));
   3300                                     break;
   3301                                 }
   3302                             }
   3303                             sigmaTrafDuration += currTrafDuration;
   3304                         }
   3305                         else if (atomType == MEDIA_DATA_ATOM)
   3306                         {
   3307 
   3308                             if (atomSize == 1)
   3309                             {
   3310                                 uint64 largeSize = 0;
   3311                                 AtomUtils::read64(_movieFragmentFilePtr, largeSize);
   3312                                 uint32 size =
   3313                                     Oscl_Int64_Utils::get_uint64_lower32(largeSize);
   3314                                 count -= size;
   3315                                 size -= 8; //for large size
   3316                                 size -= DEFAULT_ATOM_SIZE;
   3317                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
   3318                             }
   3319                             else
   3320                             {
   3321                                 currfptr = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3322                                 if ((currfptr + atomSize) > fileSize)
   3323                                 {
   3324                                     uint32 timeScale = _pmovieAtom->getTrackMediaTimescale(id);
   3325                                     if ((timeScale == 0) || (timeScale == 0xFFFFFFFF))
   3326                                     {
   3327                                         PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Invalid timeScale %d for Id %d", timeScale, id));
   3328                                         return DEFAULT_ERROR;
   3329                                     }
   3330                                     uint32 trackPlayedSoFarInSec = ts / timeScale - jitterbuffertimeinmillisec / 1000;
   3331                                     uint32 rateOfDataUsageKbPerSec = 0;
   3332                                     if (trackPlayedSoFarInSec != 0)
   3333                                     {
   3334                                         rateOfDataUsageKbPerSec = fileSize / trackPlayedSoFarInSec;
   3335                                     }
   3336 
   3337                                     // estimate data for PVMF_MP4FFPARSER_PSEUDO_STREAMING_DURATION_IN_SEC
   3338                                     uint32 dataNeededAhead = (rateOfDataUsageKbPerSec * jitterbuffertimeinmillisec) / 1000;
   3339                                     *sampleFileOffset = currfptr + atomSize + moofSize + dataNeededAhead;
   3340                                     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "getOffsetByTime:: Insufficient data ot get Sample Offset= %d ********@@@@@@@@@@@@@@@@", *sampleFileOffset));
   3341                                     ret = EVERYTHING_FINE;
   3342                                     break;
   3343 
   3344                                 }
   3345                                 count -= atomSize;
   3346                                 atomSize -= DEFAULT_ATOM_SIZE;
   3347                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3348                             }
   3349                         }
   3350 
   3351                         else
   3352                         {
   3353                             if (count > 0)
   3354                             {
   3355                                 count -= atomSize;
   3356                                 atomSize -= DEFAULT_ATOM_SIZE;
   3357                                 AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3358                             }
   3359                         }
   3360                     }
   3361                     if (sigmaTrafDuration == 0)
   3362                     {
   3363                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   3364                         *sampleFileOffset = fileSize + 1000;
   3365 
   3366                         ret = EVERYTHING_FINE;
   3367                     }
   3368                 }
   3369             }
   3370             else if (ret == LAST_SAMPLE_IN_MOOV)
   3371             {
   3372                 ret = EVERYTHING_FINE;
   3373             }
   3374 
   3375         }
   3376 
   3377         return ret;
   3378     }
   3379     else
   3380     {
   3381 
   3382         return ret;
   3383     }
   3384 }
   3385 
   3386 int32 Mpeg4File::getTimestampForRandomAccessPoints(uint32 id, uint32 *num, uint32 *tsBuf, uint32* numBuf, uint32 *offsetBuf)
   3387 {
   3388     if (_pmovieAtom != NULL)
   3389     {
   3390         uint32 requestedSamples = *num, delta = 0, returnedSampleFromMoov = 0;
   3391         uint32 ret =  _pmovieAtom->getTimestampForRandomAccessPoints(id, num, tsBuf, numBuf, offsetBuf);
   3392         if (ret == 1)
   3393         {
   3394             returnedSampleFromMoov = *num;
   3395             if (requestedSamples != 0)
   3396             {
   3397                 if (requestedSamples == returnedSampleFromMoov)
   3398                     return ret;
   3399 
   3400                 if (requestedSamples > returnedSampleFromMoov)
   3401                 {
   3402                     delta = requestedSamples - returnedSampleFromMoov;
   3403                 }
   3404             }
   3405 
   3406         }
   3407         else
   3408             delta = *num;
   3409 
   3410         if (_isMovieFragmentsPresent)
   3411         {
   3412             if (_pMovieFragmentRandomAccessAtomVec != NULL)
   3413             { // Only one mfra possible in a clip so this loop will run only once
   3414                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   3415                 {
   3416                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   3417                     ret = pMovieFragmentRandomAccessAtom->getTimestampForRandomAccessPoints(id, &delta, tsBuf, numBuf, offsetBuf, returnedSampleFromMoov);
   3418                     *num = delta;
   3419                     return ret;
   3420                 }
   3421 
   3422             }
   3423         }
   3424         return ret;
   3425     }
   3426     return 0;
   3427 }
   3428 
   3429 int32 Mpeg4File::getTimestampForRandomAccessPointsBeforeAfter(uint32 id, uint32 ts, uint32 *tsBuf, uint32* numBuf,
   3430         uint32& numsamplestoget,
   3431         uint32 howManyKeySamples)
   3432 {
   3433     if (_pmovieAtom != NULL)
   3434     {
   3435         int32 ret = _pmovieAtom->getTimestampForRandomAccessPointsBeforeAfter(id, ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples);
   3436         if (ret != 1)
   3437         {
   3438             if (_isMovieFragmentsPresent)
   3439             {
   3440                 if (_pMovieFragmentRandomAccessAtomVec != NULL)
   3441                 { // Only one mfra possible in a clip so this loop will run only once
   3442                     for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   3443                     {
   3444                         MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   3445                         ret = pMovieFragmentRandomAccessAtom->getTimestampForRandomAccessPointsBeforeAfter(id, ts, tsBuf, numBuf, numsamplestoget, howManyKeySamples);
   3446                         return ret;
   3447                     }
   3448 
   3449                 }
   3450             }
   3451         }
   3452         return ret;
   3453 
   3454     }
   3455     else
   3456     {
   3457         return 0;
   3458     }
   3459 }
   3460 
   3461 
   3462 
   3463 void Mpeg4File::resetAllMovieFragments()
   3464 {
   3465     uint32 trackDuration = 0;
   3466     if (_isMovieFragmentsPresent)
   3467     {
   3468         if (_pMovieFragmentAtomVec != NULL)
   3469         {
   3470             int numTracks = _pmovieAtom->getNumTracks();
   3471             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
   3472             if (!trackList)
   3473                 return;       // malloc failed
   3474 
   3475             _pmovieAtom->getTrackWholeIDList(trackList);
   3476             for (int32 i = 0; i < numTracks; i++)
   3477             {
   3478                 uint32 trackID = trackList[i];
   3479                 _movieFragmentIdx[trackID] = 0;
   3480                 _peekMovieFragmentIdx[trackID] = 0;
   3481                 _movieFragmentSeqIdx[trackID] = 1;
   3482                 _peekMovieFragmentSeqIdx[trackID] = 1;
   3483                 TrackDurationInfo *trackinfo = NULL;
   3484                 if (_pTrackDurationContainer != NULL)
   3485                 {
   3486                     TrackDurationInfo *pTrackDurationInfo = (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i];
   3487                     if (pTrackDurationInfo != NULL)
   3488                     {
   3489                         PV_MP4_FF_DELETE(NULL, TrackDurationInfo, pTrackDurationInfo);
   3490                         pTrackDurationInfo = NULL;
   3491                     }
   3492                 }
   3493                 trackDuration = Oscl_Int64_Utils::get_uint64_lower32(_pmovieAtom->getTrackMediaDuration(trackID));
   3494                 PV_MP4_FF_NEW(fp->auditCB, TrackDurationInfo, (trackDuration, trackID), trackinfo);
   3495                 (*_pTrackDurationContainer->_pTrackdurationInfoVec)[i] = trackinfo;
   3496             }
   3497             oscl_free(trackList);
   3498             for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
   3499             {
   3500                 MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   3501                 if (pMovieFragmentAtom != NULL)
   3502                     pMovieFragmentAtom->resetPlayback();
   3503 
   3504             }
   3505         }
   3506     }
   3507 }
   3508 
   3509 
   3510 uint32 Mpeg4File::resetPlayback(uint32 time, uint16 numTracks, uint32 *trackList, bool bResetToIFrame)
   3511 {
   3512     OSCL_UNUSED_ARG(numTracks);
   3513 
   3514     uint32 modifiedTimeStamp = time;
   3515     uint32 trackID = 0;
   3516 
   3517     uint32 retVal = 0;
   3518     bool oMoofFound = false;
   3519 
   3520     uint32 convertedTS = 0;
   3521     uint32 timestamp = 0, returnedTS = 0;
   3522 
   3523     uint32 moof_offset = 0, traf_number = 0, trun_number = 0, sample_num = 0;
   3524 
   3525     trackID = *trackList; //  numTracks is the track index in trackList
   3526     if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
   3527     {
   3528         _oVideoTrackPresent = true;
   3529     }
   3530 
   3531     if (_isMovieFragmentsPresent)
   3532     {
   3533         if (_pMovieFragmentAtomVec->size() > 1)
   3534         {
   3535             // The boolean is used to reset all MOOFs to start after reposition. This should
   3536             // be true only when number of MOOFs in MOOF vector queue is more than one.
   3537             isResetPlayBackCalled = true;
   3538         }
   3539     }
   3540 
   3541     if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
   3542     {
   3543         if (repositionFromMoof(time, trackID))
   3544         {
   3545             //moof
   3546             modifiedTimeStamp = time;
   3547 
   3548             // convert modifiedTimeStamp (which is in ms) to the appropriate
   3549             // media time scale
   3550             MediaClockConverter mcc1(1000);
   3551             mcc1.update_clock(modifiedTimeStamp);
   3552             convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
   3553             if (oMfraFound)
   3554             {
   3555                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   3556                 {
   3557                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   3558                     uint32 ret = pMovieFragmentRandomAccessAtom->getSyncSampleInfoClosestToTime(trackID, convertedTS, moof_offset, traf_number, trun_number, sample_num);
   3559                     if (ret == 0)
   3560                     {
   3561                         if (moofParsingCompleted)
   3562                         {
   3563                             // do nothing
   3564                         }
   3565                         else
   3566                         {
   3567                             uint32 i = _pMovieFragmentAtomVec->size();
   3568                             _pMoofOffsetVec->pop_back();
   3569                             _pMovieFragmentAtomVec->pop_back();
   3570                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3571                             parseMoofCompletely = true;
   3572                             moofParsingCompleted = true;
   3573                             moofSize = 0;
   3574                             moofType = UNKNOWN_ATOM;
   3575                             moofCount = 0;
   3576                             moofPtrPos = 0;
   3577                         }
   3578 
   3579                         for (uint32 idx = 0; idx < _pMoofOffsetVec->size(); idx++)
   3580                         {
   3581                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
   3582                             if (moof_start_offset == moof_offset)
   3583                             {
   3584                                 _movieFragmentIdx[trackID] = idx;
   3585                                 _peekMovieFragmentIdx[trackID] = idx;
   3586                                 _movieFragmentSeqIdx[trackID] = (*_pMovieFragmentAtomVec)[idx]->getSequenceNumber();
   3587                                 _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
   3588                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   3589                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3590                                 oMoofFound = true;
   3591 
   3592                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_offset);
   3593                                 uint32 atomType = UNKNOWN_ATOM;
   3594                                 uint32 atomSize = 0;
   3595                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   3596                                 if (atomType == MOVIE_FRAGMENT_ATOM)
   3597                                 {
   3598                                     atomSize -= DEFAULT_ATOM_SIZE;
   3599                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3600                                     _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3601                                 }
   3602                                 break;
   3603                             }
   3604                         }
   3605 
   3606                         if (_parsing_mode == 1)
   3607                         {
   3608                             if (!oMoofFound)
   3609                             {
   3610                                 uint32 fileSize = 0;
   3611                                 _ptrMoofEnds = moof_offset;
   3612                                 AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   3613                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   3614                                 uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3615                                 int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
   3616 
   3617                                 while (count > 0)
   3618                                 {
   3619                                     uint32 atomType = UNKNOWN_ATOM;
   3620                                     uint32 atomSize = 0;
   3621                                     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   3622                                     if (atomType == MOVIE_FRAGMENT_ATOM)
   3623                                     {
   3624                                         parseMoofCompletely = true;
   3625 
   3626                                         uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3627                                         moofStartOffset -= DEFAULT_ATOM_SIZE;
   3628 
   3629                                         if (moofParsingCompleted)
   3630                                         {
   3631                                             // do nothing
   3632                                         }
   3633                                         else
   3634                                         {
   3635                                             uint32 i = _pMovieFragmentAtomVec->size();
   3636                                             _pMoofOffsetVec->pop_back();
   3637                                             _pMovieFragmentAtomVec->pop_back();
   3638                                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3639                                             parseMoofCompletely = true;
   3640                                             moofParsingCompleted = true;
   3641                                             moofSize = 0;
   3642                                             moofType = UNKNOWN_ATOM;
   3643                                             moofCount = 0;
   3644                                             moofPtrPos = 0;
   3645                                         }
   3646 
   3647                                         PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
   3648 
   3649                                         if (!_pMovieFragmentAtom->MP4Success())
   3650                                         {
   3651                                             _success = false;
   3652                                             _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   3653                                             break;
   3654                                         }
   3655 
   3656                                         _pMovieFragmentAtom->setParent(this);
   3657                                         count -= _pMovieFragmentAtom->getSize();
   3658 
   3659                                         uint32 i = _pMovieFragmentAtomVec->size();
   3660 
   3661                                         MovieFragmentAtom *pMovieFragmentAtom = NULL;
   3662                                         uint32 prevMoofSeqNum = 0;
   3663 
   3664                                         if (i > 0)
   3665                                         {
   3666                                             pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[i-1];
   3667 
   3668                                             if (pMovieFragmentAtom != NULL)
   3669                                                 prevMoofSeqNum = (*_pMovieFragmentAtomVec)[i-1]->getSequenceNumber();
   3670                                         }
   3671 
   3672                                         currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3673 
   3674                                         for (uint32 idx = prevMoofSeqNum; idx < currMoofNum - 1; idx++)
   3675                                         {
   3676                                             _pMovieFragmentAtomVec->push_back(NULL);
   3677                                             _pMoofOffsetVec->push_back(0);
   3678                                         }
   3679                                         if (currMoofNum > i)
   3680                                         {
   3681                                             _pMoofOffsetVec->push_back(moofStartOffset);
   3682                                             _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
   3683                                         }
   3684                                         else if ((*_pMovieFragmentAtomVec)[currMoofNum-1] == NULL)
   3685                                         {
   3686                                             (*_pMovieFragmentAtomVec)[currMoofNum-1] = _pMovieFragmentAtom;
   3687                                             (*_pMoofOffsetVec)[currMoofNum-1] = moofStartOffset;
   3688                                         }
   3689                                         else
   3690                                         {
   3691                                             PV_MP4_FF_DELETE(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, _pMovieFragmentAtom);
   3692                                             _pMovieFragmentAtom = NULL;
   3693                                             break;
   3694 
   3695                                         }
   3696                                         _movieFragmentSeqIdx[trackID] = currMoofNum;
   3697                                         _movieFragmentIdx[trackID] = currMoofNum - 1;
   3698                                         _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
   3699                                         _peekMovieFragmentSeqIdx[trackID] = currMoofNum;
   3700 
   3701                                         oMoofFound = true;
   3702 
   3703                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3704                                         break;
   3705                                     }
   3706                                     else if (atomType == MEDIA_DATA_ATOM)
   3707                                     {
   3708                                         if (atomSize == 1)
   3709                                         {
   3710                                             uint64 largeSize = 0;
   3711                                             AtomUtils::read64(_movieFragmentFilePtr, largeSize);
   3712                                             uint32 size =
   3713                                                 Oscl_Int64_Utils::get_uint64_lower32(largeSize);
   3714                                             count -= size;
   3715                                             size -= 8; //for large size
   3716                                             size -= DEFAULT_ATOM_SIZE;
   3717                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
   3718                                         }
   3719                                         else
   3720                                         {
   3721                                             if (atomSize < DEFAULT_ATOM_SIZE)
   3722                                             {
   3723                                                 _success = false;
   3724                                                 _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
   3725                                                 break;
   3726                                             }
   3727                                             if (count < (int32)atomSize)
   3728                                             {
   3729                                                 _success = false;
   3730                                                 _mp4ErrorCode = READ_FAILED;
   3731                                                 break;
   3732                                             }
   3733                                             count -= atomSize;
   3734                                             atomSize -= DEFAULT_ATOM_SIZE;
   3735                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3736                                         }
   3737                                     }
   3738 
   3739                                     else
   3740                                     {
   3741                                         if (count > 0)
   3742                                         {
   3743                                             count -= atomSize;
   3744                                             atomSize -= DEFAULT_ATOM_SIZE;
   3745                                             AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3746                                         }
   3747 
   3748                                     }
   3749                                 }
   3750                             }
   3751 
   3752                         }
   3753 
   3754                         if (_pmovieAtom != NULL)
   3755                             _pmovieAtom->resetTrackToEOT();
   3756 
   3757                         if (_pMovieFragmentAtom != NULL)
   3758                             returnedTS = _pMovieFragmentAtom->resetPlayback(trackID, convertedTS, traf_number, trun_number, sample_num);
   3759                     }
   3760                     else
   3761                     {
   3762                         // Not a valid tfra entries, cannot reposition.
   3763                         return 0;
   3764                     }
   3765                 }
   3766 
   3767             }
   3768             else
   3769                 return 0;
   3770 
   3771             // convert returnedTS (which is in media time scale) to the ms
   3772             MediaClockConverter mcc(getTrackMediaTimescale(trackID));
   3773             mcc.update_clock(returnedTS);
   3774             timestamp = mcc.get_converted_ts(1000);
   3775 
   3776             if (timestamp <= modifiedTimeStamp)
   3777             {
   3778                 modifiedTimeStamp = timestamp;
   3779             }
   3780 
   3781         }
   3782         else
   3783         {
   3784             if (_isMovieFragmentsPresent)
   3785             {
   3786                 if (_pMovieFragmentAtomVec->size() > 0)
   3787                 {
   3788                     if (moofParsingCompleted)
   3789                     {
   3790                         // do nothing
   3791                     }
   3792                     else
   3793                     {
   3794                         uint32 i = _pMovieFragmentAtomVec->size();
   3795                         _pMoofOffsetVec->pop_back();
   3796                         _pMovieFragmentAtomVec->pop_back();
   3797                         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3798                         parseMoofCompletely = true;
   3799                         moofParsingCompleted = true;
   3800                         moofSize = 0;
   3801                         moofType = UNKNOWN_ATOM;
   3802                         moofCount = 0;
   3803                         moofPtrPos = 0;
   3804                     }
   3805                 }
   3806             }
   3807 
   3808             //movie
   3809             if (_pmovieAtom != NULL)
   3810             {
   3811                 resetAllMovieFragments();
   3812                 uint32 trackVideo = trackID;
   3813                 uint32 numTrackForVideo = 1;
   3814                 modifiedTimeStamp =  _pmovieAtom->resetPlayback(modifiedTimeStamp, numTrackForVideo, &trackVideo, bResetToIFrame);
   3815             }
   3816         }
   3817     }
   3818     retVal = modifiedTimeStamp;
   3819     if ((getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO) ||
   3820             (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT))
   3821     {
   3822         if (repositionFromMoof(time, trackID))
   3823         {
   3824             oMoofFound = false;
   3825             //moof
   3826             // convert modifiedTimeStamp (which is in ms) to the appropriate
   3827             // media time scale
   3828             MediaClockConverter mcc1(1000);
   3829             mcc1.update_clock(modifiedTimeStamp);
   3830             convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
   3831             if (oMfraFound)
   3832             {
   3833                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   3834                 {
   3835                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   3836                     uint32 ret = pMovieFragmentRandomAccessAtom->getSyncSampleInfoClosestToTime(trackID, convertedTS, moof_offset, traf_number, trun_number, sample_num);
   3837                     if (ret == 0)
   3838                     {
   3839                         if (moofParsingCompleted)
   3840                         {
   3841                             // do nothing
   3842                         }
   3843                         else
   3844                         {
   3845                             uint32 i = _pMovieFragmentAtomVec->size();
   3846                             _pMoofOffsetVec->pop_back();
   3847                             _pMovieFragmentAtomVec->pop_back();
   3848                             PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3849                             parseMoofCompletely = true;
   3850                             moofParsingCompleted = true;
   3851                             moofSize = 0;
   3852                             moofType = UNKNOWN_ATOM;
   3853                             moofCount = 0;
   3854                             moofPtrPos = 0;
   3855                         }
   3856                         //
   3857                         for (idx = 0; idx < _pMoofOffsetVec->size(); idx++)
   3858                         {
   3859                             uint32 moof_start_offset = (*_pMoofOffsetVec)[idx];
   3860                             if (moof_start_offset == moof_offset)
   3861                             {
   3862                                 _movieFragmentIdx[trackID] = idx;
   3863                                 _peekMovieFragmentIdx[trackID] = idx;
   3864                                 _movieFragmentSeqIdx[trackID] = (*_pMovieFragmentAtomVec)[idx]->getSequenceNumber();
   3865                                 _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
   3866                                 _pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   3867                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3868                                 oMoofFound = true;
   3869 
   3870                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, moof_offset);
   3871                                 uint32 atomType = UNKNOWN_ATOM;
   3872                                 uint32 atomSize = 0;
   3873                                 AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   3874                                 if (atomType == MOVIE_FRAGMENT_ATOM)
   3875                                 {
   3876                                     atomSize -= DEFAULT_ATOM_SIZE;
   3877                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   3878                                     _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3879                                 }
   3880                                 break;
   3881                             }
   3882                         }
   3883                         //
   3884                     }
   3885                     else
   3886                     {
   3887                         // Not a valid tfra entries, cannot reposition.
   3888                         return 0;
   3889                     }
   3890                 }
   3891                 if (_parsing_mode == 1 && !oMoofFound)
   3892                 {
   3893 
   3894                     if (!oMoofFound)
   3895                     {
   3896                         _ptrMoofEnds = moof_offset;
   3897                         uint32 fileSize = 0;
   3898                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   3899                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   3900                         uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3901                         int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
   3902 
   3903                         while (count > 0)
   3904                         {
   3905                             uint32 atomType = UNKNOWN_ATOM;
   3906                             uint32 atomSize = 0;
   3907                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   3908                             if (atomType == MOVIE_FRAGMENT_ATOM)
   3909                             {
   3910                                 uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3911                                 moofStartOffset -= DEFAULT_ATOM_SIZE;
   3912                                 parseMoofCompletely = true;
   3913 
   3914                                 if (moofParsingCompleted)
   3915                                 {
   3916                                     // do nothing
   3917                                 }
   3918                                 else
   3919                                 {
   3920                                     uint32 i = _pMovieFragmentAtomVec->size();
   3921                                     _pMoofOffsetVec->pop_back();
   3922                                     _pMovieFragmentAtomVec->pop_back();
   3923                                     PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   3924                                     parseMoofCompletely = true;
   3925                                     moofParsingCompleted = true;
   3926                                     moofSize = 0;
   3927                                     moofType = UNKNOWN_ATOM;
   3928                                     moofCount = 0;
   3929                                     moofPtrPos = 0;
   3930                                 }
   3931 
   3932                                 PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
   3933 
   3934                                 if (!_pMovieFragmentAtom->MP4Success())
   3935                                 {
   3936                                     _success = false;
   3937                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   3938                                     break;
   3939                                 }
   3940 
   3941                                 _pMovieFragmentAtom->setParent(this);
   3942                                 count -= _pMovieFragmentAtom->getSize();
   3943                                 uint32 i = _pMovieFragmentAtomVec->size();
   3944 
   3945                                 MovieFragmentAtom *pMovieFragmentAtom = NULL;
   3946                                 uint32 prevMoofSeqNum = 0;
   3947 
   3948                                 if (i > 0)
   3949                                 {
   3950                                     pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[i-1];
   3951 
   3952                                     if (pMovieFragmentAtom != NULL)
   3953                                         prevMoofSeqNum = (*_pMovieFragmentAtomVec)[i-1]->getSequenceNumber();
   3954                                 }
   3955                                 currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3956 
   3957                                 for (uint32 idx = prevMoofSeqNum; idx < currMoofNum - 1; idx++)
   3958                                 {
   3959                                     _pMovieFragmentAtomVec->push_back(NULL);
   3960                                     _pMoofOffsetVec->push_back(0);
   3961                                 }
   3962 
   3963                                 if (currMoofNum > i)
   3964                                 {
   3965                                     _pMoofOffsetVec->push_back(moofStartOffset);
   3966                                     _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
   3967                                 }
   3968                                 else if ((*_pMovieFragmentAtomVec)[currMoofNum-1] == NULL)
   3969                                 {
   3970                                     (*_pMovieFragmentAtomVec)[currMoofNum-1] = _pMovieFragmentAtom;
   3971                                     (*_pMoofOffsetVec)[currMoofNum-1] = moofStartOffset;
   3972                                 }
   3973                                 else
   3974                                 {
   3975                                     PV_MP4_FF_DELETE(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, _pMovieFragmentAtom);
   3976                                     _pMovieFragmentAtom = NULL;
   3977                                     break;
   3978 
   3979                                 }
   3980                                 if (oMfraFound)
   3981                                 {
   3982                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3983                                     _movieFragmentIdx[trackID] = currMoofNum - 1 ;
   3984                                     _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
   3985                                     _movieFragmentSeqIdx[trackID] = currMoofNum;
   3986                                     _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
   3987                                     oMoofFound = true;
   3988                                     if (!_oVideoTrackPresent)
   3989                                     {
   3990                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   3991                                     }
   3992                                     break;
   3993                                 }
   3994                                 uint32 currTrafDuration = _pMovieFragmentAtom->getCurrentTrafDuration(trackID);
   3995                                 if (currTrafDuration >= modifiedTimeStamp)
   3996                                 {
   3997                                     currMoofNum = _pMovieFragmentAtom->getSequenceNumber();
   3998                                     _movieFragmentIdx[trackID] = currMoofNum - 1;
   3999                                     _peekMovieFragmentIdx[trackID] = currMoofNum - 1;
   4000                                     _movieFragmentSeqIdx[trackID] = currMoofNum;
   4001                                     _peekMovieFragmentSeqIdx[trackID] = _movieFragmentSeqIdx[trackID];
   4002                                     oMoofFound = true;
   4003                                     if (!_oVideoTrackPresent)
   4004                                     {
   4005                                         _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   4006                                     }
   4007                                     break;
   4008                                 }
   4009 
   4010                             }
   4011                             else if (atomType == MEDIA_DATA_ATOM)
   4012                             {
   4013                                 if (atomSize == 1)
   4014                                 {
   4015                                     uint64 largeSize = 0;
   4016                                     AtomUtils::read64(_movieFragmentFilePtr, largeSize);
   4017                                     uint32 size =
   4018                                         Oscl_Int64_Utils::get_uint64_lower32(largeSize);
   4019                                     count -= size;
   4020                                     size -= 8; //for large size
   4021                                     size -= DEFAULT_ATOM_SIZE;
   4022                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
   4023                                 }
   4024                                 else
   4025                                 {
   4026                                     if (atomSize < DEFAULT_ATOM_SIZE)
   4027                                     {
   4028                                         _success = false;
   4029                                         _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
   4030                                         break;
   4031                                     }
   4032                                     if (count < (int32)atomSize)
   4033                                     {
   4034                                         _success = false;
   4035                                         _mp4ErrorCode = READ_FAILED;
   4036                                         break;
   4037                                     }
   4038                                     count -= atomSize;
   4039                                     atomSize -= DEFAULT_ATOM_SIZE;
   4040                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   4041                                 }
   4042                             }
   4043 
   4044                             else
   4045                             {
   4046                                 if (count > 0)
   4047                                 {
   4048                                     count -= atomSize;
   4049                                     atomSize -= DEFAULT_ATOM_SIZE;
   4050                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   4051                                 }
   4052 
   4053                             }
   4054                         }
   4055                     }
   4056 
   4057                 }
   4058 
   4059                 if (_pmovieAtom != NULL)
   4060                     _pmovieAtom->resetTrackToEOT();
   4061 
   4062                 if (_pMovieFragmentAtom != NULL)
   4063                     returnedTS = _pMovieFragmentAtom->resetPlayback(trackID, convertedTS, traf_number, trun_number, sample_num);
   4064             }
   4065             else
   4066                 return 0;
   4067 
   4068             // convert returnedTS (which is in media time scale) to the ms
   4069             MediaClockConverter mcc(getTrackMediaTimescale(trackID));
   4070             mcc.update_clock(returnedTS);
   4071             timestamp = mcc.get_converted_ts(1000);
   4072 
   4073 
   4074             if (timestamp <= modifiedTimeStamp)
   4075             {
   4076                 modifiedTimeStamp = timestamp;
   4077             }
   4078             retVal = modifiedTimeStamp;
   4079 
   4080         }
   4081         else
   4082         {
   4083             if (_isMovieFragmentsPresent)
   4084             {
   4085                 if (_pMovieFragmentAtomVec->size() > 0)
   4086                 {
   4087                     if (moofParsingCompleted)
   4088                     {
   4089                         // do nothing
   4090                     }
   4091                     else
   4092                     {
   4093                         uint32 i = _pMovieFragmentAtomVec->size();
   4094                         _pMoofOffsetVec->pop_back();
   4095                         _pMovieFragmentAtomVec->pop_back();
   4096                         PV_MP4_FF_DELETE(NULL, MovieFragmentAtom , (*_pMovieFragmentAtomVec)[i-1]);
   4097                         parseMoofCompletely = true;
   4098                         moofParsingCompleted = true;
   4099                         moofSize = 0;
   4100                         moofType = UNKNOWN_ATOM;
   4101                         moofCount = 0;
   4102                         moofPtrPos = 0;
   4103                     }
   4104                 }
   4105             }
   4106 
   4107             //movie
   4108             if (_pmovieAtom != NULL)
   4109             {
   4110                 resetAllMovieFragments();
   4111                 uint32 trackAudio = trackID;
   4112                 uint32 numTrackforAudio = 1;
   4113                 retVal = _pmovieAtom->resetPlayback(modifiedTimeStamp, numTrackforAudio, &trackAudio
   4114                                                     , bResetToIFrame);
   4115             }
   4116         }
   4117 
   4118     }
   4119     return retVal;
   4120 
   4121 }
   4122 
   4123 
   4124 
   4125 int32 Mpeg4File::queryRepositionTime(uint32 time,
   4126                                      uint16 numTracks,
   4127                                      uint32 *trackList,
   4128                                      bool bResetToIFrame,
   4129                                      bool bBeforeRequestedTime)
   4130 {
   4131 
   4132     uint32 i = 0;
   4133     uint32 ret = 0;
   4134     uint32 modifiedTimeStamp = time;
   4135     uint32 trackID = 0;
   4136     uint32 trackIds[256];
   4137 
   4138     bool oVideoTrackFound = false;
   4139     int j = 1;
   4140     for (i = 0; i < numTracks; i++)
   4141     {
   4142         trackID = trackList[i];
   4143         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
   4144         {
   4145             trackIds[0] = trackList[i];
   4146             oVideoTrackFound = true;
   4147         }
   4148         else
   4149         {
   4150             trackIds[j++] = trackList[i];
   4151         }
   4152     }
   4153 
   4154     uint32 convertedTS = 0;
   4155     uint32 timestamp = 0, returnedTS = 0;
   4156 
   4157     for (i = 0; i < numTracks; i++)
   4158     {
   4159         trackID = trackIds[i];
   4160 
   4161         if (!oVideoTrackFound)
   4162             trackID = trackList[i];
   4163 
   4164         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
   4165         {
   4166             if (repositionFromMoof(time, trackID))
   4167             {
   4168                 //moof
   4169                 modifiedTimeStamp = time;
   4170 
   4171                 // convert modifiedTimeStamp (which is in ms) to the appropriate
   4172                 // media time scale
   4173                 MediaClockConverter mcc1(1000);
   4174                 mcc1.update_clock(modifiedTimeStamp);
   4175                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
   4176                 if (oMfraFound)
   4177                 {
   4178                     oMfraFound = true;
   4179                     for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   4180                     {
   4181 
   4182                         MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   4183                         returnedTS = pMovieFragmentRandomAccessAtom->queryRepositionTime(trackID, convertedTS, bResetToIFrame,
   4184                                      bBeforeRequestedTime);
   4185                         if (returnedTS != 0)
   4186                         {
   4187                             break;
   4188                         }
   4189                     }
   4190                 }
   4191                 else
   4192                 {
   4193                     oMfraFound = false;
   4194                     if (_parsing_mode == 1)
   4195                         return -1;
   4196                 }
   4197 
   4198                 // convert returnedTS (which is in media time scale) to the ms
   4199                 MediaClockConverter mcc(getTrackMediaTimescale(trackID));
   4200                 mcc.update_clock(returnedTS);
   4201                 timestamp = mcc.get_converted_ts(1000);
   4202 
   4203                 modifiedTimeStamp = timestamp;
   4204 
   4205                 ret = modifiedTimeStamp;
   4206 
   4207             }
   4208             else
   4209             {
   4210                 //movie
   4211                 if (_pmovieAtom != NULL)
   4212                 {
   4213                     modifiedTimeStamp =  _pmovieAtom->queryRepositionTime(time,
   4214                                          numTracks,
   4215                                          trackList,
   4216                                          bResetToIFrame,
   4217                                          bBeforeRequestedTime);
   4218                     ret = modifiedTimeStamp;
   4219                 }
   4220             }
   4221         }
   4222 
   4223         if ((getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO) ||
   4224                 (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT))
   4225         {
   4226             if (repositionFromMoof(time, trackID))
   4227             {
   4228                 //moof
   4229                 MediaClockConverter mcc1(1000);
   4230                 mcc1.update_clock(modifiedTimeStamp);
   4231                 convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
   4232 
   4233                 for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   4234                 {
   4235 
   4236                     MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   4237                     returnedTS = pMovieFragmentRandomAccessAtom->queryRepositionTime(trackID, convertedTS, bResetToIFrame,
   4238                                  bBeforeRequestedTime);
   4239                     if (returnedTS != 0)
   4240                     {
   4241                         break;
   4242                     }
   4243                 }
   4244                 // convert returnedTS (which is in media time scale) to the ms
   4245                 MediaClockConverter mcc(getTrackMediaTimescale(trackID));
   4246                 mcc.update_clock(returnedTS);
   4247                 timestamp = mcc.get_converted_ts(1000);
   4248 
   4249                 if (!oVideoTrackFound)
   4250                 {
   4251                     if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
   4252                     {
   4253                         modifiedTimeStamp = timestamp;
   4254                     }
   4255                     else if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT && numTracks == 1)
   4256                     {
   4257                         modifiedTimeStamp = timestamp;
   4258                     }
   4259                 }
   4260 
   4261                 return modifiedTimeStamp;
   4262 
   4263             }
   4264             else
   4265             {
   4266                 //movie
   4267                 if (_pmovieAtom != NULL)
   4268                 {
   4269                     modifiedTimeStamp =   _pmovieAtom->queryRepositionTime(modifiedTimeStamp,
   4270                                           numTracks,
   4271                                           trackList,
   4272                                           bResetToIFrame,
   4273                                           bBeforeRequestedTime);
   4274 
   4275                     if (!oVideoTrackFound)
   4276                     {
   4277                         if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
   4278                         {
   4279                             ret = modifiedTimeStamp;
   4280                         }
   4281                         else if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT && numTracks == 1)
   4282                         {
   4283                             ret = modifiedTimeStamp;
   4284                         }
   4285                     }
   4286                 }
   4287 
   4288             }
   4289 
   4290         }
   4291     }
   4292     return ret;
   4293 }
   4294 
   4295 
   4296 
   4297 int32 Mpeg4File::parseMFRA()
   4298 {
   4299     uint32 ret = 0;
   4300     uint32 fileSize = 0;
   4301     uint32 MfraStartOffset = 0;
   4302     AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   4303     AtomUtils::seekFromStart(_movieFragmentFilePtr, fileSize);
   4304     AtomUtils::rewindFilePointerByN(_movieFragmentFilePtr, 16);
   4305 
   4306     uint32 atomType = UNKNOWN_ATOM;
   4307     uint32 atomSize = 0;
   4308     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   4309 
   4310     if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_OFFSET_ATOM)
   4311     {
   4312         if (_pMfraOffsetAtom == NULL)
   4313         {
   4314             PV_MP4_FF_NEW(fp->auditCB, MfraOffsetAtom, (_movieFragmentFilePtr, atomSize, atomType), _pMfraOffsetAtom);
   4315             if (!_pMfraOffsetAtom->MP4Success())
   4316             {
   4317                 _success = false;
   4318                 _mp4ErrorCode = READ_MOVIE_FRAGMENT_RANDOM_ACCESS_OFFSET_FAILED;
   4319                 return _mp4ErrorCode;
   4320             }
   4321             MfraStartOffset = _pMfraOffsetAtom->getSizeStoredInmfro();
   4322 
   4323         }
   4324     }
   4325     AtomUtils::rewindFilePointerByN(_movieFragmentFilePtr, MfraStartOffset);
   4326     AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   4327     if (atomType == MOVIE_FRAGMENT_RANDOM_ACCESS_ATOM)
   4328     {
   4329         if (_pMovieFragmentRandomAccessAtomVec->size() == 0)
   4330         {
   4331             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = NULL;
   4332             PV_MP4_FF_NEW(fp->auditCB, MovieFragmentRandomAccessAtom, (_movieFragmentFilePtr, atomSize, atomType), pMovieFragmentRandomAccessAtom);
   4333 
   4334             if (!pMovieFragmentRandomAccessAtom->MP4Success())
   4335             {
   4336                 PV_MP4_FF_DELETE(NULL, MovieFragmentRandomAccessAtom, pMovieFragmentRandomAccessAtom);
   4337                 _success = false;
   4338                 _mp4ErrorCode = pMovieFragmentRandomAccessAtom->GetMP4Error();
   4339                 return _mp4ErrorCode ;
   4340             }
   4341             pMovieFragmentRandomAccessAtom->setParent(this);
   4342             _pMovieFragmentRandomAccessAtomVec->push_back(pMovieFragmentRandomAccessAtom);
   4343             oMfraFound = true;
   4344         }
   4345     }
   4346 
   4347     return ret;
   4348 
   4349 }
   4350 
   4351 
   4352 int32 Mpeg4File::peekNextBundledAccessUnits(const uint32 trackID,
   4353         uint32 *n,
   4354         MediaMetaInfo *mInfo)
   4355 {
   4356     // IF THERE ARE NO MEDIA TRACKS, RETURN READ ERROR
   4357     uint32 samplesTobeRead;
   4358     samplesTobeRead = *n;
   4359     uint32 totalSampleRead = 0;
   4360     if (getNumTracks() == 0)
   4361     {
   4362         return -1;
   4363     }
   4364     if (_pmovieAtom != NULL)
   4365     {
   4366         uint32 ret = (_pmovieAtom->peekNextBundledAccessUnits(trackID, n, mInfo));
   4367         if (ret == END_OF_TRACK)
   4368         {
   4369             if (!_isMovieFragmentsPresent)
   4370                 return ret;
   4371 
   4372             bool oAllMoofExhausted = false;
   4373 
   4374             totalSampleRead += *n;
   4375 
   4376             if (totalSampleRead == samplesTobeRead)
   4377             {
   4378                 *n = totalSampleRead;
   4379                 return EVERYTHING_FINE;
   4380             }
   4381 
   4382             if (_pMovieFragmentAtomVec != NULL)
   4383             {
   4384                 if (samplesTobeRead >= *n)
   4385                     *n = samplesTobeRead - *n;
   4386                 if (*n == 0)
   4387                     *n = samplesTobeRead;
   4388             }
   4389             else
   4390                 return ret;
   4391 
   4392             if (_parsing_mode == 0)
   4393             {
   4394                 int32 return1 = 0;
   4395                 while (_peekMovieFragmentIdx[trackID] < _pMovieFragmentAtomVec->size())
   4396                 {
   4397                     uint32 peekMovieFragmentIdx = _peekMovieFragmentIdx[trackID];
   4398                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[peekMovieFragmentIdx];
   4399                     if (pMovieFragmentAtom != NULL)
   4400                     {
   4401                         if ((uint32)pMovieFragmentAtom->getSequenceNumber() == _peekMovieFragmentSeqIdx[trackID])
   4402                         {
   4403                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
   4404                             if (trackfragment != NULL)
   4405                             {
   4406                                 if (trackfragment->getTrackId() == trackID)
   4407                                 {
   4408                                     return1 = pMovieFragmentAtom->peekNextBundledAccessUnits(trackID, n, totalSampleRead, mInfo);
   4409                                     totalSampleRead += *n;
   4410                                     if (return1 != END_OF_TRACK)
   4411                                     {
   4412                                         *n = totalSampleRead;
   4413                                         return return1;
   4414                                     }
   4415                                     else
   4416                                     {
   4417                                         _peekMovieFragmentSeqIdx[trackID]++;
   4418                                         if (samplesTobeRead >= *n)
   4419                                         {
   4420                                             samplesTobeRead = samplesTobeRead - *n;
   4421                                             *n = samplesTobeRead;
   4422                                         }
   4423                                     }
   4424                                 }
   4425                             }
   4426                         }
   4427                     }
   4428                     _peekMovieFragmentIdx[trackID]++;
   4429                 }
   4430                 if (return1 == END_OF_TRACK)
   4431                 {
   4432                     *n = totalSampleRead;
   4433                     _peekMovieFragmentIdx[trackID] = 0;
   4434                     _peekMovieFragmentSeqIdx[trackID] = 1;
   4435                     return return1;
   4436                 }
   4437             }
   4438             else
   4439             {
   4440 
   4441                 while (!oAllMoofExhausted)
   4442                 {
   4443                     uint32 moofIndex = 0;
   4444                     bool moofToBeParsed = false;
   4445 
   4446                     if (_pMovieFragmentAtomVec->size() > _peekMovieFragmentIdx[trackID])
   4447                     {
   4448                         MovieFragmentAtom *pMovieFragmentAtom = NULL;
   4449                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[_peekMovieFragmentIdx[trackID]];
   4450                         if (pMovieFragmentAtom == NULL)
   4451                         {
   4452                             moofToBeParsed = true;
   4453                             moofIndex = _peekMovieFragmentIdx[trackID];
   4454                         }
   4455                     }
   4456                     if ((_pMovieFragmentAtomVec->size() <= _peekMovieFragmentIdx[trackID]) || moofToBeParsed)
   4457                     {
   4458                         uint32 fileSize = 0;
   4459                         AtomUtils::getCurrentFileSize(_movieFragmentFilePtr, fileSize);
   4460                         AtomUtils::seekFromStart(_movieFragmentFilePtr, _ptrMoofEnds);
   4461                         uint32 filePointer = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   4462                         int32 count = fileSize - filePointer;// -DEFAULT_ATOM_SIZE;
   4463 
   4464                         while (count > 0)
   4465                         {
   4466                             uint32 atomType = UNKNOWN_ATOM;
   4467                             uint32 atomSize = 0;
   4468                             uint32 currPos = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   4469                             AtomUtils::getNextAtomType(_movieFragmentFilePtr, atomSize, atomType);
   4470                             if ((currPos + atomSize) > fileSize)
   4471                             {
   4472                                 AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
   4473                                 return  INSUFFICIENT_DATA;
   4474                             }
   4475                             if (atomType == MOVIE_FRAGMENT_ATOM)
   4476                             {
   4477                                 uint32 moofStartOffset = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   4478                                 moofStartOffset -= DEFAULT_ATOM_SIZE;
   4479 
   4480                                 parseMoofCompletely = true;
   4481 
   4482                                 PV_MP4_FF_NEW(_movieFragmentFilePtr->auditCB, MovieFragmentAtom, (_movieFragmentFilePtr, atomSize, atomType, _pTrackDurationContainer, _pTrackExtendsAtomVec, parseMoofCompletely, moofParsingCompleted, countOfTrunsParsed), _pMovieFragmentAtom);
   4483 
   4484                                 if (!_pMovieFragmentAtom->MP4Success())
   4485                                 {
   4486                                     _success = false;
   4487                                     _mp4ErrorCode = _pMovieFragmentAtom->GetMP4Error();
   4488                                     oAllMoofExhausted = true;
   4489                                     break;
   4490                                 }
   4491                                 _pMovieFragmentAtom->setParent(this);
   4492                                 count -= _pMovieFragmentAtom->getSize();
   4493                                 if (moofToBeParsed)
   4494                                 {
   4495                                     (*_pMovieFragmentAtomVec)[moofIndex] = _pMovieFragmentAtom;
   4496                                     (*_pMoofOffsetVec)[moofIndex] = moofStartOffset;
   4497                                 }
   4498                                 else
   4499                                 {
   4500                                     _pMoofOffsetVec->push_back(moofStartOffset);
   4501                                     _pMovieFragmentAtomVec->push_back(_pMovieFragmentAtom);
   4502                                 }
   4503                                 _ptrMoofEnds = AtomUtils::getCurrentFilePosition(_movieFragmentFilePtr);
   4504 
   4505                                 break;
   4506                             }
   4507                             else if (atomType == MEDIA_DATA_ATOM)
   4508                             {
   4509                                 if (atomSize == 1)
   4510                                 {
   4511                                     uint64 largeSize = 0;
   4512                                     AtomUtils::read64(_movieFragmentFilePtr, largeSize);
   4513                                     uint32 size =
   4514                                         Oscl_Int64_Utils::get_uint64_lower32(largeSize);
   4515                                     count -= size;
   4516                                     size -= 8; //for large size
   4517                                     size -= DEFAULT_ATOM_SIZE;
   4518                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, size);
   4519                                 }
   4520                                 else
   4521                                 {
   4522                                     if (atomSize < DEFAULT_ATOM_SIZE)
   4523                                     {
   4524                                         _success = false;
   4525                                         oAllMoofExhausted = true;
   4526                                         _mp4ErrorCode = ZERO_OR_NEGATIVE_ATOM_SIZE;
   4527                                         break;
   4528                                     }
   4529                                     if (count < (int32)atomSize)
   4530                                     {
   4531                                         _success = false;
   4532                                         oAllMoofExhausted = true;
   4533                                         _mp4ErrorCode = INSUFFICIENT_DATA;
   4534                                         AtomUtils::seekFromStart(_movieFragmentFilePtr, currPos);
   4535                                         ret = _mp4ErrorCode;
   4536                                         break;
   4537                                     }
   4538                                     count -= atomSize;
   4539                                     atomSize -= DEFAULT_ATOM_SIZE;
   4540                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   4541                                 }
   4542                             }
   4543 
   4544                             else
   4545                             {
   4546                                 if (count > 0)
   4547                                 {
   4548                                     count -= atomSize;
   4549                                     atomSize -= DEFAULT_ATOM_SIZE;
   4550                                     AtomUtils::seekFromCurrPos(_movieFragmentFilePtr, atomSize);
   4551                                 }
   4552                                 break;
   4553                             }
   4554                         }
   4555                         if (count <= 0)
   4556                         {
   4557                             oAllMoofExhausted = true;
   4558                             if (_pMovieFragmentAtomVec->size() < _peekMovieFragmentIdx[trackID])
   4559                                 break;
   4560                         }
   4561                     }
   4562 
   4563                     int32 return1 = 0;
   4564                     MovieFragmentAtom *pMovieFragmentAtom = NULL;
   4565                     uint32 movieFragmentIdx = _peekMovieFragmentIdx[trackID];
   4566 
   4567                     if (movieFragmentIdx < _pMovieFragmentAtomVec->size())
   4568                         pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[movieFragmentIdx];
   4569 
   4570                     if (pMovieFragmentAtom != NULL)
   4571                     {
   4572                         uint32 seqNum = pMovieFragmentAtom->getSequenceNumber();
   4573                         if (seqNum == _peekMovieFragmentSeqIdx[trackID])
   4574                         {
   4575                             TrackFragmentAtom *trackfragment = pMovieFragmentAtom->getTrackFragmentforID(trackID);
   4576                             if (trackfragment != NULL)
   4577                             {
   4578                                 if (trackfragment->getTrackId() == trackID)
   4579                                 {
   4580                                     return1 = pMovieFragmentAtom->peekNextBundledAccessUnits(trackID, n, totalSampleRead, mInfo);
   4581                                     totalSampleRead += *n;
   4582                                     if (return1 != END_OF_TRACK)
   4583                                     {
   4584                                         *n = totalSampleRead;
   4585                                         return return1;
   4586                                     }
   4587                                     else
   4588                                     {
   4589                                         _peekMovieFragmentSeqIdx[trackID]++;
   4590                                         if (samplesTobeRead >= *n)
   4591                                         {
   4592                                             samplesTobeRead = samplesTobeRead - *n;
   4593                                             *n = samplesTobeRead;
   4594                                         }
   4595                                     }
   4596                                 }
   4597                             }
   4598                             else
   4599                             {
   4600                                 _peekMovieFragmentIdx[trackID]++;
   4601                                 _peekMovieFragmentSeqIdx[trackID]++;
   4602                                 *n = 0;
   4603                                 return NO_SAMPLE_IN_CURRENT_MOOF;
   4604                             }
   4605                         }
   4606                     }
   4607                     _peekMovieFragmentIdx[trackID]++;
   4608 
   4609                 }
   4610             }
   4611         }
   4612         return ret;
   4613     }
   4614     else
   4615     {
   4616         return -1;
   4617     }
   4618 }
   4619 
   4620 
   4621 uint32 Mpeg4File::getSampleCountInTrack(uint32 id)
   4622 {
   4623     uint32 nTotalSamples = 0;
   4624     if (_pmovieAtom != NULL)
   4625     {
   4626         nTotalSamples = (_pmovieAtom->getSampleCountInTrack(id));
   4627         if (!_isMovieFragmentsPresent)
   4628             return nTotalSamples;
   4629 
   4630         if (_parsing_mode == 0)
   4631         {
   4632             if (_pMovieFragmentAtomVec->size() > 0)
   4633             {
   4634                 for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
   4635                 {
   4636                     MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   4637                     if (pMovieFragmentAtom != NULL)
   4638                     {
   4639                         nTotalSamples += pMovieFragmentAtom->getTotalSampleInTraf(id);
   4640                     }
   4641                 }
   4642                 return nTotalSamples;
   4643             }
   4644         }
   4645         return nTotalSamples;
   4646     }
   4647     return 0;
   4648 }
   4649 
   4650 
   4651 bool Mpeg4File::IsTFRAPresentForTrack(uint32 TrackId, bool oVideoAudioTextTrack)
   4652 {
   4653     if (_pMovieFragmentRandomAccessAtomVec != NULL)
   4654     {
   4655         for (uint32 idx = 0; idx < _pMovieFragmentRandomAccessAtomVec->size(); idx++)
   4656         {
   4657 
   4658             MovieFragmentRandomAccessAtom *pMovieFragmentRandomAccessAtom = (*_pMovieFragmentRandomAccessAtomVec)[idx];
   4659             return pMovieFragmentRandomAccessAtom->IsTFRAPresentForTrack(TrackId, oVideoAudioTextTrack);
   4660         }
   4661     }
   4662     return false;
   4663 }
   4664 
   4665 
   4666 /*
   4667 This function has been modified to check the entry count in TFRA for all tracks are equal.
   4668 The code change is under macro DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT
   4669 */
   4670 bool Mpeg4File::IsTFRAPresentForAllTrack(uint32 numTracks, uint32 *trackList)
   4671 {
   4672 
   4673 #if (DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT)
   4674     bool oVideoAudioTextTrack  = false;
   4675 // This flag will be true for Video in AVT,VT & AV and for Audio in AT.
   4676 // Based on this flag IsTFRAPresentForTrack() functions behaviour is changing
   4677 // We are comparing the entry count for all the tracks to entry count of V in case of Vonly,AVT,VT & AV clips
   4678 // and in case of Aonly & AT clips, entry count for all the tracks is compared with entry count of audio. For Tonly
   4679 // clips, entry count for text track is compared with its own entry count.
   4680 
   4681     // Support for clips having Video track.
   4682     for (int32 i = 0; i < numTracks; i++)
   4683     {
   4684         uint32 trackID = trackList[i];
   4685         if (getTrackMediaType(trackID) == MEDIA_TYPE_VISUAL)
   4686         {
   4687             oVideoAudioTextTrack  = true;
   4688             if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
   4689             {
   4690                 return false;
   4691             }
   4692             break;
   4693         }
   4694     }
   4695     // Support for clips having Audio track and no Video track.
   4696     if (!oVideoAudioTextTrack)
   4697     {
   4698         for (int32 i = 0; i < numTracks; i++)
   4699         {
   4700             uint32 trackID = trackList[i];
   4701             if (getTrackMediaType(trackID) == MEDIA_TYPE_AUDIO)
   4702             {
   4703                 oVideoAudioTextTrack = true;
   4704                 if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
   4705                 {
   4706                     return false;
   4707                 }
   4708                 break;
   4709             }
   4710         }
   4711     }
   4712     // Support for clips having only Text track.
   4713     if (!oVideoAudioTextTrack && numTracks == 1)
   4714     {
   4715         for (uint32 i = 0; i < numTracks; i++)
   4716         {
   4717             uint32 trackID = trackList[i];
   4718             if (getTrackMediaType(trackID) == MEDIA_TYPE_TEXT)
   4719             {
   4720                 oVideoAudioTextTrack = true;
   4721                 if (IsTFRAPresentForTrack(trackID, oVideoAudioTextTrack) == false)
   4722                 {
   4723                     return false;
   4724                 }
   4725                 break;
   4726             }
   4727         }
   4728     }
   4729 #endif // DISABLE_REPOS_ON_CLIPS_HAVING_UNEQUAL_TFRA_ENTRY_COUNT
   4730     for (uint32 idx = 0; idx < numTracks; idx++)
   4731     {
   4732         uint32 trackID = trackList[idx];
   4733         // second argument is false always
   4734         if (IsTFRAPresentForTrack(trackID, false) == false)
   4735         {
   4736             return false;
   4737         }
   4738     }
   4739     return true;
   4740 }
   4741 
   4742 void Mpeg4File::resetPlayback()
   4743 {
   4744     if (_pmovieAtom == NULL)
   4745         return;
   4746 
   4747     _pmovieAtom->resetPlayback();
   4748 
   4749     if (_isMovieFragmentsPresent)
   4750     {
   4751         if (_pMovieFragmentAtomVec != NULL)
   4752         {
   4753             int numTracks = _pmovieAtom->getNumTracks();
   4754             uint32 *trackList  = (uint32 *) oscl_malloc(sizeof(uint32) * numTracks);
   4755             if (!trackList)
   4756                 return;       // malloc failed
   4757 
   4758             _pmovieAtom->getTrackWholeIDList(trackList);
   4759             for (int i = 0; i < numTracks; i++)
   4760             {
   4761                 uint32 trackID = trackList[i];
   4762                 _peekMovieFragmentIdx[trackID] = 0;
   4763                 _movieFragmentIdx[trackID] = 0;
   4764                 _movieFragmentSeqIdx[trackID] = 1;
   4765                 _peekMovieFragmentSeqIdx[trackID] = 1;
   4766             }
   4767             oscl_free(trackList);
   4768             for (uint32 idx = 0; idx < _pMovieFragmentAtomVec->size(); idx++)
   4769             {
   4770                 MovieFragmentAtom *pMovieFragmentAtom = (*_pMovieFragmentAtomVec)[idx];
   4771                 if (pMovieFragmentAtom != NULL)
   4772                     pMovieFragmentAtom->resetPlayback();
   4773 
   4774             }
   4775         }
   4776     }
   4777 }
   4778 
   4779 uint32 Mpeg4File::repositionFromMoof(uint32 time, uint32 trackID)
   4780 {
   4781     uint32 modifiedTimeStamp = time;
   4782     uint32 convertedTS = 0;
   4783     uint32 trackDuration = Oscl_Int64_Utils::get_uint64_lower32(getTrackMediaDurationForMovie(trackID));//getMovieDuration() - getMovieFragmentDuration();
   4784 
   4785     MediaClockConverter mcc1(1000);
   4786     mcc1.update_clock(modifiedTimeStamp);
   4787     convertedTS = mcc1.get_converted_ts(getTrackMediaTimescale(trackID));
   4788 
   4789     if (_isMovieFragmentsPresent)
   4790     {
   4791         if (IsTFRAPresentForTrack(trackID, false) == false)
   4792         {
   4793             return 0;
   4794         }
   4795         if (modifiedTimeStamp >= trackDuration)
   4796         {
   4797             return 1; //repos in moof
   4798         }
   4799     }
   4800     return 0; //repos in moov
   4801 }
   4802 
   4803 MP4_ERROR_CODE Mpeg4File::CancelNotificationSync()
   4804 {
   4805     PVMF_MP4FFPARSER_LOGMEDIASAMPELSTATEVARIABLES((0, "Mpeg4File::CancelNotificationSync"));
   4806 
   4807     bool retVal = _commonFilePtr->_pvfile.CancelNotificationSync();
   4808 
   4809     if (retVal)
   4810     {
   4811         return EVERYTHING_FINE;
   4812     }
   4813     else
   4814     {
   4815         return DEFAULT_ERROR;
   4816     }
   4817 }
   4818 
   4819 bool Mpeg4File::CreateDataStreamSessionForExternalDownload(OSCL_wString& aFilename,
   4820         PVMFCPMPluginAccessInterfaceFactory* aCPMAccessFactory,
   4821         OsclFileHandle* aHandle,
   4822         Oscl_FileServer* aFileServSession)
   4823 {
   4824     OsclAny*ptr = oscl_malloc(sizeof(MP4_FF_FILE));
   4825     if (ptr == NULL)
   4826     {
   4827         _success = false;
   4828         _mp4ErrorCode = MEMORY_ALLOCATION_FAILED;
   4829         return false;
   4830     }
   4831     _commonFilePtr = OSCL_PLACEMENT_NEW(ptr, MP4_FF_FILE());
   4832 
   4833     if (_commonFilePtr != NULL)
   4834     {
   4835         _commonFilePtr->_fileServSession = aFileServSession;
   4836         _commonFilePtr->_pvfile.SetCPM(aCPMAccessFactory);
   4837         _commonFilePtr->_pvfile.SetFileHandle(aHandle);
   4838 
   4839         if (AtomUtils::OpenMP4File(aFilename,
   4840                                    Oscl_File::MODE_READ | Oscl_File::MODE_BINARY,
   4841                                    _commonFilePtr) != 0)
   4842         {
   4843             return false;
   4844         }
   4845 
   4846         uint32 fileSize;
   4847         AtomUtils::getCurrentFileSize(_commonFilePtr, fileSize);
   4848         _commonFilePtr->_fileSize = (int32)fileSize;
   4849     }
   4850     return true;
   4851 }
   4852 
   4853 void Mpeg4File::DestroyDataStreamForExternalDownload()
   4854 {
   4855     if (_commonFilePtr != NULL)
   4856     {
   4857         if (_commonFilePtr->IsOpen())
   4858         {
   4859             AtomUtils::CloseMP4File(_commonFilePtr);
   4860         }
   4861         oscl_free(_commonFilePtr);
   4862         _commonFilePtr = NULL;
   4863     }
   4864 }
   4865 
   4866 //Below APIs are used to supress Warning
   4867 void Mpeg4File::ReserveMemoryForLangCodeVector(Oscl_Vector<uint16, OsclMemAllocator> &iLangCode, int32 capacity, int32 &leavecode)
   4868 {
   4869     leavecode = 0;
   4870     OSCL_TRY(leavecode, iLangCode.reserve(capacity));
   4871 
   4872 }
   4873 
   4874 void Mpeg4File::ReserveMemoryForValuesVector(Oscl_Vector<OSCL_wHeapString<OsclMemAllocator>, OsclMemAllocator> &iValues, int32 capacity, int32 &leavecode)
   4875 {
   4876     leavecode = 0;
   4877     OSCL_TRY(leavecode, iValues.reserve(capacity));
   4878 
   4879 }
   4880 
   4881 
   4882