/H264Dec/source/h264bsd_macroblock_layer.c
C | 1446 lines | 963 code | 197 blank | 286 comment | 221 complexity | e9c10cbce5b76995d4de7ce068518052 MD5 | raw file
Possible License(s): BSD-3-Clause
- /*
- * 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);
- }