blob: 970da6cecf989bd3d60196a7f3878c1a6b88d90e [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: 9641
* Date: Thursday, February 7, 2008
*
*
*
*
* 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 */