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;

}