10c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
20c1bc742181ded4930842b46e9507372f0b1b963James Dong *
30c1bc742181ded4930842b46e9507372f0b1b963James Dong * File Name:  omxVCM4P2_DecodeBlockCoef_Intra.c
40c1bc742181ded4930842b46e9507372f0b1b963James Dong * OpenMAX DL: v1.0.2
50c1bc742181ded4930842b46e9507372f0b1b963James Dong * Revision:   9641
60c1bc742181ded4930842b46e9507372f0b1b963James Dong * Date:       Thursday, February 7, 2008
70c1bc742181ded4930842b46e9507372f0b1b963James Dong *
80c1bc742181ded4930842b46e9507372f0b1b963James Dong * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
90c1bc742181ded4930842b46e9507372f0b1b963James Dong *
100c1bc742181ded4930842b46e9507372f0b1b963James Dong *
110c1bc742181ded4930842b46e9507372f0b1b963James Dong *
120c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
130c1bc742181ded4930842b46e9507372f0b1b963James Dong * Contains modules for intra reconstruction
140c1bc742181ded4930842b46e9507372f0b1b963James Dong *
150c1bc742181ded4930842b46e9507372f0b1b963James Dong */
160c1bc742181ded4930842b46e9507372f0b1b963James Dong
170c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxtypes.h"
180c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armOMX.h"
190c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxVC.h"
200c1bc742181ded4930842b46e9507372f0b1b963James Dong
210c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM.h"
220c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVC.h"
230c1bc742181ded4930842b46e9507372f0b1b963James Dong
240c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
250c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: omxVCM4P2_DecodeBlockCoef_Intra
260c1bc742181ded4930842b46e9507372f0b1b963James Dong *
270c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Decodes the INTRA block coefficients. Inverse quantization, inversely zigzag
290c1bc742181ded4930842b46e9507372f0b1b963James Dong * positioning, and IDCT, with appropriate clipping on each step, are performed
300c1bc742181ded4930842b46e9507372f0b1b963James Dong * on the coefficients. The results are then placed in the output frame/plane on
310c1bc742181ded4930842b46e9507372f0b1b963James Dong * a pixel basis. For INTRA block, the output values are clipped to [0, 255] and
320c1bc742181ded4930842b46e9507372f0b1b963James Dong * written to corresponding block buffer within the destination plane.
330c1bc742181ded4930842b46e9507372f0b1b963James Dong *
340c1bc742181ded4930842b46e9507372f0b1b963James Dong * Remarks:
350c1bc742181ded4930842b46e9507372f0b1b963James Dong *
360c1bc742181ded4930842b46e9507372f0b1b963James Dong * Parameters:
370c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	ppBitStream		pointer to the pointer to the current byte in
380c1bc742181ded4930842b46e9507372f0b1b963James Dong *								the bit stream buffer. There is no boundary
390c1bc742181ded4930842b46e9507372f0b1b963James Dong *								check for the bit stream buffer.
400c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pBitOffset		pointer to the bit position in the byte pointed
410c1bc742181ded4930842b46e9507372f0b1b963James Dong *								to by *ppBitStream. *pBitOffset is valid within
420c1bc742181ded4930842b46e9507372f0b1b963James Dong *								[0-7].
430c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	step			width of the destination plane
440c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in/out]	pCoefBufRow		[in]  pointer to the coefficient row buffer
450c1bc742181ded4930842b46e9507372f0b1b963James Dong *                        [out] updated coefficient rwo buffer
460c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in/out]	pCoefBufCol		[in]  pointer to the coefficient column buffer
470c1bc742181ded4930842b46e9507372f0b1b963James Dong *                        [out] updated coefficient column buffer
480c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	curQP			quantization parameter of the macroblock which
490c1bc742181ded4930842b46e9507372f0b1b963James Dong *								the current block belongs to
500c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pQpBuf		 Pointer to a 2-element QP array. pQpBuf[0] holds the QP of the 8x8 block left to
510c1bc742181ded4930842b46e9507372f0b1b963James Dong *                   the current block(QPa). pQpBuf[1] holds the QP of the 8x8 block just above the
520c1bc742181ded4930842b46e9507372f0b1b963James Dong *                   current block(QPc).
530c1bc742181ded4930842b46e9507372f0b1b963James Dong *                   Note, in case the corresponding block is out of VOP bound, the QP value will have
540c1bc742181ded4930842b46e9507372f0b1b963James Dong *                   no effect to the intra-prediction process. Refer to subclause  "7.4.3.3 Adaptive
550c1bc742181ded4930842b46e9507372f0b1b963James Dong *                   ac coefficient prediction" of ISO/IEC 14496-2(MPEG4 Part2) for accurate description.
560c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	blockIndex		block index indicating the component type and
570c1bc742181ded4930842b46e9507372f0b1b963James Dong *								position as defined in subclause 6.1.3.8,
580c1bc742181ded4930842b46e9507372f0b1b963James Dong *								Figure 6-5 of ISO/IEC 14496-2.
590c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	intraDCVLC		a code determined by intra_dc_vlc_thr and QP.
600c1bc742181ded4930842b46e9507372f0b1b963James Dong *								This allows a mechanism to switch between two VLC
610c1bc742181ded4930842b46e9507372f0b1b963James Dong *								for coding of Intra DC coefficients as per Table
620c1bc742181ded4930842b46e9507372f0b1b963James Dong *								6-21 of ISO/IEC 14496-2.
630c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	ACPredFlag		a flag equal to ac_pred_flag (of luminance) indicating
640c1bc742181ded4930842b46e9507372f0b1b963James Dong *								if the ac coefficients of the first row or first
650c1bc742181ded4930842b46e9507372f0b1b963James Dong *								column are differentially coded for intra coded
660c1bc742181ded4930842b46e9507372f0b1b963James Dong *								macroblock.
670c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] shortVideoHeader    a flag indicating presence of short_video_header;
680c1bc742181ded4930842b46e9507372f0b1b963James Dong *                           shortVideoHeader==1 selects linear intra DC mode,
690c1bc742181ded4930842b46e9507372f0b1b963James Dong *							and shortVideoHeader==0 selects nonlinear intra DC mode.
700c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]	ppBitStream		*ppBitStream is updated after the block is
710c1bc742181ded4930842b46e9507372f0b1b963James Dong *								decoded, so that it points to the current byte
720c1bc742181ded4930842b46e9507372f0b1b963James Dong *								in the bit stream buffer
730c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]	pBitOffset		*pBitOffset is updated so that it points to the
740c1bc742181ded4930842b46e9507372f0b1b963James Dong *								current bit position in the byte pointed by
750c1bc742181ded4930842b46e9507372f0b1b963James Dong *								*ppBitStream
760c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]	pDst			pointer to the block in the destination plane.
770c1bc742181ded4930842b46e9507372f0b1b963James Dong *								pDst should be 16-byte aligned.
780c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]	pCoefBufRow		pointer to the updated coefficient row buffer.
790c1bc742181ded4930842b46e9507372f0b1b963James Dong *
800c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
810c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr - no error
820c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr - bad arguments
830c1bc742181ded4930842b46e9507372f0b1b963James Dong *   -	At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset,
840c1bc742181ded4930842b46e9507372f0b1b963James Dong *                                                      pCoefBufRow, pCoefBufCol, pQPBuf, pDst.
850c1bc742181ded4930842b46e9507372f0b1b963James Dong *      or
860c1bc742181ded4930842b46e9507372f0b1b963James Dong *   -  At least one of the below case: *pBitOffset exceeds [0,7], curQP exceeds (1, 31),
870c1bc742181ded4930842b46e9507372f0b1b963James Dong *      blockIndex exceeds [0,9], step is not the multiple of 8, intraDCVLC is zero while
880c1bc742181ded4930842b46e9507372f0b1b963James Dong *      blockIndex greater than 5.
890c1bc742181ded4930842b46e9507372f0b1b963James Dong *      or
900c1bc742181ded4930842b46e9507372f0b1b963James Dong *   -	pDst is not 16-byte aligned
910c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_Err - status error
920c1bc742181ded4930842b46e9507372f0b1b963James Dong *
930c1bc742181ded4930842b46e9507372f0b1b963James Dong */
940c1bc742181ded4930842b46e9507372f0b1b963James Dong
950c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P2_DecodeBlockCoef_Intra(
960c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 ** ppBitStream,
970c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT *pBitOffset,
980c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_U8 *pDst,
990c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT step,
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_S16 *pCoefBufRow,
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_S16 *pCoefBufCol,
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_U8 curQP,
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pQPBuf,
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT blockIndex,
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT intraDCVLC,
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT ACPredFlag,
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong	 OMX_INT shortVideoHeader
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong )
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S16 tempBuf1[79], tempBuf2[79];
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S16 *pTempBuf1, *pTempBuf2;
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT predDir, predACDir;
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT  predQP;
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2VideoComponent videoComp;
1150c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXResult errorCode;
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Aligning the local buffers */
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempBuf1 = armAlignTo16Bytes(tempBuf1);
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempBuf2 = armAlignTo16Bytes(tempBuf2);
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Setting the AC prediction direction and prediction direction */
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong    armVCM4P2_SetPredDir(
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong        blockIndex,
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCoefBufRow,
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCoefBufCol,
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong        &predDir,
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong        &predQP,
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong        pQPBuf);
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong    predACDir = predDir;
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (ACPredFlag == 0)
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong        predACDir = OMX_VC_NONE;
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Setting the videoComp */
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (blockIndex <= 3)
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong        videoComp = OMX_VC_LUMINANCE;
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong        videoComp = OMX_VC_CHROMINANCE;
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* VLD and zigzag */
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (intraDCVLC == 1)
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1530c1bc742181ded4930842b46e9507372f0b1b963James Dong        errorCode = omxVCM4P2_DecodeVLCZigzag_IntraDCVLC(
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong            ppBitStream,
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong            pBitOffset,
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTempBuf1,
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong            predACDir,
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong            shortVideoHeader,
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong            videoComp);
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong        armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong    else
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong        errorCode = omxVCM4P2_DecodeVLCZigzag_IntraACVLC(
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong            ppBitStream,
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong            pBitOffset,
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTempBuf1,
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong            predACDir,
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong            shortVideoHeader);
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong        armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* AC DC prediction */
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong    errorCode = omxVCM4P2_PredictReconCoefIntra(
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempBuf1,
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCoefBufRow,
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCoefBufCol,
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong        curQP,
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong        predQP,
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong        predDir,
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong        ACPredFlag,
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong        videoComp);
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Dequantization */
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong    errorCode = omxVCM4P2_QuantInvIntra_I(
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong     pTempBuf1,
1880c1bc742181ded4930842b46e9507372f0b1b963James Dong     curQP,
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong     videoComp,
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong     shortVideoHeader);
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Inverse transform */
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong    errorCode = omxVCM4P2_IDCT8x8blk (pTempBuf1, pTempBuf2);
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetDataErrIf((errorCode != OMX_Sts_NoErr), errorCode);
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Placing the linear array into the destination plane and clipping
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong       it to 0 to 255 */
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong	armVCM4P2_Clip8(pTempBuf2,pDst,step);
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong}
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong
209