blob: 8a022ba3a6f9f17830ab90932acd6199956fce75 [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: omxVCM4P10_DequantTransformResidualFromPairAndAdd.c
* OpenMAX DL: v1.0.2
* Revision: 9641
* Date: Thursday, February 7, 2008
*
*
*
*
* H.264 inverse quantize and transform module
*
*/
#include "omxtypes.h"
#include "armOMX.h"
#include "omxVC.h"
#include "armCOMM.h"
#include "armVC.h"
/*
* Description:
* Dequantize Luma AC block
*/
static void DequantLumaAC4x4(
OMX_S16* pSrcDst,
OMX_INT QP
)
{
const OMX_U8 *pVRow = &armVCM4P10_VMatrix[QP%6][0];
int Shift = QP / 6;
int i;
OMX_S32 Value;
for (i=0; i<16; i++)
{
Value = (pSrcDst[i] * pVRow[armVCM4P10_PosToVCol4x4[i]]) << Shift;
pSrcDst[i] = (OMX_S16)Value;
}
}
/**
* Function: omxVCM4P10_DequantTransformResidualFromPairAndAdd (6.3.4.2.3)
*
* Description:
* Reconstruct the 4x4 residual block from coefficient-position pair buffer,
* perform dequantization and integer inverse transformation for 4x4 block of
* residuals with previous intra prediction or motion compensation data, and
* update the pair buffer pointer to next non-empty block. If pDC == NULL,
* there re 16 non-zero AC coefficients at most in the packed buffer starting
* from 4x4 block position 0; If pDC != NULL, there re 15 non-zero AC
* coefficients at most in the packet buffer starting from 4x4 block position
* 1.
*
* Input Arguments:
*
* ppSrc - Double pointer to residual coefficient-position pair buffer
* output by CALVC decoding
* pPred - Pointer to the predicted 4x4 block; must be aligned on a 4-byte
* boundary
* predStep - Predicted frame step size in bytes; must be a multiple of 4
* dstStep - Destination frame step in bytes; must be a multiple of 4
* pDC - Pointer to the DC coefficient of this block, NULL if it doesn't
* exist
* QP - QP Quantization parameter. It should be QpC in chroma 4x4 block
* decoding, otherwise it should be QpY.
* AC - Flag indicating if at least one non-zero AC coefficient exists
*
* Output Arguments:
*
* pDst - pointer to the reconstructed 4x4 block data; must be aligned on a
* 4-byte boundary
*
* Return Value:
* OMX_Sts_NoErr, if the function runs without error.
* OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
* - pPred or pDst is NULL.
* - pPred or pDst is not 4-byte aligned.
* - predStep or dstStep is not a multiple of 4.
* - AC !=0 and Qp is not in the range of [0-51] or ppSrc == NULL.
* - AC ==0 && pDC ==NULL.
*
*/
OMXResult omxVCM4P10_DequantTransformResidualFromPairAndAdd(
const OMX_U8 **ppSrc,
const OMX_U8 *pPred,
const OMX_S16 *pDC,
OMX_U8 *pDst,
OMX_INT predStep,
OMX_INT dstStep,
OMX_INT QP,
OMX_INT AC
)
{
OMX_S16 pBuffer[16+4];
OMX_S16 *pDelta;
int i,x,y;
armRetArgErrIf(pPred == NULL, OMX_Sts_BadArgErr);
armRetArgErrIf(armNot4ByteAligned(pPred),OMX_Sts_BadArgErr);
armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
armRetArgErrIf(armNot4ByteAligned(pDst), OMX_Sts_BadArgErr);
armRetArgErrIf(predStep & 3, OMX_Sts_BadArgErr);
armRetArgErrIf(dstStep & 3, OMX_Sts_BadArgErr);
armRetArgErrIf(AC!=0 && (QP<0), OMX_Sts_BadArgErr);
armRetArgErrIf(AC!=0 && (QP>51), OMX_Sts_BadArgErr);
armRetArgErrIf(AC!=0 && ppSrc==NULL, OMX_Sts_BadArgErr);
armRetArgErrIf(AC!=0 && *ppSrc==NULL, OMX_Sts_BadArgErr);
armRetArgErrIf(AC==0 && pDC==NULL, OMX_Sts_BadArgErr);
pDelta = armAlignTo8Bytes(pBuffer);
for (i=0; i<16; i++)
{
pDelta[i] = 0;
}
if (AC)
{
armVCM4P10_UnpackBlock4x4(ppSrc, pDelta);
DequantLumaAC4x4(pDelta, QP);
}
if (pDC)
{
pDelta[0] = pDC[0];
}
armVCM4P10_TransformResidual4x4(pDelta,pDelta);
for (y=0; y<4; y++)
{
for (x=0; x<4; x++)
{
pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,pPred[y*predStep+x] + pDelta[4*y+x]);
}
}
return OMX_Sts_NoErr;
}
/* End of file */