diff options
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c')
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c new file mode 100644 index 0000000..7616add --- /dev/null +++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p10/src/armVCM4P10_DecodeCoeffsToPair.c @@ -0,0 +1,267 @@ +/* ---------------------------------------------------------------- + * + * + * File Name: armVCM4P10_DecodeCoeffsToPair.c + * OpenMAX DL: v1.0.2 + * Revision: 9641 + * Date: Thursday, February 7, 2008 + * + * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. + * + * + * + * H.264 decode coefficients module + * + */ + +#ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR +#undef DEBUG_ON +#define DEBUG_ON +#endif + +#include "omxtypes.h" +#include "armOMX.h" +#include "omxVC.h" + +#include "armCOMM.h" +#include "armCOMM_Bitstream.h" +#include "armVCM4P10_CAVLCTables.h" + +/* 4x4 DeZigZag table */ + +static const OMX_U8 armVCM4P10_ZigZag[16] = +{ + 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 +}; + +/* + * Description: + * This function perform the work required by the OpenMAX + * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair. + * Since most of the code is common we share it here. + * + * Parameters: + * [in] ppBitStream Double pointer to current byte in bit stream buffer + * [in] pOffset Pointer to current bit position in the byte pointed + * to by *ppBitStream + * [in] sMaxNumCoeff Maximum number of non-zero coefficients in current + * block (4,15 or 16) + * [in] nTable Table number (0 to 4) according to the five columns + * of Table 9-5 in the H.264 spec + * [out] ppBitStream *ppBitStream is updated after each block is decoded + * [out] pOffset *pOffset is updated after each block is decoded + * [out] pNumCoeff Pointer to the number of nonzero coefficients in + * this block + * [out] ppPosCoefbuf Double pointer to destination residual + * coefficient-position pair buffer + * Return Value: + * Standard omxError result. See enumeration for possible result codes. + + */ + +OMXResult armVCM4P10_DecodeCoeffsToPair( + const OMX_U8** ppBitStream, + OMX_S32* pOffset, + OMX_U8* pNumCoeff, + OMX_U8 **ppPosCoefbuf, + OMX_INT nTable, + OMX_INT sMaxNumCoeff + ) +{ + int CoeffToken, TotalCoeff, TrailingOnes; + int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize; + int SuffixLength, Run, ZerosLeft,CoeffNum; + int i, Flags; + OMX_U8 *pPosCoefbuf = *ppPosCoefbuf; + OMX_S16 pLevel[16]; + OMX_U8 pRun[16]; + + CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]); + armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + + TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken]; + TotalCoeff = armVCM4P10_CAVLCTotalCoeff[CoeffToken]; + *pNumCoeff = (OMX_U8)TotalCoeff; + + DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes); + + if (TotalCoeff == 0) + { + /* Nothing to do */ + return OMX_Sts_NoErr; + } + + /* Decode trailing ones */ + for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--) + { + if (armGetBits(ppBitStream, pOffset, 1)) + { + Level = -1; + } + else + { + Level = +1; + } + pLevel[i] = (OMX_S16)Level; + + DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); + } + + /* Decode (non zero) level values */ + SuffixLength = 0; + if (TotalCoeff>10 && TrailingOnes<3) + { + SuffixLength=1; + } + for ( ; i>=0; i--) + { + LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix); + armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + + LevelSuffixSize = SuffixLength; + if (LevelPrefix==14 && SuffixLength==0) + { + LevelSuffixSize = 4; + } + if (LevelPrefix==15) + { + LevelSuffixSize = 12; + } + + LevelSuffix = 0; + if (LevelSuffixSize > 0) + { + LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize); + } + + LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix; + + + if (LevelPrefix==15 && SuffixLength==0) + { + LevelCode += 15; + } + + /* LevelCode = 2*(magnitude-1) + sign */ + + if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3) + { + /* Level magnitude can't be 1 */ + LevelCode += 2; + } + if (LevelCode & 1) + { + /* 2a+1 maps to -a-1 */ + Level = (-LevelCode-1)>>1; + } + else + { + /* 2a+0 maps to +a+1 */ + Level = (LevelCode+2)>>1; + } + pLevel[i] = (OMX_S16)Level; + + DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]); + + if (SuffixLength==0) + { + SuffixLength=1; + } + if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 ) + { + SuffixLength++; + } + } + + /* Decode run values */ + ZerosLeft = 0; + if (TotalCoeff < sMaxNumCoeff) + { + /* Decode TotalZeros VLC */ + if (sMaxNumCoeff==4) + { + ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]); + armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); + } + else + { + ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]); + armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err); + } + } + + DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft); + + CoeffNum=ZerosLeft+TotalCoeff-1; + + for (i=TotalCoeff-1; i>0; i--) + { + Run = 0; + if (ZerosLeft > 0) + { + int Table = ZerosLeft; + if (Table > 6) + { + Table = 7; + } + Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]); + armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err); + } + pRun[i] = (OMX_U8)Run; + + DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]); + + ZerosLeft -= Run; + } + pRun[0] = (OMX_U8)ZerosLeft; + + DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]); + + + /* Fill in coefficients */ + + if (sMaxNumCoeff==15) + { + CoeffNum++; /* Skip the DC position */ + } + + /*for (i=0;i<TotalCoeff;i++) + CoeffNum += pRun[i]+1;*/ + + for (i=(TotalCoeff-1); i>=0; i--) + { + /*CoeffNum += pRun[i]+1;*/ + Level = pLevel[i]; + + DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level); + + Flags = CoeffNum; + CoeffNum -= (pRun[i]+1); + if (sMaxNumCoeff>4) + { + /* Perform 4x4 DeZigZag */ + Flags = armVCM4P10_ZigZag[Flags]; + } + if (i==0) + { + /* End of block flag */ + Flags += 0x20; + } + if (Level<-128 || Level>127) + { + /* Overflow flag */ + Flags += 0x10; + } + + *pPosCoefbuf++ = (OMX_U8)(Flags); + *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF); + if (Flags & 0x10) + { + *pPosCoefbuf++ = (OMX_U8)(Level>>8); + } + } + + *ppPosCoefbuf = pPosCoefbuf; + + return OMX_Sts_NoErr; +} |