summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c')
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c1446
1 files changed, 1446 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c
new file mode 100755
index 0000000..2b3e7f0
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_macroblock_layer.c
@@ -0,0 +1,1446 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * 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.
+ */
+
+/*------------------------------------------------------------------------------
+
+ Table of contents
+
+ 1. Include headers
+ 2. External compiler flags
+ 3. Module defines
+ 4. Local function prototypes
+ 5. Functions
+ h264bsdDecodeMacroblockLayer
+ h264bsdMbPartPredMode
+ h264bsdNumMbPart
+ h264bsdNumSubMbPart
+ DecodeMbPred
+ DecodeSubMbPred
+ DecodeResidual
+ DetermineNc
+ CbpIntra16x16
+ h264bsdPredModeIntra16x16
+ h264bsdDecodeMacroblock
+ ProcessResidual
+ h264bsdSubMbPartMode
+
+------------------------------------------------------------------------------*/
+
+/*------------------------------------------------------------------------------
+ 1. Include headers
+------------------------------------------------------------------------------*/
+
+#include "h264bsd_macroblock_layer.h"
+#include "h264bsd_slice_header.h"
+#include "h264bsd_util.h"
+#include "h264bsd_vlc.h"
+#include "h264bsd_cavlc.h"
+#include "h264bsd_nal_unit.h"
+#include "h264bsd_neighbour.h"
+#include "h264bsd_transform.h"
+#include "h264bsd_intra_prediction.h"
+#include "h264bsd_inter_prediction.h"
+
+#ifdef H264DEC_OMXDL
+#include "omxtypes.h"
+#include "omxVC.h"
+#include "armVC.h"
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+ 2. External compiler flags
+--------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------
+ 3. Module defines
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+static const u32 chromaIndex[8] = { 256, 260, 288, 292, 320, 324, 352, 356 };
+static const u32 lumaIndex[16] = { 0, 4, 64, 68,
+ 8, 12, 72, 76,
+ 128, 132, 192, 196,
+ 136, 140, 200, 204 };
+#endif
+/* mapping of dc coefficients array to luma blocks */
+static const u32 dcCoeffIndex[16] =
+ {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
+
+/*------------------------------------------------------------------------------
+ 4. Local function prototypes
+------------------------------------------------------------------------------*/
+
+static u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive);
+static u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern);
+
+#ifdef H264DEC_OMXDL
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff);
+#else
+static u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff);
+#endif
+
+static u32 CbpIntra16x16(mbType_e mbType);
+#ifdef H264DEC_OMXDL
+static u32 ProcessIntra4x4Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer, const u8 **pSrc, image_t *image);
+static u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc );
+static u32 ProcessIntra16x16Residual(mbStorage_t *pMb, u8 *data, u32 constrainedIntraPred,
+ u32 intraChromaPredMode, const u8 **pSrc, image_t *image);
+
+
+#else
+static u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *);
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function name: h264bsdDecodeMacroblockLayer
+
+ Functional description:
+ Parse macroblock specific information from bit stream.
+
+ Inputs:
+ pStrmData pointer to stream data structure
+ pMb pointer to macroblock storage structure
+ sliceType type of the current slice
+ numRefIdxActive maximum reference index
+
+ Outputs:
+ pMbLayer stores the macroblock data parsed from stream
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK end of stream or error in stream
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblockLayer(strmData_t *pStrmData,
+ macroblockLayer_t *pMbLayer, mbStorage_t *pMb, u32 sliceType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, value;
+ i32 itmp;
+ mbPartPredMode_e partMode;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbLayer);
+
+#ifdef H264DEC_NEON
+ h264bsdClearMbLayer(pMbLayer, ((sizeof(macroblockLayer_t) + 63) & ~0x3F));
+#else
+ H264SwDecMemset(pMbLayer, 0, sizeof(macroblockLayer_t));
+#endif
+
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+
+ if (IS_I_SLICE(sliceType))
+ {
+ if ((value + 6) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 6);
+ }
+ else
+ {
+ if ((value + 1) > 31 || tmp != HANTRO_OK)
+ return(HANTRO_NOK);
+ pMbLayer->mbType = (mbType_e)(value + 1);
+ }
+
+ if (pMbLayer->mbType == I_PCM)
+ {
+ i32 *level;
+ while( !h264bsdIsByteAligned(pStrmData) )
+ {
+ /* pcm_alignment_zero_bit */
+ tmp = h264bsdGetBits(pStrmData, 1);
+ if (tmp)
+ return(HANTRO_NOK);
+ }
+
+ level = pMbLayer->residual.level[0];
+ for (i = 0; i < 384; i++)
+ {
+ value = h264bsdGetBits(pStrmData, 8);
+ if (value == END_OF_STREAM)
+ return(HANTRO_NOK);
+ *level++ = (i32)value;
+ }
+ }
+ else
+ {
+ partMode = h264bsdMbPartPredMode(pMbLayer->mbType);
+ if ( (partMode == PRED_MODE_INTER) &&
+ (h264bsdNumMbPart(pMbLayer->mbType) == 4) )
+ {
+ tmp = DecodeSubMbPred(pStrmData, &pMbLayer->subMbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ else
+ {
+ tmp = DecodeMbPred(pStrmData, &pMbLayer->mbPred,
+ pMbLayer->mbType, numRefIdxActive);
+ }
+ if (tmp != HANTRO_OK)
+ return(tmp);
+
+ if (partMode != PRED_MODE_INTRA16x16)
+ {
+ tmp = h264bsdDecodeExpGolombMapped(pStrmData, &value,
+ (u32)(partMode == PRED_MODE_INTRA4x4));
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbLayer->codedBlockPattern = value;
+ }
+ else
+ {
+ pMbLayer->codedBlockPattern = CbpIntra16x16(pMbLayer->mbType);
+ }
+
+ if ( pMbLayer->codedBlockPattern ||
+ (partMode == PRED_MODE_INTRA16x16) )
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK || (itmp < -26) || (itmp > 25) )
+ return(HANTRO_NOK);
+ pMbLayer->mbQpDelta = itmp;
+
+ tmp = DecodeResidual(pStrmData, &pMbLayer->residual, pMb,
+ pMbLayer->mbType, pMbLayer->codedBlockPattern);
+
+ pStrmData->strmBuffReadBits =
+ (u32)(pStrmData->pStrmCurrPos - pStrmData->pStrmBuffStart) * 8 +
+ pStrmData->bitPosInWord;
+
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdMbPartPredMode
+
+ Functional description:
+ Returns the prediction mode of a macroblock type
+
+------------------------------------------------------------------------------*/
+
+mbPartPredMode_e h264bsdMbPartPredMode(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(mbType <= 31);
+
+ if ((mbType <= P_8x8ref0))
+ return(PRED_MODE_INTER);
+ else if (mbType == I_4x4)
+ return(PRED_MODE_INTRA4x4);
+ else
+ return(PRED_MODE_INTRA16x16);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumMbPart
+
+ Functional description:
+ Returns the amount of macroblock partitions in a macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumMbPart(mbType_e mbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ switch (mbType)
+ {
+ case P_L0_16x16:
+ case P_Skip:
+ return(1);
+
+ case P_L0_L0_16x8:
+ case P_L0_L0_8x16:
+ return(2);
+
+ /* P_8x8 or P_8x8ref0 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdNumSubMbPart
+
+ Functional description:
+ Returns the amount of sub-partitions in a sub-macroblock type
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdNumSubMbPart(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType <= P_L0_4x4);
+
+ switch (subMbType)
+ {
+ case P_L0_8x8:
+ return(1);
+
+ case P_L0_8x4:
+ case P_L0_4x8:
+ return(2);
+
+ /* P_L0_4x4 */
+ default:
+ return(4);
+ }
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeMbPred
+
+ Functional description:
+ Parse macroblock prediction information from bit stream and store
+ in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeMbPred(strmData_t *pStrmData, mbPred_t *pMbPred, mbType_e mbType,
+ u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pMbPred);
+
+ switch (h264bsdMbPartPredMode(mbType))
+ {
+ case PRED_MODE_INTER: /* PRED_MODE_INTER */
+ if (numRefIdxActive > 1)
+ {
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+
+ pMbPred->refIdxL0[j] = value;
+ }
+ }
+
+ for (i = h264bsdNumMbPart(mbType), j = 0; i--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pMbPred->mvdL0[j].ver = (i16)itmp;
+ }
+ break;
+
+ case PRED_MODE_INTRA4x4:
+ for (itmp = 0, i = 0; itmp < 2; itmp++)
+ {
+ value = h264bsdShowBits32(pStrmData);
+ tmp = 0;
+ for (j = 8; j--; i++)
+ {
+ pMbPred->prevIntra4x4PredModeFlag[i] =
+ value & 0x80000000 ? HANTRO_TRUE : HANTRO_FALSE;
+ value <<= 1;
+ if (!pMbPred->prevIntra4x4PredModeFlag[i])
+ {
+ pMbPred->remIntra4x4PredMode[i] = value>>29;
+ value <<= 3;
+ tmp++;
+ }
+ }
+ if (h264bsdFlushBits(pStrmData, 8 + 3*tmp) == END_OF_STREAM)
+ return(HANTRO_NOK);
+ }
+ /* fall-through */
+
+ case PRED_MODE_INTRA16x16:
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pMbPred->intraChromaPredMode = value;
+ break;
+ }
+
+ return(HANTRO_OK);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: DecodeSubMbPred
+
+ Functional description:
+ Parse sub-macroblock prediction information from bit stream and
+ store in 'pMbPred'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeSubMbPred(strmData_t *pStrmData, subMbPred_t *pSubMbPred,
+ mbType_e mbType, u32 numRefIdxActive)
+{
+
+/* Variables */
+
+ u32 tmp, i, j, value;
+ i32 itmp;
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pSubMbPred);
+ ASSERT(h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER);
+
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombUnsigned(pStrmData, &value);
+ if (tmp != HANTRO_OK || value > 3)
+ return(HANTRO_NOK);
+ pSubMbPred->subMbType[i] = (subMbType_e)value;
+ }
+
+ if ( (numRefIdxActive > 1) && (mbType != P_8x8ref0) )
+ {
+ for (i = 0; i < 4; i++)
+ {
+ tmp = h264bsdDecodeExpGolombTruncated(pStrmData, &value,
+ (u32)(numRefIdxActive > 2));
+ if (tmp != HANTRO_OK || value >= numRefIdxActive)
+ return(HANTRO_NOK);
+ pSubMbPred->refIdxL0[i] = value;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ j = 0;
+ for (value = h264bsdNumSubMbPart(pSubMbPred->subMbType[i]);
+ value--; j++)
+ {
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].hor = (i16)itmp;
+
+ tmp = h264bsdDecodeExpGolombSigned(pStrmData, &itmp);
+ if (tmp != HANTRO_OK)
+ return(tmp);
+ pSubMbPred->mvdL0[i][j].ver = (i16)itmp;
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#ifdef H264DEC_OMXDL
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ OMX_INT nc;
+ OMXResult omxRes;
+ OMX_U8 *pPosCoefBuf;
+
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ pPosCoefBuf = pResidual->posCoefBuf;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, 0, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[24],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb,blockIndex,pResidual->totalCoeff);
+ if (is16x16)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ }
+ else
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 16);
+#endif
+ }
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[25],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeChromaDcCoeffsToPairCAVLC(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8**) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[26],
+ &pPosCoefBuf,
+ 17,
+ 4);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (OMX_INT)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+#ifndef H264DEC_NEON
+ omxRes = omxVCM4P10_DecodeCoeffsToPairCAVLC(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#else
+ omxRes = armVCM4P10_DecodeCoeffsToPair(
+ (const OMX_U8 **) (&pStrmData->pStrmCurrPos),
+ (OMX_S32*) (&pStrmData->bitPosInWord),
+ &pResidual->totalCoeff[blockIndex],
+ &pPosCoefBuf,
+ nc,
+ 15);
+#endif
+ if (omxRes != OMX_Sts_NoErr)
+ return(HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+
+#else
+/*------------------------------------------------------------------------------
+
+ Function: DecodeResidual
+
+ Functional description:
+ Parse residual information from bit stream and store in 'pResidual'.
+
+------------------------------------------------------------------------------*/
+
+u32 DecodeResidual(strmData_t *pStrmData, residual_t *pResidual,
+ mbStorage_t *pMb, mbType_e mbType, u32 codedBlockPattern)
+{
+
+/* Variables */
+
+ u32 i, j, tmp;
+ i32 nc;
+ u32 blockCoded;
+ u32 blockIndex;
+ u32 is16x16;
+ i32 (*level)[16];
+
+/* Code */
+
+ ASSERT(pStrmData);
+ ASSERT(pResidual);
+
+ level = pResidual->level;
+
+ /* luma DC is at index 24 */
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ nc = (i32)DetermineNc(pMb, 0, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[24], nc, 16);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[24] = (tmp >> 4) & 0xFF;
+ is16x16 = HANTRO_TRUE;
+ }
+ else
+ is16x16 = HANTRO_FALSE;
+
+ for (i = 4, blockIndex = 0; i--;)
+ {
+ /* luma cbp in bits 0-3 */
+ blockCoded = codedBlockPattern & 0x1;
+ codedBlockPattern >>= 1;
+ if (blockCoded)
+ {
+ for (j = 4; j--; blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ if (is16x16)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ pResidual->coeffMap[blockIndex] = tmp >> 15;
+ }
+ else
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex], nc, 16);
+ pResidual->coeffMap[blockIndex] = tmp >> 16;
+ }
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ }
+ }
+ else
+ blockIndex += 4;
+ }
+
+ /* chroma DC block are at indices 25 and 26 */
+ blockCoded = codedBlockPattern & 0x3;
+ if (blockCoded)
+ {
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25], -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[25] = (tmp >> 4) & 0xFF;
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData, level[25]+4, -1, 4);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[26] = (tmp >> 4) & 0xFF;
+ }
+
+ /* chroma AC */
+ blockCoded = codedBlockPattern & 0x2;
+ if (blockCoded)
+ {
+ for (i = 8; i--;blockIndex++)
+ {
+ nc = (i32)DetermineNc(pMb, blockIndex, pResidual->totalCoeff);
+ tmp = h264bsdDecodeResidualBlockCavlc(pStrmData,
+ level[blockIndex] + 1, nc, 15);
+ if ((tmp & 0xF) != HANTRO_OK)
+ return(tmp);
+ pResidual->totalCoeff[blockIndex] = (tmp >> 4) & 0xFF;
+ pResidual->coeffMap[blockIndex] = (tmp >> 15);
+ }
+ }
+
+ return(HANTRO_OK);
+
+}
+#endif
+
+/*------------------------------------------------------------------------------
+
+ Function: DetermineNc
+
+ Functional description:
+ Returns the nC of a block.
+
+------------------------------------------------------------------------------*/
+#ifdef H264DEC_OMXDL
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, u8 *pTotalCoeff)
+#else
+u32 DetermineNc(mbStorage_t *pMb, u32 blockIndex, i16 *pTotalCoeff)
+#endif
+{
+/*lint -e702 */
+/* Variables */
+
+ u32 tmp;
+ i32 n;
+ const neighbour_t *neighbourA, *neighbourB;
+ u8 neighbourAindex, neighbourBindex;
+
+/* Code */
+
+ ASSERT(blockIndex < 24);
+
+ /* if neighbour block belongs to current macroblock totalCoeff array
+ * mbStorage has not been set/updated yet -> use pTotalCoeff */
+ neighbourA = h264bsdNeighbour4x4BlockA(blockIndex);
+ neighbourB = h264bsdNeighbour4x4BlockB(blockIndex);
+ neighbourAindex = neighbourA->index;
+ neighbourBindex = neighbourB->index;
+ if (neighbourA->mb == MB_CURR && neighbourB->mb == MB_CURR)
+ {
+ n = (pTotalCoeff[neighbourAindex] +
+ pTotalCoeff[neighbourBindex] + 1)>>1;
+ }
+ else if (neighbourA->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourAindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ }
+ }
+ else if (neighbourB->mb == MB_CURR)
+ {
+ n = pTotalCoeff[neighbourBindex];
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = (n + pMb->mbA->totalCoeff[neighbourAindex] + 1) >> 1;
+ }
+ }
+ else
+ {
+ n = tmp = 0;
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbA))
+ {
+ n = pMb->mbA->totalCoeff[neighbourAindex];
+ tmp = 1;
+ }
+ if (h264bsdIsNeighbourAvailable(pMb, pMb->mbB))
+ {
+ if (tmp)
+ n = (n + pMb->mbB->totalCoeff[neighbourBindex] + 1) >> 1;
+ else
+ n = pMb->mbB->totalCoeff[neighbourBindex];
+ }
+ }
+ return((u32)n);
+/*lint +e702 */
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: CbpIntra16x16
+
+ Functional description:
+ Returns the coded block pattern for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 CbpIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 cbp;
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ if (mbType >= I_16x16_0_0_1)
+ cbp = 15;
+ else
+ cbp = 0;
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0) >> 2;
+ if (tmp > 2)
+ tmp -= 3;
+
+ cbp += tmp << 4;
+
+ return(cbp);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdPredModeIntra16x16
+
+ Functional description:
+ Returns the prediction mode for intra 16x16 macroblock.
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdPredModeIntra16x16(mbType_e mbType)
+{
+
+/* Variables */
+
+ u32 tmp;
+
+/* Code */
+
+ ASSERT(mbType >= I_16x16_0_0_0 && mbType <= I_16x16_3_2_1);
+
+ /* tmp is 0 for I_16x16_0_0_0 mb type */
+ /* ignore lint warning on arithmetic on enum's */
+ tmp = /*lint -e(656)*/(mbType - I_16x16_0_0_0);
+
+ return(tmp & 0x3);
+
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdDecodeMacroblock
+
+ Functional description:
+ Decode one macroblock and write into output image.
+
+ Inputs:
+ pMb pointer to macroblock specific information
+ mbLayer pointer to current macroblock data from stream
+ currImage pointer to output image
+ dpb pointer to decoded picture buffer
+ qpY pointer to slice QP
+ mbNum current macroblock number
+ constrainedIntraPred flag specifying if neighbouring inter
+ macroblocks are used in intra prediction
+
+ Outputs:
+ pMb structure is updated with current macroblock
+ currImage decoded macroblock is written into output image
+
+ Returns:
+ HANTRO_OK success
+ HANTRO_NOK error in macroblock decoding
+
+------------------------------------------------------------------------------*/
+
+u32 h264bsdDecodeMacroblock(mbStorage_t *pMb, macroblockLayer_t *pMbLayer,
+ image_t *currImage, dpbStorage_t *dpb, i32 *qpY, u32 mbNum,
+ u32 constrainedIntraPredFlag, u8* data)
+{
+
+/* Variables */
+
+ u32 i, tmp;
+ mbType_e mbType;
+#ifdef H264DEC_OMXDL
+ const u8 *pSrc;
+#endif
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(pMbLayer);
+ ASSERT(currImage);
+ ASSERT(qpY && *qpY < 52);
+ ASSERT(mbNum < currImage->width*currImage->height);
+
+ mbType = pMbLayer->mbType;
+ pMb->mbType = mbType;
+
+ pMb->decoded++;
+
+ h264bsdSetCurrImageMbPointers(currImage, mbNum);
+
+ if (mbType == I_PCM)
+ {
+ u8 *pData = (u8*)data;
+#ifdef H264DEC_OMXDL
+ u8 *tot = pMb->totalCoeff;
+#else
+ i16 *tot = pMb->totalCoeff;
+#endif
+ i32 *lev = pMbLayer->residual.level[0];
+
+ pMb->qpY = 0;
+
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ {
+ for (i = 24; i--;)
+ *tot++ = 16;
+ return HANTRO_OK;
+ }
+
+ for (i = 24; i--;)
+ {
+ *tot++ = 16;
+ for (tmp = 16; tmp--;)
+ *pData++ = (u8)(*lev++);
+ }
+ h264bsdWriteMacroblock(currImage, (u8*)data);
+
+ return(HANTRO_OK);
+ }
+ else
+ {
+#ifdef H264DEC_OMXDL
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ if (mbType != P_Skip)
+ {
+ H264SwDecMemcpy(pMb->totalCoeff,
+ pMbLayer->residual.totalCoeff,
+ 27*sizeof(*pMb->totalCoeff));
+
+ /* update qpY */
+ if (pMbLayer->mbQpDelta)
+ {
+ *qpY = *qpY + pMbLayer->mbQpDelta;
+ if (*qpY < 0) *qpY += 52;
+ else if (*qpY >= 52) *qpY -= 52;
+ }
+ pMb->qpY = (u32)*qpY;
+
+#ifdef H264DEC_OMXDL
+ pSrc = pMbLayer->residual.posCoefBuf;
+
+ if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTER)
+ {
+ OMXResult res;
+ u8 *p;
+ u8 *totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (*totalCoeff)
+ {
+ res = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ &pSrc, p, 0, p, 16, 16, *qpY, *totalCoeff);
+ if (res != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA4x4)
+ {
+ tmp = ProcessIntra4x4Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else if (h264bsdMbPartPredMode(mbType) == PRED_MODE_INTRA16x16)
+ {
+ tmp = ProcessIntra16x16Residual(pMb,
+ data,
+ constrainedIntraPredFlag,
+ pMbLayer->mbPred.intraChromaPredMode,
+ &pSrc,
+ currImage);
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+
+ tmp = ProcessChromaResidual(pMb, data, &pSrc);
+
+#else
+ tmp = ProcessResidual(pMb, pMbLayer->residual.level,
+ pMbLayer->residual.coeffMap);
+#endif
+ if (tmp != HANTRO_OK)
+ return (tmp);
+ }
+ else
+ {
+ H264SwDecMemset(pMb->totalCoeff, 0, 27*sizeof(*pMb->totalCoeff));
+ pMb->qpY = (u32)*qpY;
+ }
+#ifdef H264DEC_OMXDL
+ /* if decoded flag > 1 -> mb has already been successfully decoded and
+ * written to output -> do not write again */
+ if (pMb->decoded > 1)
+ return HANTRO_OK;
+
+ h264bsdWriteMacroblock(currImage, data);
+#else
+ if (h264bsdMbPartPredMode(mbType) != PRED_MODE_INTER)
+ {
+ tmp = h264bsdIntraPrediction(pMb, pMbLayer, currImage, mbNum,
+ constrainedIntraPredFlag, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+ else
+ {
+ tmp = h264bsdInterPrediction(pMb, pMbLayer, dpb, mbNum,
+ currImage, (u8*)data);
+ if (tmp != HANTRO_OK) return (tmp);
+ }
+#endif
+ }
+
+ return HANTRO_OK;
+}
+
+
+#ifdef H264DEC_OMXDL
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessChromaResidual
+
+ Functional description:
+ Process the residual data of chroma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessChromaResidual(mbStorage_t *pMb, u8 *data, const u8 **pSrc )
+{
+ u32 i;
+ u32 chromaQp;
+ i16 *pDc;
+ i16 dc[4 + 4] = {0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+
+ if (pMb->totalCoeff[25])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ if (pMb->totalCoeff[26])
+ {
+ pDc = dc+4;
+ result = omxVCM4P10_TransformDequantChromaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)chromaQp);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+
+ pDc = dc;
+ totalCoeff = pMb->totalCoeff + 16;
+ for (i = 0; i < 8; i++, pDc++, totalCoeff++)
+ {
+ /* chroma prediction */
+ if (*totalCoeff || *pDc)
+ {
+ p = data + chromaIndex[i];
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 8,
+ 8,
+ (i32)chromaQp,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ return(HANTRO_OK);
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra16x16Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra16x16Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ u32 intraChromaPredMode,
+ const u8** pSrc,
+ image_t *image)
+{
+ u32 i;
+ i16 *pDc;
+ i16 dc[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ if (totalCoeff[24])
+ {
+ pDc = dc;
+ result = omxVCM4P10_TransformDequantLumaDCFromPair(
+ pSrc,
+ pDc,
+ (i32)pMb->qpY);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ /* Intra 16x16 pred */
+ if (h264bsdIntra16x16Prediction(pMb, data, image->luma,
+ image->width*16, constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ pDc = &dc[dcCoeffIndex[i]];
+ if (*totalCoeff || *pDc)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ pDc,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessIntra4x4Residual
+
+ Functional description:
+ Process the residual data of luma with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+u32 ProcessIntra4x4Residual(mbStorage_t *pMb,
+ u8 *data,
+ u32 constrainedIntraPred,
+ macroblockLayer_t *mbLayer,
+ const u8 **pSrc,
+ image_t *image)
+{
+ u32 i;
+ u8 *totalCoeff;
+ OMXResult result;
+ u8 *p;
+
+ totalCoeff = pMb->totalCoeff;
+
+ for (i = 0; i < 16; i++, totalCoeff++)
+ {
+ p = data + lumaIndex[i];
+ if (h264bsdIntra4x4Prediction(pMb, p, mbLayer, image->luma,
+ image->width*16, constrainedIntraPred, i) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ if (*totalCoeff)
+ {
+ result = omxVCM4P10_DequantTransformResidualFromPairAndAdd(
+ pSrc,
+ p,
+ NULL,
+ p,
+ 16,
+ 16,
+ (i32)pMb->qpY,
+ *totalCoeff);
+ if (result != OMX_Sts_NoErr)
+ return (HANTRO_NOK);
+ }
+ }
+
+ if (h264bsdIntraChromaPrediction(pMb, data + 256,
+ image,
+ mbLayer->mbPred.intraChromaPredMode,
+ constrainedIntraPred) != HANTRO_OK)
+ return(HANTRO_NOK);
+
+ return HANTRO_OK;
+}
+
+#else /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: ProcessResidual
+
+ Functional description:
+ Process the residual data of one macroblock with
+ inverse quantization and inverse transform.
+
+------------------------------------------------------------------------------*/
+
+u32 ProcessResidual(mbStorage_t *pMb, i32 residualLevel[][16], u32 *coeffMap)
+{
+
+/* Variables */
+
+ u32 i;
+ u32 chromaQp;
+ i32 (*blockData)[16];
+ i32 (*blockDc)[16];
+ i16 *totalCoeff;
+ i32 *chromaDc;
+ const u32 *dcCoeffIdx;
+
+/* Code */
+
+ ASSERT(pMb);
+ ASSERT(residualLevel);
+
+ /* set pointers to DC coefficient blocks */
+ blockDc = residualLevel + 24;
+
+ blockData = residualLevel;
+ totalCoeff = pMb->totalCoeff;
+ if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
+ {
+ if (totalCoeff[24])
+ {
+ h264bsdProcessLumaDc(*blockDc, pMb->qpY);
+ }
+ dcCoeffIdx = dcCoeffIndex;
+
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of luma block */
+ (*blockData)[0] = (*blockDc)[*dcCoeffIdx++];
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 1, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+ else
+ {
+ for (i = 16; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ if (*totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, pMb->qpY, 0, *coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+ }
+
+ /* chroma DC processing. First chroma dc block is block with index 25 */
+ chromaQp =
+ h264bsdQpC[CLIP3(0, 51, (i32)pMb->qpY + pMb->chromaQpIndexOffset)];
+ if (pMb->totalCoeff[25] || pMb->totalCoeff[26])
+ h264bsdProcessChromaDc(residualLevel[25], chromaQp);
+ chromaDc = residualLevel[25];
+ for (i = 8; i--; blockData++, totalCoeff++, coeffMap++)
+ {
+ /* set dc coefficient of chroma block */
+ (*blockData)[0] = *chromaDc++;
+ if ((*blockData)[0] || *totalCoeff)
+ {
+ if (h264bsdProcessBlock(*blockData, chromaQp, 1,*coeffMap) !=
+ HANTRO_OK)
+ return(HANTRO_NOK);
+ }
+ else
+ MARK_RESIDUAL_EMPTY(*blockData);
+ }
+
+ return(HANTRO_OK);
+}
+#endif /* H264DEC_OMXDL */
+
+/*------------------------------------------------------------------------------
+
+ Function: h264bsdSubMbPartMode
+
+ Functional description:
+ Returns the macroblock's sub-partition mode.
+
+------------------------------------------------------------------------------*/
+
+subMbPartMode_e h264bsdSubMbPartMode(subMbType_e subMbType)
+{
+
+/* Variables */
+
+
+/* Code */
+
+ ASSERT(subMbType < 4);
+
+ return((subMbPartMode_e)subMbType);
+
+}
+
+