Пример #1
0
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)

}