omxVCM4P2_EncodeMV.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
10c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 20c1bc742181ded4930842b46e9507372f0b1b963James Dong * 30c1bc742181ded4930842b46e9507372f0b1b963James Dong * File Name: omxVCM4P2_EncodeMV.c 40c1bc742181ded4930842b46e9507372f0b1b963James Dong * OpenMAX DL: v1.0.2 50c1bc742181ded4930842b46e9507372f0b1b963James Dong * Revision: 9641 60c1bc742181ded4930842b46e9507372f0b1b963James Dong * Date: Thursday, February 7, 2008 70c1bc742181ded4930842b46e9507372f0b1b963James Dong * 80c1bc742181ded4930842b46e9507372f0b1b963James Dong * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 90c1bc742181ded4930842b46e9507372f0b1b963James Dong * 100c1bc742181ded4930842b46e9507372f0b1b963James Dong * 110c1bc742181ded4930842b46e9507372f0b1b963James Dong * 120c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 130c1bc742181ded4930842b46e9507372f0b1b963James Dong * Contains module for predicting MV of MB 140c1bc742181ded4930842b46e9507372f0b1b963James Dong * 150c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 160c1bc742181ded4930842b46e9507372f0b1b963James Dong 170c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxtypes.h" 180c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armOMX.h" 190c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxVC.h" 200c1bc742181ded4930842b46e9507372f0b1b963James Dong 210c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM.h" 220c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM_Bitstream.h" 230c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVCM4P2_Huff_Tables_VLC.h" 240c1bc742181ded4930842b46e9507372f0b1b963James Dong 250c1bc742181ded4930842b46e9507372f0b1b963James Dong 260c1bc742181ded4930842b46e9507372f0b1b963James Dong 270c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: omxVCM4P2_EncodeMV (6.2.4.5.4) 290c1bc742181ded4930842b46e9507372f0b1b963James Dong * 300c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 310c1bc742181ded4930842b46e9507372f0b1b963James Dong * Predicts a motion vector for the current macroblock, encodes the 320c1bc742181ded4930842b46e9507372f0b1b963James Dong * difference, and writes the output to the stream buffer. The input MVs 330c1bc742181ded4930842b46e9507372f0b1b963James Dong * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie 340c1bc742181ded4930842b46e9507372f0b1b963James Dong * within the ranges associated with the input parameter fcodeForward, as 350c1bc742181ded4930842b46e9507372f0b1b963James Dong * described in [ISO14496-2], subclause 7.6.3. This function provides a 360c1bc742181ded4930842b46e9507372f0b1b963James Dong * superset of the functionality associated with the function 370c1bc742181ded4930842b46e9507372f0b1b963James Dong * omxVCM4P2_FindMVpred. 380c1bc742181ded4930842b46e9507372f0b1b963James Dong * 390c1bc742181ded4930842b46e9507372f0b1b963James Dong * Input Arguments: 400c1bc742181ded4930842b46e9507372f0b1b963James Dong * 410c1bc742181ded4930842b46e9507372f0b1b963James Dong * ppBitStream - double pointer to the current byte in the bitstream buffer 420c1bc742181ded4930842b46e9507372f0b1b963James Dong * pBitOffset - index of the first free (next available) bit in the stream 430c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer referenced by *ppBitStream, valid in the range 0 to 7. 440c1bc742181ded4930842b46e9507372f0b1b963James Dong * pMVCurMB - pointer to the current macroblock motion vector; a value of 450c1bc742181ded4930842b46e9507372f0b1b963James Dong * NULL indicates unavailability. 460c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a 470c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULLindicates unavailability. 480c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a 490c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULL indicates unavailability. 500c1bc742181ded4930842b46e9507372f0b1b963James Dong * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a 510c1bc742181ded4930842b46e9507372f0b1b963James Dong * value of NULL indicates unavailability. 520c1bc742181ded4930842b46e9507372f0b1b963James Dong * fcodeForward - an integer with values from 1 to 7; used in encoding 530c1bc742181ded4930842b46e9507372f0b1b963James Dong * motion vectors related to search range, as described in 540c1bc742181ded4930842b46e9507372f0b1b963James Dong * [ISO14496-2], subclause 7.6.3. 550c1bc742181ded4930842b46e9507372f0b1b963James Dong * MBType - macro block type, valid in the range 0 to 5 560c1bc742181ded4930842b46e9507372f0b1b963James Dong * 570c1bc742181ded4930842b46e9507372f0b1b963James Dong * Output Arguments: 580c1bc742181ded4930842b46e9507372f0b1b963James Dong * 590c1bc742181ded4930842b46e9507372f0b1b963James Dong * ppBitStream - updated pointer to the current byte in the bit stream 600c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer 610c1bc742181ded4930842b46e9507372f0b1b963James Dong * pBitOffset - updated index of the next available bit position in stream 620c1bc742181ded4930842b46e9507372f0b1b963James Dong * buffer referenced by *ppBitStream 630c1bc742181ded4930842b46e9507372f0b1b963James Dong * 640c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value: 650c1bc742181ded4930842b46e9507372f0b1b963James Dong * 660c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr - no error 670c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr - bad arguments 680c1bc742181ded4930842b46e9507372f0b1b963James Dong * - At least one of the following pointers is NULL: ppBitStream, 690c1bc742181ded4930842b46e9507372f0b1b963James Dong * *ppBitStream, pBitOffset, pMVCurMB 700c1bc742181ded4930842b46e9507372f0b1b963James Dong * - *pBitOffset < 0, or *pBitOffset >7. 710c1bc742181ded4930842b46e9507372f0b1b963James Dong * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0. 720c1bc742181ded4930842b46e9507372f0b1b963James Dong * 730c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 740c1bc742181ded4930842b46e9507372f0b1b963James Dong 750c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P2_EncodeMV( 760c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 **ppBitStream, 770c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT *pBitOffset, 780c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pMVCurMB, 790c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVLeftMB, 800c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVUpperMB, 810c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector * pSrcMVUpperRightMB, 820c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT fcodeForward, 830c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCM4P2MacroblockType MBType 840c1bc742181ded4930842b46e9507372f0b1b963James Dong) 850c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 860c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector dstMVPred, diffMV; 870c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector dstMVPredME[12]; 880c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Initialized to remove compilation warning */ 890c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT iBlk, i, count = 1; 900c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData; 910c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 scaleFactor, index; 920c1bc742181ded4930842b46e9507372f0b1b963James Dong 930c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Argument error checks */ 940c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); 950c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); 960c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); 970c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr); 980c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr); 990c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \ 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_Sts_BadArgErr); 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((MBType == OMX_VC_INTRA) || 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong (MBType == OMX_VC_INTRA_Q) 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong ) 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong /* No candidate vectors hence make them zero */ 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong for (i = 0; i < 12; i++) 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME[i].dx = 0; 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME[i].dy = 0; 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q)) 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong count = 4; 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q)) 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong count = 1; 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the scale factor */ 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong scaleFactor = 1 << (fcodeForward -1); 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong for (iBlk = 0; iBlk < count; iBlk++) 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Find the predicted vector */ 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong omxVCM4P2_FindMVpred ( 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong pMVCurMB, 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVLeftMB, 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVUpperMB, 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcMVUpperRightMB, 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong &dstMVPred, 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong dstMVPredME, 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong iBlk ); 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the differential motion vector (diffMV) */ 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx; 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy; 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the mv_data and mv_residual for Horizantal MV */ 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dx == 0) 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorResidual = 0; 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = 0; 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong else 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor; 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1)) 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong / scaleFactor; 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dx < 0) 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong mvHorData = -mvHorData; 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong 1620c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculating the mv_data and mv_residual for Vertical MV */ 1630c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dy == 0) 1640c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerResidual = 0; 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = 0; 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1680c1bc742181ded4930842b46e9507372f0b1b963James Dong else 1690c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1700c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor; 1710c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1)) 1720c1bc742181ded4930842b46e9507372f0b1b963James Dong / scaleFactor; 1730c1bc742181ded4930842b46e9507372f0b1b963James Dong if (diffMV.dy < 0) 1740c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1750c1bc742181ded4930842b46e9507372f0b1b963James Dong mvVerData = -mvVerData; 1760c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1770c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1780c1bc742181ded4930842b46e9507372f0b1b963James Dong 1790c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Huffman encoding */ 1800c1bc742181ded4930842b46e9507372f0b1b963James Dong 1810c1bc742181ded4930842b46e9507372f0b1b963James Dong /* The index is actually calculate as 1820c1bc742181ded4930842b46e9507372f0b1b963James Dong index = ((float) (mvHorData/2) + 16) * 2, 1830c1bc742181ded4930842b46e9507372f0b1b963James Dong meaning the MV data is halfed and then normalized 1840c1bc742181ded4930842b46e9507372f0b1b963James Dong to begin with zero and then doubled to take care of indexing 1850c1bc742181ded4930842b46e9507372f0b1b963James Dong the fractional part included */ 1860c1bc742181ded4930842b46e9507372f0b1b963James Dong index = mvHorData + 32; 1870c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 1880c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((fcodeForward > 1) && (diffMV.dx != 0)) 1890c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1900c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1)); 1910c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1920c1bc742181ded4930842b46e9507372f0b1b963James Dong 1930c1bc742181ded4930842b46e9507372f0b1b963James Dong /* The index is actually calculate as 1940c1bc742181ded4930842b46e9507372f0b1b963James Dong index = ((float) (mvVerData/2) + 16) * 2, 1950c1bc742181ded4930842b46e9507372f0b1b963James Dong meaning the MV data is halfed and then normalized 1960c1bc742181ded4930842b46e9507372f0b1b963James Dong to begin with zero and then doubled to take care of indexing 1970c1bc742181ded4930842b46e9507372f0b1b963James Dong the fractional part included */ 1980c1bc742181ded4930842b46e9507372f0b1b963James Dong index = mvVerData + 32; 1990c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 2000c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((fcodeForward > 1) && (diffMV.dy != 0)) 2010c1bc742181ded4930842b46e9507372f0b1b963James Dong { 2020c1bc742181ded4930842b46e9507372f0b1b963James Dong armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1)); 2030c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2040c1bc742181ded4930842b46e9507372f0b1b963James Dong } 2050c1bc742181ded4930842b46e9507372f0b1b963James Dong 2060c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 2070c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2080c1bc742181ded4930842b46e9507372f0b1b963James Dong 2090c1bc742181ded4930842b46e9507372f0b1b963James Dong 2100c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */ 2110c1bc742181ded4930842b46e9507372f0b1b963James Dong 2120c1bc742181ded4930842b46e9507372f0b1b963James Dong 213