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