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;
}
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;
}