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