blob: 91ec5d2fe5f78fda6fceb09aa8820ff673031e7f [file] [log] [blame]
/*
* Copyright (C) 2007-2008 ARM Limited
*
* 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.
*
*/
/**
*
* File Name: omxVCM4P2_DecodeBlockCoef_Intra.c
* OpenMAX DL: v1.0.2
* Revision: 12290
* Date: Wednesday, April 9, 2008
*
*
*
*
* Description:
* Contains modules for intra reconstruction
*
*/
#include "omxtypes.h"
#include "armOMX.h"
#include "omxVC.h"
#include "armCOMM.h"
#include "armVC.h"
/* Function for saturating 16 bit values to the [0,255] range and */
/* writing out as 8 bit values. Does 64 entries */
void armVCM4P2_Clip8(OMX_S16 *pSrc, OMX_U8 *pDst, OMX_INT dstStep );
/**
* Function: omxVCM4P2_DecodeBlockCoef_Intra
*
* 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. For INTRA block, the output values are clipped to [0, 255] and
* written to corresponding block buffer within the destination plane.
*
* Remarks:
*
* Parameters:
* [in] ppBitStream pointer to the pointer to the current byte in
* the bit stream buffer. There is no boundary
* check for the bit stream buffer.
* [in] pBitOffset pointer to the bit position in the byte pointed
* to by *ppBitStream. *pBitOffset is valid within
* [0-7].
* [in] step width of the destination plane
* [in/out] pCoefBufRow [in] pointer to the coefficient row buffer
* [out] updated coefficient rwo buffer
* [in/out] pCoefBufCol [in] pointer to the coefficient column buffer
* [out] updated coefficient column buffer
* [in] curQP quantization parameter of the macroblock which
* the current block belongs to
* [in] pQpBuf Pointer to a 2-element QP array. pQpBuf[0] holds the QP of the 8x8 block left to
* the current block(QPa). pQpBuf[1] holds the QP of the 8x8 block just above the
* current block(QPc).
* Note, in case the corresponding block is out of VOP bound, the QP value will have
* no effect to the intra-prediction process. Refer to subclause "7.4.3.3 Adaptive
* ac coefficient prediction" of ISO/IEC 14496-2(MPEG4 Part2) for accurate description.
* [in] blockIndex block index indicating the component type and
* position as defined in subclause 6.1.3.8,
* Figure 6-5 of ISO/IEC 14496-2.
* [in] 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 Table
* 6-21 of ISO/IEC 14496-2.
* [in] 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.
* [in] shortVideoHeader a flag indicating presence of short_video_header;
* shortVideoHeader==1 selects linear intra DC mode,
* and shortVideoHeader==0 selects nonlinear intra DC mode.
* [out] ppBitStream *ppBitStream is updated after the block is
* decoded, so that it points to the current byte
* in the bit stream buffer
* [out] pBitOffset *pBitOffset is updated so that it points to the
* current bit position in the byte pointed by
* *ppBitStream
* [out] pDst pointer to the block in the destination plane.
* pDst should be 16-byte aligned.
* [out] pCoefBufRow pointer to the updated coefficient row buffer.
*
* Return Value:
* OMX_Sts_NoErr - no error
* OMX_Sts_BadArgErr - bad arguments
* - At least one of the following pointers is NULL: ppBitStream, *ppBitStream, pBitOffset,
* pCoefBufRow, pCoefBufCol, pQPBuf, pDst.
* or
* - At least one of the below case: *pBitOffset exceeds [0,7], curQP exceeds (1, 31),
* blockIndex exceeds [0,9], step is not the multiple of 8, intraDCVLC is zero while
* blockIndex greater than 5.
* or
* - pDst is not 16-byte aligned
* OMX_Sts_Err - status error
*
*/
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;
OMX_INT predQP;
OMXVCM4P2VideoComponent videoComp;
OMXResult errorCode;
/* 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;
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 */
armVCM4P2_Clip8(pTempBuf2,pDst,step);
return OMX_Sts_NoErr;
}
/* End of file */