blob: ac17e904eb3a4022a72260af9173ece111c94d60 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#include "pv_avifile_streamlist.h"
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 = (uint8*)oscl_malloc(iCodecSpecificHdrDataSize);
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 (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);
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)
}
PV_AVI_FILE_PARSER_ERROR_TYPE
PVAviFileStreamlist::ParseStreamHeader(PVFile *aFp, uint32 aHdrSize)
{
uint32 bytesRead = 0;
if (PV_AVI_FILE_PARSER_SUCCESS != PVAviFileParserUtils::read32(aFp, iStreamHdr.iStreamTypeFCC))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (0 == (PVAviFileParserUtils::read8(aFp, iStreamHdr.iStreamHandler, CHUNK_SIZE)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iFlags)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (iStreamHdr.iFlags != 0)
{
if (iStreamHdr.iFlags & AVISF_VIDEO_PALCHANGES)
iStreamHdr.iIsVidPalChangeAvailable = true;
if (iStreamHdr.iFlags & AVISF_DISABLED)
iStreamHdr.iAVISF_Disabled = true;
}
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.iPriority, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(iStreamHdr.iPriority);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.iLanguage, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(iStreamHdr.iPriority);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iInitFrames, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iScale, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iRate, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iStart, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iLength, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iSugBufSize, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iQuality, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamHdr.iSampleSize, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (bytesRead > aHdrSize)
{
return PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
}
else if (bytesRead == aHdrSize)
{
return PV_AVI_FILE_PARSER_SUCCESS;
}
else // read rcFrame
{
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.ircFrame.left, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
else
{
bytesRead += sizeof(uint16);
}
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.ircFrame.top, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
else
{
bytesRead += sizeof(uint16);
}
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.ircFrame.right, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
else
{
bytesRead += sizeof(uint16);
}
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamHdr.ircFrame.bottom, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
else
{
bytesRead += sizeof(uint16);
}
}
if (bytesRead != aHdrSize)
{
return PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
}
iStreamHdr.iSamplingRate = iStreamHdr.iRate / iStreamHdr.iScale;
return PV_AVI_FILE_PARSER_SUCCESS;
}
PV_AVI_FILE_PARSER_ERROR_TYPE
PVAviFileStreamlist::ParseStreamFormat(PVFile *aFp, uint32 aHdrSize)
{
uint32 bytesRead = 0;
switch (iStreamHdr.iStreamTypeFCC)
{
case AUDS:
{
iStreamFmt.iType = AUDIO;
}
break;
case VIDS:
{
iStreamFmt.iType = VIDEO;
}
break;
case MIDI:
{
iStreamFmt.iType = MIDI;
}
break;
case TXTS:
{
iStreamFmt.iType = TEXT;
}
break;
default:
{
return PV_AVI_FILE_PARSER_ERROR_STREAM_TYPE_UNKNOWN;
}
}
; //end switch
if (iStreamFmt.iType == AUDIO)
{
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iAudWaveFormatEx.FormatTag, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iAudWaveFormatEx.Channels, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iAudWaveFormatEx.SamplesPerSec, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iAudWaveFormatEx.AvgBytesPerSec, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iAudWaveFormatEx.BlockAlign, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iAudWaveFormatEx.BitsPerSample, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (bytesRead < aHdrSize)
{
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iAudWaveFormatEx.Size, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
}
else
{
iStreamFmt.iAudWaveFormatEx.Size = 0;
}
}
else if (iStreamFmt.iType == VIDEO)
{
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiSize, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiWidth, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiHeight, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiPlanes, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read16(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiBitCount, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += sizeof(uint16);
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiCompression, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiSizeImage, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiXPelsPerMeter, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiYPelsPerMeter, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiClrUsed, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
if (PV_AVI_FILE_PARSER_SUCCESS != (PVAviFileParserUtils::read32(aFp, iStreamFmt.iVidBitMapInfo.BmiHeader.BiClrImportant, true)))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
bytesRead += CHUNK_SIZE;
//get the color table size
uint32 colorTblSize = iStreamFmt.iVidBitMapInfo.BmiHeader.BiClrUsed;
if (colorTblSize == 0)
{
switch (iStreamFmt.iVidBitMapInfo.BmiHeader.BiBitCount)
{
case BIT_COUNT1:
{
colorTblSize = 2;
}
break;
case BIT_COUNT2:
{
colorTblSize = 4;
}
break;
case BIT_COUNT4:
{
colorTblSize = 16;
}
break;
case BIT_COUNT8:
{
colorTblSize = 256;
}
break;
case BIT_COUNT16:
case BIT_COUNT32:
{
if (BI_BITFIELDS == iStreamFmt.iVidBitMapInfo.BmiHeader.BiCompression)
{
colorTblSize = 3;
}
else if (BI_ALPHABITFIELDS == iStreamFmt.iVidBitMapInfo.BmiHeader.BiCompression)
{
colorTblSize = 4;
}
else if (BI_RGB == iStreamFmt.iVidBitMapInfo.BmiHeader.BiCompression)
{
colorTblSize = 0;
}
}
break;
case BIT_COUNT24:
{
colorTblSize = 0;
}
break;
default:
return PV_AVI_FILE_PARSER_WRONG_BIT_COUNT;
} //switch
}
iStreamFmt.iVidBitMapInfo.BmiColorsCount = colorTblSize;
uint32 length = 1;
//get color table entries
for (uint32 ii = 0; ii < colorTblSize; ii++)
{
if (length != PVAviFileParserUtils::read8(aFp, &(iStreamFmt.iVidBitMapInfo.BmiColors[ii].Blue), length))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
if (length != PVAviFileParserUtils::read8(aFp, &(iStreamFmt.iVidBitMapInfo.BmiColors[ii].Green), length))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
if (length != PVAviFileParserUtils::read8(aFp, &(iStreamFmt.iVidBitMapInfo.BmiColors[ii].Red), length))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
if (length != PVAviFileParserUtils::read8(aFp, &(iStreamFmt.iVidBitMapInfo.BmiColors[ii].Reserved), length))
{
return PV_AVI_FILE_PARSER_READ_ERROR;
}
}
bytesRead += colorTblSize * sizeof(RGBQuad);
}
if (bytesRead != aHdrSize)
{
return PV_AVI_FILE_PARSER_BYTE_COUNT_ERROR;
}
return PV_AVI_FILE_PARSER_SUCCESS;
}
OSCL_HeapString<OsclMemAllocator> PVAviFileStreamlist::GetStreamMimeType()
{
OSCL_HeapString<OsclMemAllocator> mime_str;
if (AUDS == iStreamHdr.iStreamTypeFCC)
{
mime_str = "audio";
}
else if (VIDS == iStreamHdr.iStreamTypeFCC)
{
mime_str = "video";
}
else if (MIDS == iStreamHdr.iStreamTypeFCC)
{
mime_str = "midi";
}
else if (TXTS == iStreamHdr.iStreamTypeFCC)
{
mime_str = "text";
}
else
{
return 0;
}
return mime_str;
}
bool PVAviFileStreamlist::GetHandlerType(uint8* aHdlr, uint32& aSize)
{
if (aSize < CHUNK_SIZE)
{
return false;
}
oscl_memcpy(aHdlr, iStreamHdr.iStreamHandler, CHUNK_SIZE);
aSize = CHUNK_SIZE;
return true;
}
uint32 PVAviFileStreamlist::GetBitsPerSample()
{
if (AUDIO == iStreamFmt.iType)
{
return (iStreamFmt.iAudWaveFormatEx).BitsPerSample;
}
else if (VIDEO == iStreamFmt.iType)
{
return (iStreamFmt.iVidBitMapInfo).BmiHeader.BiBitCount;
}
else
{
return 0;
}
}
uint32 PVAviFileStreamlist::GetAudioFormat()
{
if (AUDIO == iStreamFmt.iType)
{
return (iStreamFmt.iAudWaveFormatEx).FormatTag;
}
else
{
return WAVE_FORMAT_UNKNOWN;
}
}
uint32 PVAviFileStreamlist::GetNumAudioChannels()
{
if (AUDIO == iStreamFmt.iType)
{
return (iStreamFmt.iAudWaveFormatEx).Channels;
}
else
{
return 0;
}
}
uint32 PVAviFileStreamlist::GetVideoWidth()
{
if (VIDEO == iStreamFmt.iType)
{
return (iStreamFmt.iVidBitMapInfo).BmiHeader.BiWidth;
}
else
{
return 0;
}
}
uint32 PVAviFileStreamlist::GetVideoHeight(bool& rBottomUp)
{
if (VIDEO == iStreamFmt.iType)
{
int32 height = (iStreamFmt.iVidBitMapInfo).BmiHeader.BiHeight;
if (height < 0) //negative height
{
rBottomUp = false;
height = oscl_abs(height);
}
else
{
rBottomUp = true;
}
return ((uint32)height);
}
else
{
return 0;
}
}
bool PVAviFileStreamlist::GetFormatSpecificInfo(uint8*& aBuff, uint32& aSize)
{
if (AUDIO == iStreamFmt.iType)
{
aSize = sizeof(WaveFormatExStruct);
aBuff = OSCL_STATIC_CAST(uint8*, &(iStreamFmt.iAudWaveFormatEx));
}
else if (VIDEO == iStreamFmt.iType)
{
aSize = sizeof(BitmapInfoHhr) + (sizeof(RGBQuad) * iStreamFmt.iVidBitMapInfo.BmiColorsCount);
aBuff = OSCL_STATIC_CAST(uint8*, &(iStreamFmt.iVidBitMapInfo));
}
else
{
return false;
}
return true;
}
bool PVAviFileStreamlist::GetCodecSpecificData(uint8*& aBuff, uint32& aSize)
{
if (iCodecSpecificHdrDataSize > 0)
{
aBuff = ipCodecSpecificHdrData;
aSize = iCodecSpecificHdrDataSize;
}
else
{
return false;
}
return true;
}