OMXResult omxVCM4P2_QuantInter_I( OMX_S16 * pSrcDst, OMX_U8 QP, OMX_INT shortVideoHeader ) { /* Definitions and Initializations*/ OMX_INT coeffCount; OMX_INT fSign; OMX_INT maxClpAC = 0, minClpAC = 0; OMX_INT maxClpDC = 0, minClpDC = 0; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* One argument check is delayed until we have ascertained that */ /* pQMatrix is not NULL. */ /* Set the Clip Range based on SVH on/off */ if(shortVideoHeader == 1) { maxClpDC = 254; minClpDC = 1; maxClpAC = 127; minClpAC = -127; } else { maxClpDC = 2047; minClpDC = -2047; maxClpAC = 2047; minClpAC = -2047; } /* Second Inverse quantisation method */ for (coeffCount = 0; coeffCount < 64; coeffCount++) { fSign = armSignCheck (pSrcDst[coeffCount]); pSrcDst[coeffCount] = (armAbs(pSrcDst[coeffCount]) - (QP/2))/(2 * QP); pSrcDst[coeffCount] *= fSign; /* Clip */ if (coeffCount == 0) { pSrcDst[coeffCount] = (OMX_S16) armClip (minClpDC, maxClpDC, pSrcDst[coeffCount]); } else { pSrcDst[coeffCount] = (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]); } } return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_QuantInvInter_I( OMX_S16 * pSrcDst, OMX_INT QP ) { OMX_INT coeffCount, Sign; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* Second Inverse quantisation method */ for (coeffCount = 0; coeffCount < 64; coeffCount++) { /* check sign */ Sign = armSignCheck (pSrcDst[coeffCount]); /* Quantize the coeff */ if (QP & 0x1) { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP; pSrcDst[coeffCount] *= Sign; } else { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP - 1; pSrcDst[coeffCount] *= Sign; } /* Saturate */ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }
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; }
OMXResult armVCM4P10_InterpolateHalfHor_Luma( const OMX_U8* pSrc, OMX_U32 iSrcStep, OMX_U8* pDst, OMX_U32 iDstStep, OMX_U32 iWidth, OMX_U32 iHeight ) { OMX_INT x, y; OMX_S32 HalfCoeff, pos; /* check for argument error */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) for (y = 0; y < iHeight; y++) { for (x = 0; x < iWidth; x++) { pos = y * iSrcStep + x; HalfCoeff = pSrc [pos - 2] - 5 * pSrc [pos - 1] + 20 * pSrc [pos] + 20 * pSrc [pos + 1] - 5 * pSrc [pos + 2] + pSrc [pos + 3]; HalfCoeff = (HalfCoeff + 16) >> 5; HalfCoeff = armClip(0, 255, HalfCoeff); pDst [y * iDstStep + x] = HalfCoeff; } /* x */ } /* y */ return OMX_Sts_NoErr; }
OMXResult omxVCM4P2_QuantIntra_I( OMX_S16 * pSrcDst, OMX_U8 QP, OMX_INT blockIndex, OMX_INT shortVideoHeader ) { /* Definitions and Initializations*/ /* Initialized to remove compilation error */ OMX_INT dcScaler = 0, coeffCount,fSign; OMX_INT maxClpAC, minClpAC; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((blockIndex < 0) || (blockIndex >= 10)), OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); /* One argument check is delayed until we have ascertained that */ /* pQMatrix is not NULL. */ /* Set the Clip Range based on SVH on/off */ if(shortVideoHeader == 1) { maxClpAC = 127; minClpAC = -127; dcScaler = 8; /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler); /* Clip between 1 and 254 */ pSrcDst[0] = (OMX_S16) armClip (1, 254, pSrcDst[0]); } else { maxClpAC = 2047; minClpAC = -2047; /* Calculate the DC scaler value */ if ((blockIndex < 4) || (blockIndex > 5)) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 8) { dcScaler = 2 * QP; } else if (QP >= 9 && QP <= 24) { dcScaler = QP + 8; } else { dcScaler = (2 * QP) - 16; } } else if (blockIndex < 6) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 24) { dcScaler = (QP + 13)/2; } else { dcScaler = QP - 6; } } /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = armIntDivAwayFromZero (pSrcDst[0], dcScaler); } /* Second Inverse quantisation method */ for (coeffCount = 1; coeffCount < 64; coeffCount++) { fSign = armSignCheck (pSrcDst[coeffCount]); pSrcDst[coeffCount] = armAbs(pSrcDst[coeffCount])/(2 * QP); pSrcDst[coeffCount] *= fSign; /* Clip */ pSrcDst[coeffCount] = (OMX_S16) armClip (minClpAC, maxClpAC, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }
OMXResult armVCM4P10_InterpolateHalfDiag_Luma( const OMX_U8* pSrc, OMX_U32 iSrcStep, OMX_U8* pDst, OMX_U32 iDstStep, OMX_U32 iWidth, OMX_U32 iHeight ) { OMX_S32 HalfCoeff, pos; OMX_S16 Buf [21 * 16]; /* 21 rows by 16 pixels per row */ OMX_U32 y, x; /* check for argument error */ armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr) armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr) /* * Intermediate values will be 1/2 pel at Horizontal direction * Starting at (0.5, -2) at top extending to (0.5, height + 3) at bottom * Buf contains a 2D array of size (iWidth)X(iHeight + 5) */ for (y = 0; y < iHeight + 5; y++) { for (x = 0; x < iWidth; x++) { pos = (y-2) * iSrcStep + x; HalfCoeff = pSrc [pos - 2] - 5 * pSrc [pos - 1] + 20 * pSrc [pos] + 20 * pSrc [pos + 1] - 5 * pSrc [pos + 2] + pSrc [pos + 3]; Buf [y * iWidth + x] = (OMX_S16)HalfCoeff; } /* x */ } /* y */ /* Vertical interpolate */ for (y = 0; y < iHeight; y++) { for (x = 0; x < iWidth; x++) { pos = y * iWidth + x; HalfCoeff = Buf [pos] - 5 * Buf [pos + 1 * iWidth] + 20 * Buf [pos + 2 * iWidth] + 20 * Buf [pos + 3 * iWidth] - 5 * Buf [pos + 4 * iWidth] + Buf [pos + 5 * iWidth]; HalfCoeff = (HalfCoeff + 512) >> 10; HalfCoeff = armClip(0, 255, HalfCoeff); pDst [y * iDstStep + x] = (OMX_U8) HalfCoeff; } } return OMX_Sts_NoErr; }
/** * Function: omxVCM4P10_PredictIntraChroma_8x8 (6.3.3.1.3) * * Description: * Performs intra prediction for chroma samples. * * Input Arguments: * * pSrcLeft - Pointer to the buffer of 8 left pixels: p[x, y] (x = -1, y= * 0..7). * pSrcAbove - Pointer to the buffer of 8 above pixels: p[x,y] (x = 0..7, y * = -1); must be aligned on an 8-byte boundary. * pSrcAboveLeft - Pointer to the above left pixels: p[x,y] (x = -1, y = -1) * leftStep - Step of left pixel buffer; must be a multiple of 8. * dstStep - Step of the destination buffer; must be a multiple of 8. * predMode - Intra chroma prediction mode, please refer to section 3.4.3. * availability - Neighboring chroma block availability flag, please refer * to "Neighboring Macroblock Availability". * * Output Arguments: * * pDst - Pointer to the destination buffer; must be aligned on an 8-byte * boundary. * * Return Value: * If the function runs without error, it returns OMX_Sts_NoErr. * If any of the following cases occurs, the function returns * OMX_Sts_BadArgErr: * pDst is NULL. * dstStep < 8 or dstStep is not a multiple of 8. * leftStep is not a multiple of 8. * predMode is not in the valid range of enumeration * OMXVCM4P10IntraChromaPredMode. * predMode is OMX_VC_CHROMA_VERT, but availability doesn't set * OMX_VC_UPPER indicating p[x,-1] (x = 0..7) is not available. * predMode is OMX_VC_CHROMA_HOR, but availability doesn't set OMX_VC_LEFT * indicating p[-1,y] (y = 0..7) is not available. * predMode is OMX_VC_CHROMA_PLANE, but availability doesn't set * OMX_VC_UPPER_LEFT or OMX_VC_UPPER or OMX_VC_LEFT indicating * p[x,-1](x = 0..7), or p[-1,y] (y = 0..7), or p[-1,-1] is not * available. * availability sets OMX_VC_UPPER, but pSrcAbove is NULL. * availability sets OMX_VC_LEFT, but pSrcLeft is NULL. * availability sets OMX_VC_UPPER_LEFT, but pSrcAboveLeft is NULL. * either pSrcAbove or pDst is not aligned on a 8-byte boundary. Note: * pSrcAbove, pSrcAbove, pSrcAboveLeft may be invalid pointer if * they are not used by intra prediction implied in predMode. * Note: OMX_VC_UPPER_RIGHT is not used in intra chroma * prediction. * */ OMXResult omxVCM4P10_PredictIntraChroma_8x8( const OMX_U8* pSrcLeft, const OMX_U8 *pSrcAbove, const OMX_U8 *pSrcAboveLeft, OMX_U8* pDst, OMX_INT leftStep, OMX_INT dstStep, OMXVCM4P10IntraChromaPredMode predMode, OMX_S32 availability ) { int x, y, Sum; int H, V, a, b, c; armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(dstStep < 8, OMX_Sts_BadArgErr); armRetArgErrIf((dstStep % 8) != 0, OMX_Sts_BadArgErr); armRetArgErrIf((leftStep % 8) != 0, OMX_Sts_BadArgErr); armRetArgErrIf(armNot8ByteAligned(pSrcAbove), OMX_Sts_BadArgErr); armRetArgErrIf(armNot8ByteAligned(pDst), OMX_Sts_BadArgErr); armRetArgErrIf((availability & OMX_VC_UPPER) && pSrcAbove == NULL, OMX_Sts_BadArgErr); armRetArgErrIf((availability & OMX_VC_LEFT ) && pSrcLeft == NULL, OMX_Sts_BadArgErr); armRetArgErrIf((availability & OMX_VC_UPPER_LEFT) && pSrcAboveLeft == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(predMode==OMX_VC_CHROMA_VERT && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); armRetArgErrIf(predMode==OMX_VC_CHROMA_HOR && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER), OMX_Sts_BadArgErr); armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_UPPER_LEFT), OMX_Sts_BadArgErr); armRetArgErrIf(predMode==OMX_VC_CHROMA_PLANE && !(availability & OMX_VC_LEFT), OMX_Sts_BadArgErr); armRetArgErrIf((unsigned)predMode > OMX_VC_CHROMA_PLANE, OMX_Sts_BadArgErr); switch (predMode) { case OMX_VC_CHROMA_DC: armVCM4P10_PredictIntraDC4x4( pSrcLeft, pSrcAbove, pDst, leftStep, dstStep, availability); armVCM4P10_PredictIntraDCUp4x4( pSrcLeft, pSrcAbove+4, pDst+4, leftStep, dstStep, availability); armVCM4P10_PredictIntraDCLeft4x4( pSrcLeft+4*leftStep, pSrcAbove, pDst+4*dstStep, leftStep, dstStep, availability); armVCM4P10_PredictIntraDC4x4( pSrcLeft+4*leftStep, pSrcAbove+4, pDst+4+4*dstStep, leftStep, dstStep, availability); break; case OMX_VC_CHROMA_HOR: for (y=0; y<8; y++) { for (x=0; x<8; x++) { pDst[y*dstStep+x] = pSrcLeft[y*leftStep]; } } break; case OMX_VC_CHROMA_VERT: for (y=0; y<8; y++) { for (x=0; x<8; x++) { pDst[y*dstStep+x] = pSrcAbove[x]; } } break; case OMX_VC_CHROMA_PLANE: H = 4*(pSrcAbove[7] - pSrcAboveLeft[0]); for (x=2; x>=0; x--) { H += (x+1)*(pSrcAbove[4+x] - pSrcAbove[2-x]); } V = 4*(pSrcLeft[7*leftStep] - pSrcAboveLeft[0]); for (y=2; y>=0; y--) { V += (y+1)*(pSrcLeft[(4+y)*leftStep] - pSrcLeft[(2-y)*leftStep]); } a = 16*(pSrcAbove[7] + pSrcLeft[7*leftStep]); b = (17*H+16)>>5; c = (17*V+16)>>5; for (y=0; y<8; y++) { for (x=0; x<8; x++) { Sum = (a + b*(x-3) + c*(y-3) + 16)>>5; pDst[y*dstStep+x] = (OMX_U8)armClip(0,255,Sum); } } break; } return OMX_Sts_NoErr; }
void armVCM4P10_DeBlockPixel( OMX_U8 *pQ0, /* pointer to the pixel q0 */ int Step, /* step between pixels q0 and q1 */ int tC0, /* edge threshold value */ int alpha, /* alpha */ int beta, /* beta */ int bS, /* deblocking strength */ int ChromaFlag ) { int p3, p2, p1, p0, q0, q1, q2, q3; int ap, aq, delta; if (bS==0) { return; } p3 = pQ0[-4*Step]; p2 = pQ0[-3*Step]; p1 = pQ0[-2*Step]; p0 = pQ0[-1*Step]; q0 = pQ0[ 0*Step]; q1 = pQ0[ 1*Step]; q2 = pQ0[ 2*Step]; q3 = pQ0[ 3*Step]; if (armAbs(p0-q0)>=alpha || armAbs(p1-p0)>=beta || armAbs(q1-q0)>=beta) { DEBUG_PRINTF_10("DeBlockPixel: %02x %02x %02x %02x | %02x %02x %02x %02x alpha=%d beta=%d\n", p3, p2, p1, p0, q0, q1, q2, q3, alpha, beta); return; } ap = armAbs(p2 - p0); aq = armAbs(q2 - q0); if (bS < 4) { int tC = tC0; if (ChromaFlag) { tC++; } else { if (ap < beta) { tC++; } if (aq < beta) { tC++; } } delta = (((q0-p0)<<2) + (p1-q1) + 4) >> 3; delta = armClip(-tC, tC, delta); pQ0[-1*Step] = (OMX_U8)armClip(0, 255, p0 + delta); pQ0[ 0*Step] = (OMX_U8)armClip(0, 255, q0 - delta); if (ChromaFlag==0 && ap<beta) { delta = (p2 + ((p0+q0+1)>>1) - (p1<<1))>>1; delta = armClip(-tC0, tC0, delta); pQ0[-2*Step] = (OMX_U8)(p1 + delta); }
OMXResult omxVCM4P2_QuantInvIntra_I( OMX_S16 * pSrcDst, OMX_INT QP, OMXVCM4P2VideoComponent videoComp, OMX_INT shortVideoHeader ) { /* Initialized to remove compilation error */ OMX_INT dcScaler = 0, coeffCount, Sign; /* Argument error checks */ armRetArgErrIf(pSrcDst == NULL, OMX_Sts_BadArgErr); armRetArgErrIf(((QP <= 0) || (QP >= 32)), OMX_Sts_BadArgErr); armRetArgErrIf(((videoComp != OMX_VC_LUMINANCE) && (videoComp != OMX_VC_CHROMINANCE)), OMX_Sts_BadArgErr); /* Calculate the DC scaler value */ /* linear intra DC mode */ if(shortVideoHeader) { dcScaler = 8; } /* nonlinear intra DC mode */ else { if (videoComp == OMX_VC_LUMINANCE) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 8) { dcScaler = 2 * QP; } else if (QP >= 9 && QP <= 24) { dcScaler = QP + 8; } else { dcScaler = (2 * QP) - 16; } } else if (videoComp == OMX_VC_CHROMINANCE) { if (QP >= 1 && QP <= 4) { dcScaler = 8; } else if (QP >= 5 && QP <= 24) { dcScaler = (QP + 13)/2; } else { dcScaler = QP - 6; } } } /* Dequant the DC value, this applies to both the methods */ pSrcDst[0] = pSrcDst[0] * dcScaler; /* Saturate */ pSrcDst[0] = armClip (-2048, 2047, pSrcDst[0]); /* Second Inverse quantisation method */ for (coeffCount = 1; coeffCount < 64; coeffCount++) { /* check sign */ Sign = armSignCheck (pSrcDst[coeffCount]); if (QP & 0x1) { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP; pSrcDst[coeffCount] *= Sign; } else { pSrcDst[coeffCount] = (2* armAbs(pSrcDst[coeffCount]) + 1) * QP - 1; pSrcDst[coeffCount] *= Sign; } /* Saturate */ pSrcDst[coeffCount] = armClip (-2048, 2047, pSrcDst[coeffCount]); } return OMX_Sts_NoErr; }