PVAviFileHeader::PVAviFileHeader(PVFile *aFp, uint32 aHdrSize) { iHeaderTotalSize = aHdrSize; uint32 bytesRead = 0; uint32 chunkType = 0; uint32 oldChkType = 0; iError = PV_AVI_FILE_PARSER_SUCCESS; for (uint32 ii = 0; ii < iStreamList.size(); ii++) { iStreamList.pop_back(); } uint32 streamListSz = 0; while (bytesRead < iHeaderTotalSize) { oldChkType = chunkType; if ((iError = PVAviFileParserUtils::ReadNextChunkType(aFp, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS) { if ((PV_AVI_FILE_PARSER_UNSUPPORTED_CHUNK == iError)) { PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Unsupported chunk")); uint32 chksz = 0; if (oldChkType != LIST) { //get the size of unsupported chunk and skip it. if (PVAviFileParserUtils::read32(aFp, chksz, true) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } aFp->Seek(chksz, Oscl_File::SEEKCUR); bytesRead += chksz + CHUNK_SIZE + CHUNK_SIZE; //data + chunk size + chunk type } else { //skip the entire list if not supported aFp->Seek((streamListSz - CHUNK_SIZE), Oscl_File::SEEKCUR); //subtract list name read above bytesRead += streamListSz; } PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Unsupported chunk skipped")); iError = PV_AVI_FILE_PARSER_SUCCESS; continue; } else { break; } } bytesRead += CHUNK_SIZE; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if (AVIH == chunkType) { uint32 aviStrSize = 0; if (PVAviFileParserUtils::read32(aFp, aviStrSize, true) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((aviStrSize <= 0) || (aviStrSize > iHeaderTotalSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: AVIH size greater than file header size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } if ((iError = ParseMainHeader(aFp)) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Error encountered while parsing File Header")); break; } bytesRead += aviStrSize; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else if (LIST == chunkType) { if (PVAviFileParserUtils::read32(aFp, streamListSz, true) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((streamListSz <= 0) || (streamListSz > iHeaderTotalSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: stream list soze greater tha file header size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } } else if (STRL == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileHeader::PVAviFileHeader: Found stream list")); PVAviFileStreamlist* strlst = OSCL_NEW(PVAviFileStreamlist, (aFp, (streamListSz - CHUNK_SIZE))); //subtract 4 bytes of List type from list size if (strlst != NULL) { if ((iError = strlst->GetStatus()) != PV_AVI_FILE_PARSER_SUCCESS) { OSCL_DELETE(strlst); strlst = NULL; break; } } iStreamList.push_back(*strlst); bytesRead += streamListSz - CHUNK_SIZE; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } OSCL_DELETE(strlst); } else if (JUNK == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileParser::ParseFile: Skip Junk data")); uint32 junkSize = 0; if (PVAviFileParserUtils::read32(aFp, junkSize, true) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((junkSize <= 0) || (junkSize > iHeaderTotalSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Junk data size more than file header size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } aFp->Seek(junkSize, Oscl_File::SEEKCUR); bytesRead += junkSize; if (bytesRead > iHeaderTotalSize) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: File Size & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: Chunk not supported in file main header")); iError = PV_AVI_FILE_PARSER_WRONG_CHUNK; break; } } if ((PV_AVI_FILE_PARSER_SUCCESS == iError) && (iStreamList.size() != iMainHeader.iStreams)) { PVAVIFILE_LOGERROR((0, "PVAviFileHeader::PVAviFileHeader: ")); iError = PV_AVI_FILE_PARSER_ERROR_NUM_STREAM; } }
PVAviFileStreamlist::PVAviFileStreamlist(PVFile *aFp, uint32 aStrListSz) { iCodecSpecificHdrDataSize = 0; iStreamListSize = aStrListSz; ipCodecSpecificHdrData = NULL; iError = PV_AVI_FILE_PARSER_SUCCESS; uint32 bytesRead = 0; uint32 chunkType = 0; while (bytesRead < iStreamListSize) { if ((iError = PVAviFileParserUtils::ReadNextChunkType(aFp, chunkType)) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Unsupported chunk")); if (PV_AVI_FILE_PARSER_UNSUPPORTED_CHUNK == iError) { uint32 chksz = 0; if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, chksz, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } aFp->Seek(chksz, Oscl_File::SEEKCUR); bytesRead += chksz + CHUNK_SIZE + CHUNK_SIZE; // data + chunk size + chunk type PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Unsupported Chunk Skipped")); iError = PV_AVI_FILE_PARSER_SUCCESS; continue; } else { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } } bytesRead += CHUNK_SIZE; if (STRH == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Found Stream Header")); uint32 aviStrhSize = 0; if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, aviStrhSize, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File & Byte Count mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((aviStrhSize <= 0) || (aviStrhSize > iStreamListSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: stream header size greater than stream list size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } if ((iError = ParseStreamHeader(aFp, aviStrhSize)) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: ParseStreamHeader function error")); break; } bytesRead += aviStrhSize; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else if (STRF == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Found Stream Format Header")); uint32 aviStrfSize = 0; if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, aviStrfSize, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((aviStrfSize <= 0) || (aviStrfSize > iStreamListSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: Stream Format Header Size Greater Than Stream List Size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } if ((iError = ParseStreamFormat(aFp, aviStrfSize)) != PV_AVI_FILE_PARSER_SUCCESS) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: ParseStreamFormat returned error")); break; } bytesRead += aviStrfSize; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else if (STRD == chunkType) { if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, iCodecSpecificHdrDataSize, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if ((iCodecSpecificHdrDataSize <= 0) || (iCodecSpecificHdrDataSize > iStreamListSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } ipCodecSpecificHdrData = NULL; ipCodecSpecificHdrData = (uint8*)oscl_malloc(iCodecSpecificHdrDataSize); if (!ipCodecSpecificHdrData) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: Unable to allocate memory.")); iError = PV_AVI_FILE_PARSER_INSUFFICIENT_MEMORY; break; } if (0 == PVAviFileParserUtils::read8(aFp, ipCodecSpecificHdrData, iCodecSpecificHdrDataSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += iCodecSpecificHdrDataSize; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else if (STRN == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Found stream name")); uint32 strnSz = 0; if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, strnSz, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (strnSz >= MAX_STRN_SZ) { uint8* strn = (uint8*)oscl_malloc(strnSz); if (!strn) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: Unable to allocate memory.")); iError = PV_AVI_FILE_PARSER_INSUFFICIENT_MEMORY; break; } if (PVAviFileParserUtils::read8(aFp, strn, strnSz) == 0) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } oscl_strncpy(iStreamName, (char*)strn, (MAX_STRN_SZ - 1)); iStreamName[MAX_STRN_SZ - 1] = '\0'; oscl_free(strn); } else { if (PVAviFileParserUtils::read8(aFp, (uint8*)iStreamName, strnSz) == 0) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } } bytesRead += strnSz; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else if (JUNK == chunkType) { PVAVIFILE_LOGINFO((0, "PVAviFileStreamlist::PVAviFileStreamlist: Skip Junk Data")); uint32 junkSize = 0; if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, junkSize, true)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Read Error")); iError = PV_AVI_FILE_PARSER_READ_ERROR; break; } bytesRead += CHUNK_SIZE; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } if ((junkSize <= 0) || (junkSize > iStreamListSize)) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: Junk data size more than stream list size")); iError = PV_AVI_FILE_PARSER_WRONG_SIZE; break; } aFp->Seek(junkSize, Oscl_File::SEEKCUR); bytesRead += junkSize; if (bytesRead > iStreamListSize) { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: File Size & Byte Count Mismatch")); iError = PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR; break; } } else { PVAVIFILE_LOGERROR((0, "PVAviFileStreamlist::PVAviFileStreamlist: Unexpected chunk in stream list")); iError = PV_AVI_FILE_PARSER_WRONG_CHUNK; break; } } //while(bytesRead <= iStreamListSize) }