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 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 armVCM4P2_SetPredDir(
    OMX_INT blockIndex,
    OMX_S16 *pCoefBufRow,
    OMX_S16 *pCoefBufCol,
    OMX_INT *predDir,
    OMX_INT *predQP,
    const OMX_U8 *pQpBuf
)
{
    OMX_U8  blockDCLeft;
    OMX_U8  blockDCTop;
    OMX_U8  blockDCTopLeft;

    if (blockIndex == 3)
    {
        blockDCTop = *(pCoefBufCol - 8);
    }
    else
    {
        blockDCTop = *pCoefBufRow;
    }
    blockDCLeft = *pCoefBufCol;
    blockDCTopLeft = *(pCoefBufRow - 8);

    if (armAbs(blockDCLeft - blockDCTopLeft) < armAbs(blockDCTopLeft \
            - blockDCTop))
    {
        *predDir = OMX_VC_VERTICAL;
        *predQP = pQpBuf[1];
    }
    else
    {
        *predDir = OMX_VC_HORIZONTAL;
        *predQP = pQpBuf[0];
    }
    return OMX_Sts_NoErr;
}
static OMX_U16 armVCM4P10_ExpGolBitsUsed (OMX_S16 val)
{
    OMX_U16 sizeCodeNum, codeNum;
    
    /* Mapping val to codeNum */
    codeNum = armAbs (val);
    if (val > 0)
    {
        codeNum = (2 * codeNum) - 1;
    }
    else
    {
        codeNum = 2 * codeNum;
    }
    
    /* Size of the exp-golomb code */
    sizeCodeNum = (2 * armLogSize (codeNum + 1)) - 1;
    
    return sizeCodeNum;
}
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 omxVCM4P2_MotionEstimationMB (
    const OMX_U8 *pSrcCurrBuf,
    OMX_S32 srcCurrStep,
    const OMX_U8 *pSrcRefBuf,
    OMX_S32 srcRefStep,
    const OMXRect*pRefRect,
    const OMXVCM4P2Coordinate *pCurrPointPos,
    void *pMESpec,
    const OMXVCM4P2MBInfoPtr *pMBInfo,
    OMXVCM4P2MBInfo *pSrcDstMBCurr,
    OMX_U16 *pDstSAD,
    OMX_U16 *pDstBlockSAD
)
{
 
    OMX_INT intraSAD, average, count, index, x, y;
    OMXVCMotionVector dstMV16x16;
    OMX_INT           dstSAD16x16;
    OMX_INT           dstSAD8x8;
    OMXVCM4P2MEParams  *pMEParams; 
	OMXVCM4P2Coordinate TempCurrPointPos; 
    OMXVCM4P2Coordinate *pTempCurrPointPos; 
    OMX_U8 aTempSrcCurrBuf[271];
    OMX_U8 *pTempSrcCurrBuf;
    OMX_U8 *pDst;
    OMX_U8 aDst[71];
    OMX_S32 dstStep = 8;
    OMX_INT predictType;
	OMX_S32 Sad;
    const OMX_U8 *pTempSrcRefBuf;
    OMXVCMotionVector* pSrcCandMV1[4];
    OMXVCMotionVector* pSrcCandMV2[4];
    OMXVCMotionVector* pSrcCandMV3[4];
        
    /* Argument error checks */
    armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
	armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr);
    armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr);
	armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
	armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);    
    armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
    
    
    pTempCurrPointPos = &(TempCurrPointPos);
    pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf);
    pMEParams = (OMXVCM4P2MEParams *)pMESpec;
    pTempCurrPointPos->x = pCurrPointPos->x;
    pTempCurrPointPos->y = pCurrPointPos->y;
    pSrcDstMBCurr->mbType = OMX_VC_INTER;
    
    /* Preparing a linear buffer for block match */
    for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16)
    {
        for(x = 0; x < 16; x++, count++, index++)
        {
            pTempSrcCurrBuf[count] = pSrcCurrBuf[index];
        }
    }
    for(y = 0, index = 0; y < 2; y++)
    {
        for(x = 0; x < 2; x++,index++)
        {
            if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA))
            {
               pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]); 
            }
            else
            {
               pSrcCandMV1[index] = NULL;
            }
            if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA))
            {
               pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]);
            }
            else
            {
               pSrcCandMV2[index] = NULL; 
            }
            if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA))
            {
               pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]);
            }
            else
            {
               pSrcCandMV3[index] = NULL; 
            }
        }
    }
	/* Calculating SAD at MV(0,0) */
	armVCCOMM_SAD(pTempSrcCurrBuf,
					  16,
					  pSrcRefBuf,
					  srcRefStep,
					  &Sad,
					  16,
					  16);
	*pDstSAD = Sad;

    /* Mode decision for NOT_CODED MB */
	if(*pDstSAD == 0)
	{
        pSrcDstMBCurr->pMV0[0][0].dx = 0;
        pSrcDstMBCurr->pMV0[0][0].dy = 0;
        *pDstSAD   = 0;
		return OMX_Sts_NoErr;
	}

    omxVCM4P2_FindMVpred(
                    &(pSrcDstMBCurr->pMV0[0][0]),
                    pSrcCandMV1[0],
                    pSrcCandMV2[0],
                    pSrcCandMV3[0],
                    &(pSrcDstMBCurr->pMVPred[0][0]),
                    NULL,
                    0);
                    
    /* Inter 1 MV */
    armVCM4P2_BlockMatch_16x16(
        pSrcRefBuf,
        srcRefStep,
        pRefRect,
        pTempSrcCurrBuf,
        pCurrPointPos,
        &(pSrcDstMBCurr->pMVPred[0][0]),
        NULL,
        pMEParams,
        &dstMV16x16,
        &dstSAD16x16);
    
    /* Initialize all with 1 MV values */
    pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx;
    pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy;
    pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx;
    pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy;
    pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx;
    pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy;
    pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx;
    pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy; 
    
    *pDstSAD   = dstSAD16x16;       
    
    if (pMEParams->searchEnable8x8)
    {
        /* Inter 4MV */
        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
                                      srcRefStep, pRefRect,
                                      pTempSrcCurrBuf, pTempCurrPointPos,
                                      &(pSrcDstMBCurr->pMVPred[0][0]), NULL,
                                      pMEParams, &(pSrcDstMBCurr->pMV0[0][0]),
                                      &dstSAD8x8
                                      );
        pDstBlockSAD[0] = dstSAD8x8;
        *pDstSAD = dstSAD8x8;
        pTempCurrPointPos->x += 8;
        pSrcRefBuf += 8;
        omxVCM4P2_FindMVpred(
                    &(pSrcDstMBCurr->pMV0[0][1]),
                    pSrcCandMV1[1],
                    pSrcCandMV2[1],
                    pSrcCandMV3[1],
                    &(pSrcDstMBCurr->pMVPred[0][1]),
                    NULL,
                    1);
        
        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
                                      srcRefStep, pRefRect,
                                      pTempSrcCurrBuf, pTempCurrPointPos,
                                      &(pSrcDstMBCurr->pMVPred[0][1]), NULL,
                                      pMEParams, &(pSrcDstMBCurr->pMV0[0][1]),
                                      &dstSAD8x8
                                      );
        pDstBlockSAD[1] = dstSAD8x8;
        *pDstSAD += dstSAD8x8;
        pTempCurrPointPos->x -= 8;
        pTempCurrPointPos->y += 8;
        pSrcRefBuf += (srcRefStep * 8) - 8;
        
        omxVCM4P2_FindMVpred(
                    &(pSrcDstMBCurr->pMV0[1][0]),
                    pSrcCandMV1[2],
                    pSrcCandMV2[2],
                    pSrcCandMV3[2],
                    &(pSrcDstMBCurr->pMVPred[1][0]),
                    NULL,
                    2);
        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
                                      srcRefStep, pRefRect,
                                      pTempSrcCurrBuf, pTempCurrPointPos,
                                      &(pSrcDstMBCurr->pMVPred[1][0]), NULL,
                                      pMEParams, &(pSrcDstMBCurr->pMV0[1][0]),
                                      &dstSAD8x8
                                      );
        pDstBlockSAD[2] = dstSAD8x8;
        *pDstSAD += dstSAD8x8;
        pTempCurrPointPos->x += 8;
        pSrcRefBuf += 8;
        omxVCM4P2_FindMVpred(
                    &(pSrcDstMBCurr->pMV0[1][1]),
                    pSrcCandMV1[3],
                    pSrcCandMV2[3],
                    pSrcCandMV3[3],
                    &(pSrcDstMBCurr->pMVPred[1][1]),
                    NULL,
                    3);
        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
                                      srcRefStep, pRefRect,
                                      pTempSrcCurrBuf, pTempCurrPointPos,
                                      &(pSrcDstMBCurr->pMVPred[1][1]), NULL,
                                      pMEParams, &(pSrcDstMBCurr->pMV0[1][1]),
                                      &dstSAD8x8
                                      );
        pDstBlockSAD[3] = dstSAD8x8;
        *pDstSAD += dstSAD8x8;   
        
        
        /* Checking if 4MV is equal to 1MV */
        if (
            (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) ||
            (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) ||
            (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) ||
            (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) ||
            (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) ||
            (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) ||
            (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) ||
            (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy)
           )
        {
            /* select the 4 MV */
            pSrcDstMBCurr->mbType = OMX_VC_INTER4V;
        }                                      
    }
                                         
    /* finding the error in intra mode */
    for (count = 0, average = 0; count < 256 ; count++)
    {
        average = average + pTempSrcCurrBuf[count];
    }
    average = average/256;
    
	intraSAD = 0;

    /* Intra SAD calculation */
    for (count = 0; count < 256 ; count++)
    {
        intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average));
    }
    
	/* Using the MPEG4 VM formula for intra/inter mode decision 
	   Var < (SAD - 2*NB) where NB = N^2 is the number of pixels
	   of the macroblock.*/

    if (intraSAD <= (*pDstSAD - 512))
    {
        pSrcDstMBCurr->mbType = OMX_VC_INTRA;
        pSrcDstMBCurr->pMV0[0][0].dx = 0;
        pSrcDstMBCurr->pMV0[0][0].dy = 0;
        *pDstSAD   = intraSAD;
        pDstBlockSAD[0] = 0xFFFF;
        pDstBlockSAD[1] = 0xFFFF;
        pDstBlockSAD[2] = 0xFFFF;
        pDstBlockSAD[3] = 0xFFFF;
    }

    if(pSrcDstMBCurr->mbType == OMX_VC_INTER)
    {
      pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx;
    
      if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1))
      {
        predictType = OMX_VC_HALF_PIXEL_XY;
      }
      else if(dstMV16x16.dx & 0x1)
      {
        predictType = OMX_VC_HALF_PIXEL_X;
      }
      else if(dstMV16x16.dy & 0x1)
      {
        predictType = OMX_VC_HALF_PIXEL_Y;
      }
      else
      {
        predictType = OMX_VC_INTEGER_PIXEL;
      }
      
      pDst = armAlignTo8Bytes(&(aDst[0]));
      /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */
	  /* Block 0 */
      omxVCM4P2_MCReconBlock(pTempSrcRefBuf,
	                             srcRefStep,
                                 NULL,
                                 pDst, 
                                 dstStep,
                                 predictType,
                                 pMEParams->rndVal);
    
      armVCCOMM_SAD(pTempSrcCurrBuf,
                        16,
                        pDst,
                        dstStep,
                        &Sad,
                        8,
                        8);
      pDstBlockSAD[0] = Sad;
   
      /* Block 1 */
      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8,
                                 srcRefStep,
                                 NULL,
                                 pDst, 
                                 dstStep,
                                 predictType,
                                 pMEParams->rndVal);					  

      armVCCOMM_SAD(pTempSrcCurrBuf + 8,
                        16,
                        pDst,
                        dstStep,
                        &Sad,
                        8,
                        8);
      pDstBlockSAD[1] = Sad;
	
      /* Block 2 */
      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8),
                                 srcRefStep,
                                 NULL,
                                 pDst, 
                                 dstStep,
                                 predictType,
                                 pMEParams->rndVal);

      armVCCOMM_SAD(pTempSrcCurrBuf + (16*8),
                        16,
                        pDst,
                        dstStep,
                        &Sad,
                        8,
                        8);
      pDstBlockSAD[2] = Sad;

	  /* Block 3 */
      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8,
                                 srcRefStep,
                                 NULL,
                                 pDst, 
                                 dstStep,
                                 predictType,
                                 pMEParams->rndVal);

      armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8,
                        16,
                        pDst,
                        dstStep,
                        &Sad,
                        8,
                        8);
      pDstBlockSAD[3] = Sad;
    }
    return OMX_Sts_NoErr;
}
OMXResult armVCM4P2_BlockMatch_Integer(
     const OMX_U8 *pSrcRefBuf,
     OMX_INT refWidth,
     const OMXRect *pRefRect,
     const OMX_U8 *pSrcCurrBuf,
     const OMXVCM4P2Coordinate *pCurrPointPos,
     const OMXVCMotionVector *pSrcPreMV,
     const OMX_INT *pSrcPreSAD,
     void *pMESpec,
     OMXVCMotionVector *pDstMV,
     OMX_INT *pDstSAD,
     OMX_U8 BlockSize
)
{

    /* Definitions and Initializations*/

    OMX_INT     outer, inner, count,index;
    OMX_INT     candSAD;
    /*(256*256 +1) this is to make the SAD max initially*/
    OMX_INT     minSAD = 0x10001, fromX, toX, fromY, toY;
    /* Offset to the reference at the begining of the bounding box */
    const OMX_U8      *pTempSrcRefBuf;
    OMX_S16     x, y;
    OMX_INT searchRange;
   
    /* Argument error checks */
    armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
        
    searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange;
    /* Check for valid region */
    fromX = searchRange;
    toX   = searchRange;
    fromY = searchRange;
    toY   = searchRange;

    if ((pCurrPointPos->x - searchRange) < pRefRect->x)
    {
        fromX =  pCurrPointPos->x - pRefRect->x;
    }

    if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width))
    {
        toX   = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize;
    }

    if ((pCurrPointPos->y - searchRange) < pRefRect->y)
    {
        fromY = pCurrPointPos->y - pRefRect->y;
    }

    if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height))
    {
        toY   = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize;
    }

    pDstMV->dx = -fromX;
    pDstMV->dy = -fromY;
    /* Looping on y- axis */
    for (y = -fromY; y <= toY; y++)
    {

        /* Looping on x- axis */
        for (x = -fromX; x <= toX; x++)
        {
            /* Positioning the pointer */
            pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x;

            /* Calculate the SAD */
            for (outer = 0, count = 0, index = 0, candSAD = 0;
                 outer < BlockSize;
                 outer++, index += refWidth - BlockSize)
            {
                for (inner = 0; inner < BlockSize; inner++, count++, index++)
                {
                    candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);                    
                }
            }

            /* Result calculations */
            if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD))
            {
                *pDstSAD = candSAD;
                minSAD   = candSAD;
                pDstMV->dx = x*2;
                pDstMV->dy = y*2;
            }

        } /* End of x- axis */
    } /* End of y-axis */

    return OMX_Sts_NoErr;

}
OMXResult omxVCM4P2_EncodeMV(
     OMX_U8 **ppBitStream,
     OMX_INT *pBitOffset,
     const OMXVCMotionVector * pMVCurMB,
     const OMXVCMotionVector * pSrcMVLeftMB,
     const OMXVCMotionVector * pSrcMVUpperMB,
     const OMXVCMotionVector * pSrcMVUpperRightMB,
     OMX_INT fcodeForward,
     OMXVCM4P2MacroblockType MBType
)
{
    OMXVCMotionVector dstMVPred, diffMV;
    OMXVCMotionVector dstMVPredME[12];
    /* Initialized to remove compilation warning */
    OMX_INT iBlk, i, count = 1;
    OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData;
    OMX_U8 scaleFactor, index;

    /* Argument error checks */
    armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr);
    armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
    armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \
                    OMX_Sts_BadArgErr);
    
    if ((MBType == OMX_VC_INTRA) ||
        (MBType == OMX_VC_INTRA_Q)
       )
    {
        /* No candidate vectors hence make them zero */
        for (i = 0; i < 12; i++)
        {
            dstMVPredME[i].dx = 0;
            dstMVPredME[i].dy = 0;
        }

        return OMX_Sts_NoErr;
    }

    if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q))
    {
        count = 4;
    }
    else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
    {
        count = 1;
    }

    /* Calculating the scale factor */
    scaleFactor = 1 << (fcodeForward -1);

    for (iBlk = 0; iBlk < count; iBlk++)
    {

        /* Find the predicted vector */
        omxVCM4P2_FindMVpred (
            pMVCurMB,
            pSrcMVLeftMB,
            pSrcMVUpperMB,
            pSrcMVUpperRightMB,
            &dstMVPred,
            dstMVPredME,
            iBlk );

        /* Calculating the differential motion vector (diffMV) */
        diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx;
        diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy;

        /* Calculating the mv_data and mv_residual for Horizantal MV */
        if (diffMV.dx == 0)
        {
            mvHorResidual = 0;
            mvHorData = 0;
        }
        else
        {
            mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor;
            mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1))
                     / scaleFactor;
            if (diffMV.dx < 0)
            {
                mvHorData = -mvHorData;
            }
        }

        /* Calculating the mv_data and mv_residual for Vertical MV */
        if (diffMV.dy == 0)
        {
            mvVerResidual = 0;
            mvVerData = 0;
        }
        else
        {
            mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor;
            mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1))
                     / scaleFactor;
            if (diffMV.dy < 0)
            {
                mvVerData = -mvVerData;
            }
        }

        /* Huffman encoding */

        /* The index is actually calculate as
           index = ((float) (mvHorData/2) + 16) * 2,
           meaning the MV data is halfed and then normalized
           to begin with zero and then doubled to take care of indexing
           the fractional part included */
        index = mvHorData + 32;
        armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
        if ((fcodeForward > 1) && (diffMV.dx != 0))
        {
            armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1));
        }

        /* The index is actually calculate as
           index = ((float) (mvVerData/2) + 16) * 2,
           meaning the MV data is halfed and then normalized
           to begin with zero and then doubled to take care of indexing
           the fractional part included */
        index = mvVerData + 32;
        armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
        if ((fcodeForward > 1) && (diffMV.dy != 0))
        {
            armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1));
        }
    }

    return OMX_Sts_NoErr;
}
OMX_U8 armVCM4P2_CheckVLCEscapeMode(
     OMX_U32 run,
     OMX_U32 runPlus,
     OMX_S16 level,
     OMX_S16 levelPlus,
     OMX_U8  maxStoreRun,
     OMX_U8  maxRunForMultipleEntries,
     OMX_INT shortVideoHeader,
     const OMX_U8  *pRunIndexTable
)
{
    OMX_U8 escape = 0, fMode = 0, entries;
    
    level = armAbs (level);
    levelPlus = armAbs (levelPlus);
    
    /* Check for a valid entry with run, level and Last combination 
       Mode 0 check */
    if (run <= maxStoreRun)
    {
        entries = pRunIndexTable[run + 1]
                  - pRunIndexTable[run];
        if (run > maxRunForMultipleEntries)
        {
            entries = 1;
        }
        if (level > entries)
        {
            escape = 1;
        }
    }
    else
    {
        escape = 1;
    }
    if(escape && shortVideoHeader)
    {
        escape = 0;
        fMode = 4;
    }
    /* Check for a valid entry with run, levelPlus and Last combination 
       Mode 1 check */    
    if (escape)
    {
        escape = 0;
        fMode = 1;
        if (run <= maxStoreRun)
        {
            entries = pRunIndexTable[run + 1]
                      - pRunIndexTable[run];
            if (run > maxRunForMultipleEntries)
            {
                entries = 1;
            }
            if (levelPlus > entries)
            {
                escape = 1;
            }
        }
        else
        {
            escape = 1;
        }
    }
    
    /* Check for a valid entry with runPlus, level and Last combination 
       Mode 2 check */    
    if (escape)
    {
        escape = 0;
        fMode = 2;
        if (runPlus <= maxStoreRun)
        {
            entries = pRunIndexTable[runPlus + 1]
                      - pRunIndexTable[runPlus];
            if (runPlus > maxRunForMultipleEntries)
            {
                entries = 1;
            }
            if (level > entries)
            {
                escape = 1;
            }
        }
        else
        {
            escape = 1;
        }
    }
    
    /* select mode 3 --> FLC */
    if (escape)
    {
        fMode = 3;
    }
    
    return fMode;
}
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 armVCM4P2_FillVLCBuffer (
              OMX_U8 **ppBitStream,
              OMX_INT * pBitOffset,
              OMX_U32 run,
              OMX_S16 level, 
			  OMX_U32 runPlus,
              OMX_S16 levelPlus, 
              OMX_U8  fMode,
			  OMX_U8  last,
              OMX_U8  maxRunForMultipleEntries, 
              const OMX_U8  *pRunIndexTable,
              const ARM_VLC32 *pVlcTable
)
{
    OMX_INT tempIndex;
	OMX_U32 tempRun = run, sign = 0;
    OMX_S16 tempLevel = level; 
    
    /* Escape sequence addition */
    if (fMode == 1)
    {
        armPackBits(ppBitStream, pBitOffset, 3, 7);
        armPackBits(ppBitStream, pBitOffset, 0, 1);
		tempLevel = levelPlus;

    }
    else if(fMode == 2)
    {
        armPackBits(ppBitStream, pBitOffset, 3, 7);
        armPackBits(ppBitStream, pBitOffset, 2, 2);
		tempRun = runPlus;
    }
    else if (fMode == 3)
    {
        armPackBits(ppBitStream, pBitOffset, 3, 7);
        armPackBits(ppBitStream, pBitOffset, 3, 2);
    }
    else if (fMode == 4)
    {
        armPackBits(ppBitStream, pBitOffset, 3, 7);
        armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1);
		armPackBits(ppBitStream, pBitOffset, tempRun, 6);
		if((tempLevel != 0) && (tempLevel != -128))
		{
		    armPackBits(ppBitStream, pBitOffset,
			   (OMX_U32) tempLevel, 8);
		}
		return OMX_Sts_NoErr;		
    }
    
    if (tempLevel < 0)
    {
        sign = 1;
        tempLevel = armAbs(tempLevel);
    }
    /* Putting VLC bits in the stream */
	if (fMode < 3)
	{
		if (tempRun > maxRunForMultipleEntries)
		{
			tempIndex = pRunIndexTable [maxRunForMultipleEntries + 1] + 
						(tempRun - maxRunForMultipleEntries - 1);
		}
		else
		{
			tempIndex = pRunIndexTable [tempRun] + (tempLevel -1);
		}
    
		armPackVLC32 (ppBitStream, pBitOffset,
					  pVlcTable [tempIndex]);
		armPackBits(ppBitStream, pBitOffset, (OMX_U32)sign, 1);
	}
    else
	{
		if (sign)
		{
			tempLevel = -tempLevel;
		}
		tempRun  = run;
		armPackBits(ppBitStream, pBitOffset, (OMX_U32)last, 1);
		armPackBits(ppBitStream, pBitOffset, tempRun, 6);
		armPackBits(ppBitStream, pBitOffset, 1, 1);
		armPackBits(ppBitStream, pBitOffset,
			   (OMX_U32) tempLevel, 12);
		armPackBits(ppBitStream, pBitOffset, 1, 1);
	}
    return OMX_Sts_NoErr;
}
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;

}