/** * * File Name: armVCM4P2_GetVLCBits.c * OpenMAX DL: v1.0.2 * Revision: 9641 * Date: Thursday, February 7, 2008 * * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. * * * * Description: * Contains module for VLC get bits from the stream * */ #include "omxtypes.h" #include "armOMX.h" #include "armVC.h" #include "armCOMM.h" #include "armCOMM_Bitstream.h" #include "armVCM4P2_ZigZag_Tables.h" #include "armVCM4P2_Huff_Tables_VLC.h" /** * Function: armVCM4P2_GetVLCBits * * Description: * Performs escape mode decision based on the run, run+, level, level+ and * last combinations. * * Remarks: * * Parameters: * [in] ppBitStream pointer to the pointer to the current byte in * the bit stream * [in] pBitOffset pointer to the bit position in the byte pointed * by *ppBitStream. Valid within 0 to 7 * [in] start start indicates whether the encoding begins with * 0th element or 1st. * [in/out] pLast pointer to last status flag * [in] runBeginSingleLevelEntriesL0 The run value from which level * will be equal to 1: last == 0 * [in] IndexBeginSingleLevelEntriesL0 Array index in the VLC table * pointing to the * runBeginSingleLevelEntriesL0 * [in] runBeginSingleLevelEntriesL1 The run value from which level * will be equal to 1: last == 1 * [in] IndexBeginSingleLevelEntriesL1 Array index in the VLC table * pointing to the * runBeginSingleLevelEntriesL0 * [in] pRunIndexTableL0 Run Index table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 0 * [in] pVlcTableL0 VLC table for last == 0 * [in] pRunIndexTableL1 Run Index table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 1 * [in] pVlcTableL1 VLC table for last == 1 * [in] pLMAXTableL0 Level MAX table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 0 * [in] pLMAXTableL1 Level MAX table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 1 * [in] pRMAXTableL0 Run MAX table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 0 * [in] pRMAXTableL1 Run MAX table defined in * armVCM4P2_Huff_Tables_VLC.c for last == 1 * [out]pDst pointer to the coefficient buffer of current * block. Should be 32-bit aligned * * Return Value: * Standard OMXResult result. See enumeration for possible result codes. * */ OMXResult armVCM4P2_GetVLCBits ( const OMX_U8 **ppBitStream, OMX_INT * pBitOffset, OMX_S16 * pDst, OMX_INT shortVideoHeader, OMX_U8 start, OMX_U8 * pLast, OMX_U8 runBeginSingleLevelEntriesL0, OMX_U8 maxIndexForMultipleEntriesL0, OMX_U8 maxRunForMultipleEntriesL1, OMX_U8 maxIndexForMultipleEntriesL1, const OMX_U8 * pRunIndexTableL0, const ARM_VLC32 *pVlcTableL0, const OMX_U8 * pRunIndexTableL1, const ARM_VLC32 *pVlcTableL1, const OMX_U8 * pLMAXTableL0, const OMX_U8 * pLMAXTableL1, const OMX_U8 * pRMAXTableL0, const OMX_U8 * pRMAXTableL1, const OMX_U8 * pZigzagTable ) { OMX_U32 storeRun; OMX_U8 tabIndex, markerBit; OMX_S16 storeLevel; OMX_U16 unpackRetIndex; OMX_U8 i, fType, escape; OMX_U8 sign = 0; /* Unpacking the bitstream and RLD */ for (i = start; i < 64;) { escape = armLookAheadBits(ppBitStream, pBitOffset, 7); if (escape != 3) { fType = 0; /* Not in escape mode */ } else { armSkipBits (ppBitStream, pBitOffset, 7); if(shortVideoHeader) { *pLast = armGetBits(ppBitStream, pBitOffset, 1); storeRun = armGetBits(ppBitStream, pBitOffset, 6); storeLevel = armGetBits(ppBitStream, pBitOffset, 8); /* Ref to Table B-18 (c) in MPEG4 Standard- FLC code for */ /* LEVEL when short_video_header is 1, the storeLevel is */ /* a signed value and the sign and the unsigned value for */ /* storeLevel need to be extracted and passed to arm */ /* FillVLDBuffer function */ sign = (storeLevel & 0x80); if(sign==0x80) { storeLevel=(storeLevel^0xff)+1; sign=1; } armRetDataErrIf( storeLevel == 0 || sign*storeLevel == 128 , OMX_Sts_Err); /* Invalid FLC */ armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err); armVCM4P2_FillVLDBuffer( storeRun, pDst, storeLevel, sign, *pLast, &i, pZigzagTable); return OMX_Sts_NoErr; } if (armGetBits(ppBitStream, pBitOffset, 1)) { if (armGetBits(ppBitStream, pBitOffset, 1)) { fType = 3; } else { fType = 2; } } else { fType = 1; } } if (fType < 3) { unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset, pVlcTableL0); if (unpackRetIndex != ARM_NO_CODEBOOK_INDEX) { /* Decode run and level from the index */ /* last = 0 */ *pLast = 0; if (unpackRetIndex > maxIndexForMultipleEntriesL0) { storeLevel = 1; storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL0) + runBeginSingleLevelEntriesL0; } else { tabIndex = 1; while (pRunIndexTableL0[tabIndex] <= unpackRetIndex) { tabIndex++; } storeRun = tabIndex - 1; storeLevel = unpackRetIndex - pRunIndexTableL0[tabIndex - 1] + 1; } sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1); if (fType == 1) { storeLevel = (armAbs(storeLevel) + pLMAXTableL0[storeRun]); } else if (fType == 2) { storeRun = storeRun + pRMAXTableL0[storeLevel-1] + 1; } } else { unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset, pVlcTableL1); armRetDataErrIf(unpackRetIndex == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); /* Decode run and level from the index */ /* last = 1 */ *pLast = 1; if (unpackRetIndex > maxIndexForMultipleEntriesL1) { storeLevel = 1; storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL1) + maxRunForMultipleEntriesL1; } else { tabIndex = 1; while (pRunIndexTableL1[tabIndex] <= unpackRetIndex) { tabIndex++; } storeRun = tabIndex - 1; storeLevel = unpackRetIndex - pRunIndexTableL1[tabIndex - 1] + 1; } sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1); if (fType == 1) { storeLevel = (armAbs(storeLevel) + pLMAXTableL1[storeRun]); } else if (fType == 2) { storeRun = storeRun + pRMAXTableL1[storeLevel-1] + 1; } } armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err); armVCM4P2_FillVLDBuffer( storeRun, pDst, storeLevel, sign, *pLast, &i, pZigzagTable); } else { *pLast = armGetBits(ppBitStream, pBitOffset, 1); storeRun = armGetBits(ppBitStream, pBitOffset, 6); armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err); markerBit = armGetBits(ppBitStream, pBitOffset, 1); armRetDataErrIf( markerBit == 0, OMX_Sts_Err); storeLevel = armGetBits(ppBitStream, pBitOffset, 12); if (storeLevel & 0x800) { storeLevel -= 4096; } armRetDataErrIf( storeLevel == 0 || storeLevel == -2048 , OMX_Sts_Err); /* Invalid FLC */ armGetBits(ppBitStream, pBitOffset, 1); armVCM4P2_FillVLDBuffer( storeRun, pDst, storeLevel, 0, /* Sign is not used, preprocessing done */ *pLast, &i, pZigzagTable); } } /* End of forloop for i */ return OMX_Sts_NoErr; } /* End of File */