/** * * File Name: omxVCM4P2_DecodeBlockCoef_Intra.c * OpenMAX DL: v1.0.2 * Revision: 9641 * Date: Thursday, February 7, 2008 * * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. * * * * Description: * Contains modules for intra reconstruction * */ #include "omxtypes.h" #include "armOMX.h" #include "omxVC.h" #include "armCOMM.h" #include "armVC.h" /** * Function: omxVCM4P2_DecodeBlockCoef_Intra (6.2.5.4.1) * * Description: * Decodes the INTRA block coefficients. Inverse quantization, inversely * zigzag positioning, and IDCT, with appropriate clipping on each step, are * performed on the coefficients. The results are then placed in the output * frame/plane on a pixel basis. Note: This function will be used only when * at least one non-zero AC coefficient of current block exists in the bit * stream. The DC only condition will be handled in another function. * * * Input Arguments: * * ppBitStream - pointer to the pointer to the current byte in the bit * stream buffer. There is no boundary check for the bit stream * buffer. * pBitOffset - pointer to the bit position in the byte pointed to by * *ppBitStream. *pBitOffset is valid within [0-7]. * step - width of the destination plane * pCoefBufRow - pointer to the coefficient row buffer; must be aligned on * an 8-byte boundary. * pCoefBufCol - pointer to the coefficient column buffer; must be aligned * on an 8-byte boundary. * curQP - quantization parameter of the macroblock which the current block * belongs to * pQPBuf - pointer to the quantization parameter buffer * blockIndex - block index indicating the component type and position as * defined in [ISO14496-2], subclause 6.1.3.8, Figure 6-5. * intraDCVLC - a code determined by intra_dc_vlc_thr and QP. This allows a * mechanism to switch between two VLC for coding of Intra DC * coefficients as per [ISO14496-2], Table 6-21. * ACPredFlag - a flag equal to ac_pred_flag (of luminance) indicating if * the ac coefficients of the first row or first column are * differentially coded for intra coded macroblock. * shortVideoHeader - binary flag indicating presence of * short_video_header; shortVideoHeader==1 selects linear intra DC * mode, and shortVideoHeader==0 selects non linear intra DC mode. * * Output Arguments: * * ppBitStream - *ppBitStream is updated after the block is decoded, so * that it points to the current byte in the bit stream buffer * pBitOffset - *pBitOffset is updated so that it points to the current bit * position in the byte pointed by *ppBitStream * pDst - pointer to the block in the destination plane; must be aligned on * an 8-byte boundary. * pCoefBufRow - pointer to the updated coefficient row buffer. * pCoefBufCol - pointer to the updated coefficient column buffer Note: * The coefficient buffers must be updated in accordance with the * update procedure defined in section 6.2.2. * * Return Value: * * OMX_Sts_NoErr - no error * OMX_Sts_BadArgErr - bad arguments, if: * - At least one of the following pointers is NULL: * ppBitStream, *ppBitStream, pBitOffset, pCoefBufRow, pCoefBufCol, * pQPBuf, pDst. * - *pBitOffset exceeds [0,7] * - curQP exceeds (1, 31) * - blockIndex exceeds [0,5] * - step is not the multiple of 8 * - a pointer alignment requirement was violated. * OMX_Sts_Err - status error. Refer to OMX_Sts_Err of DecodeVLCZigzag_Intra. * */ OMXResult omxVCM4P2_DecodeBlockCoef_Intra( const OMX_U8 ** ppBitStream, OMX_INT *pBitOffset, OMX_U8 *pDst, OMX_INT step, OMX_S16 *pCoefBufRow, OMX_S16 *pCoefBufCol, OMX_U8 curQP, const OMX_U8 *pQPBuf, OMX_INT blockIndex, OMX_INT intraDCVLC, OMX_INT ACPredFlag, OMX_INT shortVideoHeader ) { OMX_S16 tempBuf1[79], tempBuf2[79]; OMX_S16 *pTempBuf1, *pTempBuf2; OMX_INT predDir, predACDir, i, j, count; OMX_INT predQP; OMXVCM4P2VideoComponent videoComp; OMXResult errorCode; /* Argument error checks */ armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pCoefBufRow == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pCoefBufCol == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(pQPBuf == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf(((curQP <= 0) || (curQP >= 32)), OMX_Sts_BadArgErr); armRetArgErrIf((*pBitOffset < 0) || (*pBitOffset >7), OMX_Sts_BadArgErr); armRetArgErrIf((blockIndex < 0) || (blockIndex > 5), OMX_Sts_BadArgErr); armRetArgErrIf((step % 8) != 0, OMX_Sts_BadArgErr); /* Aligning the local buffers */ pTempBuf1 = armAlignTo16Bytes(tempBuf1); pTempBuf2 = armAlignTo16Bytes(tempBuf2); /* Setting the AC prediction direction and prediction direction */ armVCM4P2_SetPredDir( blockIndex, pCoefBufRow, pCoefBufCol, &predDir, &predQP, pQPBuf); predACDir = predDir; armRetArgErrIf(((predQP <= 0) || (predQP >= 32)), OMX_Sts_BadArgErr); if (ACPredFlag == 0) { predACDir = OMX_VC_NONE; } /* Setting the videoComp */ if (blockIndex <= 3) { videoComp = OMX_VC_LUMINANCE; } else { videoComp = OMX_VC_CHROMINANCE; } /* VLD and zigzag */ if (intraDCVLC == 1) { errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC( ppBitStream, pBitOffset, pTempBuf1, predACDir, shortVideoHeader, videoComp); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); } else { errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC( ppBitStream, pBitOffset, pTempBuf1, predACDir, shortVideoHeader); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); } /* AC DC prediction */ errorCode = omxVCM4P2_PredictReconCoefIntra( pTempBuf1, pCoefBufRow, pCoefBufCol, curQP, predQP, predDir, ACPredFlag, videoComp); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); /* Dequantization */ errorCode = omxVCM4P2_QuantInvIntra_I( pTempBuf1, curQP, videoComp, shortVideoHeader); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); /* Inverse transform */ errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2); armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode); /* Placing the linear array into the destination plane and clipping it to 0 to 255 */ for (j = 0, count = 0; j < 8; j++) { for(i = 0; i < 8; i++, count++) { pDst[i] = armClip (0, 255, pTempBuf2[count]); } pDst += step; } return OMX_Sts_NoErr; } /* End of file */