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 #include "pv_avifile_parser.h"
     19 
     20 
     21 PVAviFileParser::PVAviFileParser(OSCL_wHeapString<OsclMemAllocator> aFileName, int32& aError, Oscl_FileServer* aFileServer,
     22                                  PVMFCPMPluginAccessInterfaceFactory*  aCPM, OsclFileHandle*  aFileHandle)
     23 {
     24     ipFileHeader = NULL;
     25     ipIdxChunk = NULL;
     26     iIdxChunkPresent = false;
     27     iFileSize = 0;
     28     iHeaderChunkSize = 0;
     29     iMovieChunkSize = 0;
     30     iMovieChunkStartOffset = 0;
     31     iIndxChunkSize = 0;
     32     iSampleOffset = 0;
     33     iTimeStampVideo = 0;
     34     iTimeStampAudio = 0;
     35 
     36     OSCL_TRY(aError, ipFilePtr = OSCL_NEW(PVFile, ()););
     37 
     38     if (0 == aError)
     39     {
     40         ipFilePtr->SetCPM(aCPM);
     41         ipFilePtr->SetFileHandle(aFileHandle);
     42 
     43         aError = PV_AVI_FILE_PARSER_SUCCESS;
     44 
     45         if (ipFilePtr->Open(aFileName.get_cstr(), (Oscl_File::MODE_READ | Oscl_File::MODE_BINARY), *aFileServer) != 0)
     46         {
     47             aError = PV_AVI_FILE_PARSER_FILE_OPEN_ERROR;
     48         }
     49     }
     50 }
     51 
     52 PV_AVI_FILE_PARSER_ERROR_TYPE
     53 PVAviFileParser::ParseFile()
     54 {
     55     iError = PV_AVI_FILE_PARSER_SUCCESS;
     56     ipFilePtr->Seek(0, Oscl_File::SEEKSET);
     57 
     58     // Seek to the end to find the file size
     59     uint32 filesize = 0;
     60     if (ipFilePtr->Seek(0, Oscl_File::SEEKEND))
     61     {
     62         iError = PV_AVI_FILE_PARSER_SEEK_ERROR;
     63         return iError;
     64     }
     65     filesize = ipFilePtr->Tell();
     66 
     67     // Seek back to the beginning
     68     ipFilePtr->Seek(0, Oscl_File::SEEKSET);
     69     uint32 chunkType = 0;
     70 
     71     if ((iError = PVAviFileParserUtils::ReadNextChunkType(ipFilePtr, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS)
     72     {
     73         PVAVIFILE_LOGERROR((0, "PVAviFileParser::ParseFile: UnSupported Chunk at begining of the file"));
     74         return iError;
     75     }
     76 
     77     //first chunk must be RIFF
     78     if (chunkType != RIFF)
     79     {
     80         PVAVIFILE_LOGERROR((0, "PVAviFileParser::ParseFile: First Chunk Must be RIFF"));
     81         iError = PV_AVI_FILE_PARSER_WRONG_FILE;
     82         return iError;
     83     }
     84 
     85     if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, iFileSize, true))
     86     {
     87         iError = PV_AVI_FILE_PARSER_READ_ERROR;
     88         return iError;
     89     }
     90 
     91     if ((iFileSize <= 0) || (iFileSize > filesize))
     92     {
     93         iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
     94         return iError;
     95     }
     96 
     97     if ((iError = PVAviFileParserUtils::ReadNextChunkType(ipFilePtr, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS)
     98     {
     99         PVAVIFILE_LOGERROR((0, "PVAviFileParser::ParseFile: UnSupported Chunk at begining of the file"));
    100         return iError;
    101     }
    102 
    103     //second chunk must be AVI
    104     if (chunkType != AVI)
    105     {
    106         PVAVIFILE_LOGERROR((0, "Second Chunk Must be AVI"));
    107         iError = PV_AVI_FILE_PARSER_WRONG_FILE;
    108         return iError;
    109     }
    110 
    111     uint32 bytesRead = CHUNK_SIZE;
    112     uint32 listSize = 0;
    113     uint32 oldChkType = chunkType;
    114 
    115     while (bytesRead < iFileSize)
    116     {
    117         oldChkType = chunkType;
    118         if ((iError = PVAviFileParserUtils::ReadNextChunkType(ipFilePtr, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS)
    119         {
    120             if ((PV_AVI_FILE_PARSER_UNSUPPORTED_CHUNK == iError))
    121             {
    122                 PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Unsupported chunk"));
    123 
    124                 uint32 chksz = 0;
    125                 if (oldChkType != LIST)
    126                 {
    127                     //get the size of unsupported chunk and skip it.
    128                     if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, chksz, true))
    129                     {
    130                         PVAVIFILE_LOGERROR((0, "PVAviFileParser::ParseFile: File Read Error"));
    131                         iError = PV_AVI_FILE_PARSER_READ_ERROR;
    132                         break;
    133                     }
    134 
    135                     ipFilePtr->Seek(chksz, Oscl_File::SEEKCUR);
    136                     bytesRead += chksz + CHUNK_SIZE + CHUNK_SIZE; //chunk data + chunk size + chunk type;
    137 
    138                 }
    139                 else
    140                 {
    141                     //skip the entire list if not supported
    142                     chksz = listSize - CHUNK_SIZE ;  //subtract list name already read
    143                     ipFilePtr->Seek(chksz, Oscl_File::SEEKCUR);
    144                     bytesRead += listSize;
    145                 }
    146 
    147                 PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Unsupported chunk skipped"));
    148                 iError = PV_AVI_FILE_PARSER_SUCCESS;
    149                 continue;
    150             }
    151             else
    152             {
    153                 break;
    154             }
    155         }
    156         bytesRead += CHUNK_SIZE;
    157 
    158         if (LIST == chunkType)
    159         {
    160             if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, listSize, true))
    161             {
    162                 iError = PV_AVI_FILE_PARSER_READ_ERROR;
    163                 break;
    164             }
    165 
    166             bytesRead += CHUNK_SIZE;
    167             if (bytesRead > iFileSize)
    168             {
    169                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    170                 break;
    171             }
    172 
    173             if ((listSize <= 0) || (listSize > iFileSize))
    174             {
    175                 iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
    176                 break;
    177             }
    178         }
    179         else if (HDRL == chunkType)
    180         {
    181             PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Found File Header"));
    182 
    183             iHeaderChunkSize = listSize - CHUNK_SIZE; //subtract 4 bytes of chunk type
    184             ipFileHeader = OSCL_NEW(PVAviFileHeader, (ipFilePtr, iHeaderChunkSize));
    185             if (ipFileHeader != NULL)
    186             {
    187                 iError = ipFileHeader->GetStatus();
    188                 if (iError != PV_AVI_FILE_PARSER_SUCCESS)
    189                 {
    190                     OSCL_DELETE(ipFileHeader);
    191                     ipFileHeader = NULL;
    192                     break;
    193                 }
    194             }
    195             bytesRead += iHeaderChunkSize;
    196             if (bytesRead > iFileSize)
    197             {
    198                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    199                 break;
    200             }
    201         }
    202         else if (MOVI == chunkType)
    203         {
    204             PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Found MOVI Chunk"));
    205 
    206             iMovieChunkSize = listSize - CHUNK_SIZE;
    207             iMovieChunkStartOffset = ipFilePtr->Tell();     //get movi chunk start offset.
    208             iSampleOffset = iMovieChunkStartOffset;
    209             ipFilePtr->Seek(iMovieChunkSize, Oscl_File::SEEKCUR);
    210 
    211             uint32 numStr = GetNumStreams();
    212             for (uint32 ii = 0; ii < numStr; ii++)
    213             {
    214                 iStreamCount.push_back(ii);
    215                 iStreamSampleCount.push_back(0);
    216             }
    217 
    218             bytesRead += iMovieChunkSize;
    219 
    220         }
    221         else if (IDX1 == chunkType)
    222         {
    223             PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Found Index Table"));
    224 
    225             if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, iIndxChunkSize, true))
    226             {
    227                 iError = PV_AVI_FILE_PARSER_READ_ERROR;
    228                 break;
    229             }
    230 
    231             bytesRead += CHUNK_SIZE;
    232             if (bytesRead > iFileSize)
    233             {
    234                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    235                 break;
    236             }
    237 
    238             if ((iIndxChunkSize <= 0) || (iIndxChunkSize > iFileSize))
    239             {
    240                 iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
    241                 break;
    242             }
    243             uint32 numStreams = GetNumStreams();
    244             ipIdxChunk = OSCL_NEW(PVAviFileIdxChunk, (ipFilePtr, iIndxChunkSize, numStreams));
    245             if (ipIdxChunk != NULL)
    246             {
    247                 iError = ipIdxChunk->GetStatus();
    248                 if (iError != PV_AVI_FILE_PARSER_SUCCESS)
    249                 {
    250                     OSCL_DELETE(ipIdxChunk);
    251                     ipIdxChunk = NULL;
    252                     break;
    253                 }
    254                 iIdxChunkPresent = true;
    255             }
    256             bytesRead += iIndxChunkSize;
    257         }
    258         else if (JUNK == chunkType)
    259         {
    260             PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Skip Junk data"));
    261 
    262             uint32 junkSize = 0;
    263             if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, junkSize, true))
    264             {
    265                 iError = PV_AVI_FILE_PARSER_READ_ERROR;
    266                 break;
    267             }
    268 
    269             bytesRead += CHUNK_SIZE;
    270             if (bytesRead > iFileSize)
    271             {
    272                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    273                 break;
    274             }
    275 
    276             if ((junkSize <= 0) || (junkSize > iFileSize))
    277             {
    278                 iError = PV_AVI_FILE_PARSER_WRONG_SIZE;
    279                 break;
    280             }
    281 
    282             ipFilePtr->Seek(junkSize, Oscl_File::SEEKCUR);
    283             bytesRead += junkSize;
    284             if (bytesRead > iFileSize)
    285             {
    286                 iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    287                 break;
    288             }
    289         }
    290         else
    291         {
    292             iError = PV_AVI_FILE_PARSER_WRONG_CHUNK;
    293             break;
    294         }
    295 
    296     }   //while (bytesRead <= iFileSize)
    297 
    298     return iError;
    299 }
    300 
    301 PV_AVI_FILE_PARSER_ERROR_TYPE
    302 PVAviFileParser::GetNextMediaSample(uint32& arStreamNo, uint8* aBuffer,
    303                                     uint32& arSize, uint32& arTimeStamp)
    304 {
    305     if (iSampleOffset >= iFileSize)
    306     {
    307         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Wrong offset"));
    308         return PV_AVI_FILE_PARSER_WRONG_OFFSET;
    309     }
    310 
    311     if (iSampleOffset == iMovieChunkStartOffset)
    312     {
    313         //first Sample reset sample count.
    314         for (uint32 ii = 0; ii < GetNumStreams(); ii++)
    315         {
    316             iStreamSampleCount[ii] = 0;
    317         }
    318 
    319         ipFilePtr->Seek(0, Oscl_File::SEEKSET);
    320     }
    321 
    322     uint32 CurrOff = ipFilePtr->Tell();
    323     if (CurrOff > iSampleOffset)
    324     {
    325         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Wrong offset"));
    326         return PV_AVI_FILE_PARSER_WRONG_OFFSET;
    327     }
    328 
    329     ipFilePtr->Seek((iSampleOffset - CurrOff), Oscl_File::SEEKCUR);
    330 
    331     uint32 bytesRead = 0;
    332     uint32 data = 0;
    333     if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, data))
    334     {
    335         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Read Error"));
    336         return PV_AVI_FILE_PARSER_READ_ERROR;
    337     }
    338 
    339     int32 strNo = PVAviFileParserUtils::GetStreamNumber(data);
    340     if (PV_AVI_FILE_PARSER_ERROR_UNKNOWN == strNo)
    341     {
    342         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Wrong Stream No"));
    343         return PV_AVI_FILE_PARSER_ERROR_WRONG_STREAM_NUM;
    344     }
    345 
    346     arStreamNo = strNo;
    347 
    348     bytesRead += CHUNK_SIZE;
    349 
    350     uint32 size = 0;
    351     if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, size, true))
    352     {
    353         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: File Read Error"));
    354         return PV_AVI_FILE_PARSER_READ_ERROR;
    355     }
    356 
    357     bytesRead += CHUNK_SIZE;
    358 
    359     if (size > arSize)
    360     {
    361         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Insufficient Buffer Size"));
    362         return PV_AVI_FILE_PARSER_INSUFFICIENT_MEMORY;
    363     }
    364 
    365     arSize = size;
    366 
    367     if (PVAviFileParserUtils::read8(ipFilePtr, aBuffer, arSize) != arSize)
    368     {
    369         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: File Read Error"));
    370         return PV_AVI_FILE_PARSER_READ_ERROR;
    371     }
    372 
    373     iSampleOffset = iSampleOffset + arSize + bytesRead;
    374 
    375     uint32 offsetFrmMoviChk = iSampleOffset - iMovieChunkStartOffset;
    376 
    377     if (offsetFrmMoviChk >= iMovieChunkSize)
    378     {
    379         PVAVIFILE_LOGINFO((0, "PVAviFileParser::GetNextMediaSample: EOF Reached"));
    380         return PV_AVI_FILE_PARSER_EOF_REACHED;
    381     }
    382 
    383     //calculate time stamp
    384     if (oscl_strstr(GetStreamMimeType(arStreamNo).get_str(), "audio"))
    385     {
    386         arTimeStamp = iTimeStampAudio;
    387         uint32 sampleSize = GetBitsPerSample(arStreamNo);
    388         sampleSize = sampleSize / BIT_COUNT8; //in bytes
    389         OsclFloat  samplingRate = GetFrameRate(arStreamNo);
    390         if (sampleSize > 0)
    391         {
    392             OsclFloat  sampleCount = (OsclFloat)arSize / sampleSize;
    393             if (samplingRate > 0)
    394             {
    395                 iTimeStampAudio += (uint32)((sampleCount * 1000) / samplingRate);
    396             }
    397         }
    398     }
    399     else
    400     {
    401         if (iStreamSampleCount[arStreamNo] > 0)
    402         {
    403             uint32 frameDurationInms = GetFrameDuration() / 1000;
    404             arTimeStamp = (iStreamSampleCount[arStreamNo] * (frameDurationInms));
    405         }
    406         else
    407         {
    408             arTimeStamp = 0;
    409         }
    410     }
    411 
    412     iStreamSampleCount[arStreamNo] = iStreamSampleCount[arStreamNo] + 1;
    413     return PV_AVI_FILE_PARSER_SUCCESS;
    414 }
    415 
    416 
    417 PV_AVI_FILE_PARSER_ERROR_TYPE
    418 PVAviFileParser::GetNextStreamSampleInfo(uint32 aStreamNo, uint32& arSize, uint32& arOffset)
    419 {
    420     if (false == iIdxChunkPresent)
    421     {
    422         return PV_AVI_FILE_PARSER_NO_INDEX_CHUNK;
    423     }
    424     else
    425     {
    426         return GetStreamOffsetFromIndexTable(aStreamNo, arSize, arOffset);
    427     }
    428 }
    429 
    430 PV_AVI_FILE_PARSER_ERROR_TYPE
    431 PVAviFileParser::GetNextStreamMediaSample(uint32 aStreamNo, uint8* aBuffer,
    432         uint32& arSize, uint32& arTimeStamp)
    433 {
    434     uint32 sampleOffset = 0;
    435     PV_AVI_FILE_PARSER_ERROR_TYPE error = PV_AVI_FILE_PARSER_SUCCESS;
    436 
    437     if (false == iIdxChunkPresent)
    438     {
    439         error = GetStreamOffset(aStreamNo, arSize, sampleOffset);
    440 
    441         if ((error != PV_AVI_FILE_PARSER_SUCCESS))
    442         {
    443             if (PV_AVI_FILE_PARSER_NO_OFFSET_FOUND == error)
    444             {
    445                 arSize = 0;
    446                 arTimeStamp = 0;
    447                 //probably EOS has been reached.
    448                 return PV_AVI_FILE_PARSER_EOS_REACHED;
    449             }
    450             else
    451             {
    452                 return error;
    453             }
    454         }
    455 
    456         uint32 offsetFrmMoviChk = sampleOffset - iMovieChunkStartOffset;
    457         if (offsetFrmMoviChk >= iMovieChunkSize)
    458         {
    459             PVAVIFILE_LOGINFO((0, "PVAviFileParser::GetNextStreamMediaSample: EOF Reached"));
    460             return PV_AVI_FILE_PARSER_EOF_REACHED;
    461         }
    462     }
    463     else
    464     {
    465         error = GetStreamOffsetFromIndexTable(aStreamNo, arSize, sampleOffset);
    466         if (error != PV_AVI_FILE_PARSER_SUCCESS)
    467         {
    468             return error;
    469         }
    470     }
    471 
    472     if (PVAviFileParserUtils::read8(ipFilePtr, aBuffer, arSize) != arSize)
    473     {
    474         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: File Read Error"));
    475         return PV_AVI_FILE_PARSER_READ_ERROR;
    476     }
    477 
    478     //calculate time stamp
    479     if (oscl_strstr(GetStreamMimeType(aStreamNo).get_str(), "audio"))
    480     {
    481         arTimeStamp = iTimeStampAudio;
    482         uint32 sampleSize = GetBitsPerSample(aStreamNo);
    483         sampleSize = sampleSize / BIT_COUNT8; //in bytes
    484         OsclFloat samplingRate = GetFrameRate(aStreamNo);
    485         if (sampleSize > 0)
    486         {
    487             OsclFloat sampleCount = (OsclFloat)arSize / sampleSize;
    488             if (samplingRate > 0)
    489             {
    490                 iTimeStampAudio += (uint32)((sampleCount * 1000) / samplingRate);
    491             }
    492         }
    493     }
    494     else
    495     {
    496         if (iStreamSampleCount[aStreamNo] > 0)
    497         {
    498             uint32 frameDurationInms = GetFrameDuration() / 1000;
    499             arTimeStamp = (iStreamSampleCount[aStreamNo] * (frameDurationInms));
    500         }
    501         else
    502         {
    503             arTimeStamp = 0;
    504         }
    505     }
    506 
    507     iStreamSampleCount[aStreamNo] = iStreamSampleCount[aStreamNo] + 1;
    508 
    509     return PV_AVI_FILE_PARSER_SUCCESS;
    510 }
    511 
    512 
    513 PV_AVI_FILE_PARSER_ERROR_TYPE
    514 PVAviFileParser::GetStreamOffsetFromIndexTable(uint32 aStreamNo, uint32& arSize, uint32& arOffset)
    515 {
    516     uint32 sampleOffset = 0;
    517 
    518     if (iStreamSampleCount[aStreamNo] >= ipIdxChunk->GetNumberOfSamplesInStream(aStreamNo))
    519     {
    520         PVAVIFILE_LOGINFO((0, "PVAviFileParser::GetNextMediaSample: EOF Reached"));
    521         return PV_AVI_FILE_PARSER_EOS_REACHED;
    522     }
    523 
    524     sampleOffset = ipIdxChunk->GetOffset(aStreamNo, iStreamSampleCount[aStreamNo]);
    525     uint32 size = ipIdxChunk->GetSampleSize(aStreamNo, iStreamSampleCount[aStreamNo]);
    526 
    527     if (size > arSize)
    528     {
    529         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Insufficient Buffer Size"));
    530         return PV_AVI_FILE_PARSER_INSUFFICIENT_MEMORY;
    531     }
    532 
    533     arSize = size;
    534 
    535     if (ipIdxChunk->IsOffsetFromMoviList())
    536     {
    537         arOffset = iMovieChunkStartOffset + sampleOffset - CHUNK_SIZE;
    538     }
    539     else
    540     {
    541         arOffset = sampleOffset;
    542     }
    543 
    544     arOffset += (CHUNK_SIZE + CHUNK_SIZE); //add 4 bytes each for sample type and data size param.
    545 
    546     if ((arOffset > iFileSize))
    547     {
    548         PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: File Size & Byte Count mismatch"));
    549         return PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
    550     }
    551 
    552     ipFilePtr->Seek(0, Oscl_File::SEEKSET);
    553     ipFilePtr->Seek(arOffset, Oscl_File::SEEKCUR);
    554 
    555     return PV_AVI_FILE_PARSER_SUCCESS;
    556 }
    557 
    558 
    559 PV_AVI_FILE_PARSER_ERROR_TYPE
    560 PVAviFileParser::GetStreamOffset(uint32 aStreamNo, uint32& arSampleSize, uint32& arOffset)
    561 {
    562     uint32 startOffset = 0;
    563     arOffset = 0;
    564     bool foundOffset = false;
    565 
    566     if (iStreamSampleOffset.size() == 0)
    567     {
    568         uint32 numstreams = GetNumStreams();
    569         startOffset = iMovieChunkStartOffset;
    570 
    571         for (uint32 ii = 0; ii < numstreams; ii++)
    572         {
    573             iStreamSampleOffset.push_back(startOffset);
    574         }
    575     }
    576     else
    577     {
    578         startOffset = iStreamSampleOffset[aStreamNo];
    579     }
    580 
    581     ipFilePtr->Seek(startOffset, Oscl_File::SEEKSET);
    582     uint32 currentFileOffset = startOffset;
    583 
    584     uint32 endOfdataPosition = iMovieChunkStartOffset + iMovieChunkSize;
    585 
    586     while (currentFileOffset < endOfdataPosition)
    587     {
    588         uint32 data = 0;
    589         if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, data))
    590         {
    591             PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Read Error"));
    592             return PV_AVI_FILE_PARSER_READ_ERROR;
    593         }
    594 
    595         int32 strNo = PVAviFileParserUtils::GetStreamNumber(data);
    596         if (PV_AVI_FILE_PARSER_ERROR_UNKNOWN == strNo)
    597         {
    598             PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Wrong Stream No"));
    599             return PV_AVI_FILE_PARSER_ERROR_WRONG_STREAM_NUM;
    600         }
    601 
    602         uint32 size = 0;
    603         if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(ipFilePtr, size, true))
    604         {
    605             PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: File Read Error"));
    606             return PV_AVI_FILE_PARSER_READ_ERROR;
    607         }
    608 
    609         if ((uint32)strNo == aStreamNo)
    610         {
    611             arOffset = ipFilePtr->Tell();
    612             iStreamSampleOffset[aStreamNo] = arOffset + size;
    613             if (size > arSampleSize)
    614             {
    615                 PVAVIFILE_LOGERROR((0, "PVAviFileParser::GetNextMediaSample: Insufficient Buffer Size"));
    616                 return PV_AVI_FILE_PARSER_INSUFFICIENT_MEMORY;
    617             }
    618 
    619             arSampleSize = size;
    620             foundOffset = true;
    621             break;
    622         }
    623         else
    624         {
    625             ipFilePtr->Seek(size, Oscl_File::SEEKCUR);
    626             foundOffset = false;
    627         }
    628 
    629         currentFileOffset = ipFilePtr->Tell();
    630     }
    631 
    632     if (foundOffset)
    633     {
    634         return PV_AVI_FILE_PARSER_SUCCESS;
    635     }
    636     else
    637     {
    638         return PV_AVI_FILE_PARSER_NO_OFFSET_FOUND;
    639     }
    640 }
    641 
    642 OSCL_EXPORT_REF void PVAviFileParser::Reset()
    643 {
    644     PVAVIFILE_LOGINFO((0, "PVAviFileParser::Reset"));
    645 
    646     uint32 ii = 0;
    647     for (ii = 0; ii < GetNumStreams(); ii++)
    648     {
    649         iStreamSampleCount[ii] = 0;
    650     }
    651 
    652     if (iStreamSampleOffset.size() > 0)
    653     {
    654         for (ii = 0; ii < iStreamSampleOffset.size(); ii++)
    655         {
    656             iStreamSampleOffset.pop_back();
    657         }
    658     }
    659 
    660     iSampleOffset = iMovieChunkStartOffset;
    661     iTimeStampAudio = 0;
    662 }
    663 
    664 OSCL_EXPORT_REF void PVAviFileParser::Reset(uint32 aStreamNo)
    665 {
    666     PVAVIFILE_LOGINFO((0, "PVAviFileParser::Reset stream"));
    667 
    668     iStreamSampleCount[aStreamNo] = 0;
    669 
    670     if (iStreamSampleOffset.size() > aStreamNo)
    671     {
    672         iStreamSampleOffset[aStreamNo] = iMovieChunkStartOffset;
    673     }
    674 
    675     if (oscl_strstr(GetStreamMimeType(aStreamNo).get_str(), "audio"))
    676     {
    677         iTimeStampAudio = 0;
    678     }
    679 }
    680 
    681 OSCL_EXPORT_REF bool PVAviFileParser::GetFormatSpecificInfo(uint32 aStreamNum, OsclRefCounterMemFrag& arFormatSpecificDataFrag)
    682 {
    683     uint8* buff = NULL;
    684     uint32 len = 0;
    685 
    686     ipFileHeader->GetFormatSpecificInfo(aStreamNum, buff, len);
    687 
    688     if ((buff == NULL) || (len == 0))
    689     {
    690         return false;
    691     }
    692 
    693     OsclMemAllocDestructDealloc<uint8> my_alloc;
    694     OsclRefCounter* my_refcnt;
    695 
    696     uint aligned_refcnt_size =
    697         oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
    698 
    699     uint8* my_ptr = NULL;
    700     int32 errcode = 0;
    701     OSCL_TRY(errcode, my_ptr = (uint8*) oscl_malloc(aligned_refcnt_size + len));
    702 
    703     if (errcode != OsclErrNone)
    704     {
    705         return false;
    706     }
    707 
    708     my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
    709     my_ptr += aligned_refcnt_size;
    710 
    711     oscl_memcpy(my_ptr, buff, len);
    712 
    713     OsclMemoryFragment memfrag;
    714     memfrag.len = len;
    715     memfrag.ptr = my_ptr;
    716 
    717     OsclRefCounterMemFrag refcntMemFrag(memfrag, my_refcnt, memfrag.len);
    718     arFormatSpecificDataFrag = refcntMemFrag;
    719     return true;
    720 
    721 }
    722 
    723 //method to get codec specific info
    724 OSCL_EXPORT_REF bool PVAviFileParser::GetCodecSpecificData(uint32 aStreamNum, OsclRefCounterMemFrag& arFormatSpecificDataFrag)
    725 {
    726     uint8* buff = NULL;
    727     uint32 len = 0;
    728     ipFileHeader->GetCodecSpecificData(aStreamNum, buff, len);
    729 
    730     if ((buff == NULL) || (len == 0))
    731     {
    732         return false;
    733     }
    734 
    735     OsclMemAllocDestructDealloc<uint8> my_alloc;
    736     OsclRefCounter* my_refcnt;
    737 
    738     uint aligned_refcnt_size =
    739         oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
    740 
    741     uint8* my_ptr = NULL;
    742     int32 errcode = 0;
    743     OSCL_TRY(errcode, my_ptr = (uint8*) oscl_malloc(aligned_refcnt_size + len));
    744 
    745     if (errcode != OsclErrNone)
    746     {
    747         return false;
    748     }
    749 
    750     my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
    751     my_ptr += aligned_refcnt_size;
    752 
    753     oscl_memcpy(my_ptr, buff, len);
    754 
    755     OsclMemoryFragment memfrag;
    756     memfrag.len = len;
    757     memfrag.ptr = my_ptr;
    758 
    759     OsclRefCounterMemFrag refcntMemFrag(memfrag, my_refcnt, memfrag.len);
    760     arFormatSpecificDataFrag = refcntMemFrag;
    761     return true;
    762 }
    763 
    764 PVAviFileParser::~PVAviFileParser()
    765 {
    766     if (NULL != ipFileHeader)
    767     {
    768         OSCL_DELETE(ipFileHeader);
    769         ipFileHeader = NULL;
    770     }
    771 
    772     if (NULL != ipIdxChunk)
    773     {
    774         OSCL_DELETE(ipIdxChunk);
    775         ipIdxChunk = NULL;
    776     }
    777 
    778     if (ipFilePtr->IsOpen())
    779     {
    780         ipFilePtr->Close();
    781     }
    782 
    783     OSCL_DELETE(ipFilePtr);
    784 }
    785 
    786 uint32 PVAviFileParser::GetFileSuggestedBufferSize()
    787 {
    788     uint32 buffSz = ipFileHeader->GetFileSuggestedBufferSize();
    789     if (0 == buffSz)
    790     {
    791         uint32 numStr = ipFileHeader->GetNumStreams();
    792         for (uint32 ii = 0; ii < numStr; ii++)
    793         {
    794             uint32 strSz = ipFileHeader->GetStreamSuggestedBufferSize(ii);
    795             if (buffSz < strSz)
    796             {
    797                 buffSz = strSz;
    798             }
    799         }
    800     }
    801     return buffSz;
    802 }
    803 
    804 bool PVAviFileParser::GetVideoFormatType(uint8* aHdlr, uint32& arSize, uint32 aStreamNo)
    805 {
    806     uint32 numstr = GetNumStreams();
    807     uint32 ii = 0;
    808     bool retTyp = false;
    809     for (ii = 0; ii < numstr; ii++)
    810     {
    811         if ((oscl_strstr((GetStreamMimeType(ii)).get_cstr(), "video")) && (aStreamNo == ii))
    812         {
    813             ipFileHeader->GetHandlerType(ii, aHdlr, arSize);
    814             retTyp = true;
    815         }
    816     }
    817     return retTyp;
    818 }
    819 
    820 OSCL_EXPORT_REF Oscl_Vector<uint32, OsclMemAllocator> PVAviFileParser::GetAudioStreamCountList()
    821 {
    822     uint32 ii = 0;
    823     Oscl_Vector<uint32, OsclMemAllocator> audioStrNum;
    824     for (ii = 0; ii < GetNumStreams(); ii++)
    825     {
    826         if (oscl_strstr((GetStreamMimeType(ii)).get_cstr(), "audio"))
    827         {
    828             audioStrNum.push_back(ii);
    829         }
    830     }
    831 
    832     return audioStrNum;
    833 }
    834 
    835 OSCL_EXPORT_REF Oscl_Vector<uint32, OsclMemAllocator> PVAviFileParser::GetVideoStreamCountList()
    836 {
    837     uint32 ii = 0;
    838     Oscl_Vector<uint32, OsclMemAllocator> vidStrNum;
    839     for (ii = 0; ii < GetNumStreams(); ii++)
    840     {
    841         if (oscl_strstr((GetStreamMimeType(ii)).get_cstr(), "video"))
    842         {
    843             vidStrNum.push_back(ii);
    844         }
    845     }
    846 
    847     return vidStrNum;
    848 }
    849 
    850 OSCL_EXPORT_REF uint32 PVAviFileParser::GetFileDuration()
    851 {
    852     uint32 frameDuration = ipFileHeader->GetFrameDuration();
    853     uint32 totalFrames = ipFileHeader->GetTotalFrames();
    854     uint32 fileDuration = (uint32)((OsclFloat)(frameDuration * totalFrames) / 1000000.0); //in seconds
    855     return fileDuration;
    856 }
    857 
    858 OSCL_EXPORT_REF PVAviFileStreamHeaderStruct
    859 PVAviFileParser::GetStreamHeaderStruct(uint32 aStreamNum)
    860 {
    861     return (ipFileHeader->GetStreamHeaderStruct(aStreamNum));
    862 }
    863 
    864 OSCL_EXPORT_REF uint32 PVAviFileParser::GetNumStreams()
    865 {
    866     return (ipFileHeader->GetNumStreams());
    867 }
    868 
    869 OSCL_EXPORT_REF OSCL_HeapString<OsclMemAllocator>
    870 PVAviFileParser::GetStreamMimeType(uint32 aStreamNum)
    871 {
    872     return (ipFileHeader->GetStreamMimeType(aStreamNum));
    873 }
    874 
    875 OSCL_EXPORT_REF uint32 PVAviFileParser::GetWidth(int32 aStreamNo)
    876 {
    877     return (ipFileHeader->GetWidth(aStreamNo));
    878 }
    879 
    880 OSCL_EXPORT_REF uint32 PVAviFileParser::GetHeight(bool& rBottomUp, int32 aStreamNo)
    881 {
    882     return (ipFileHeader->GetHeight(rBottomUp, aStreamNo));
    883 }
    884 
    885 OSCL_EXPORT_REF uint32 PVAviFileParser::GetFrameDuration()
    886 {
    887     return (ipFileHeader->GetFrameDuration());
    888 }
    889 
    890 OSCL_EXPORT_REF OsclFloat PVAviFileParser::GetFrameRate(uint32 aStreamNum)
    891 {
    892     return (ipFileHeader->GetSamplingRate(aStreamNum));
    893 }
    894 
    895 OSCL_EXPORT_REF uint32 PVAviFileParser::GetStreamDuration(uint32 aStreamNum)
    896 {
    897     return (ipFileHeader->GetStreamDuration(aStreamNum));
    898 }
    899