1/** 2 * 3 * File Name: omxVCM4P2_EncodeMV.c 4 * OpenMAX DL: v1.0.2 5 * Revision: 9641 6 * Date: Thursday, February 7, 2008 7 * 8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 9 * 10 * 11 * 12 * Description: 13 * Contains module for predicting MV of MB 14 * 15 */ 16 17#include "omxtypes.h" 18#include "armOMX.h" 19#include "omxVC.h" 20 21#include "armCOMM.h" 22#include "armCOMM_Bitstream.h" 23#include "armVCM4P2_Huff_Tables_VLC.h" 24 25 26 27/** 28 * Function: omxVCM4P2_EncodeMV (6.2.4.5.4) 29 * 30 * Description: 31 * Predicts a motion vector for the current macroblock, encodes the 32 * difference, and writes the output to the stream buffer. The input MVs 33 * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie 34 * within the ranges associated with the input parameter fcodeForward, as 35 * described in [ISO14496-2], subclause 7.6.3. This function provides a 36 * superset of the functionality associated with the function 37 * omxVCM4P2_FindMVpred. 38 * 39 * Input Arguments: 40 * 41 * ppBitStream - double pointer to the current byte in the bitstream buffer 42 * pBitOffset - index of the first free (next available) bit in the stream 43 * buffer referenced by *ppBitStream, valid in the range 0 to 7. 44 * pMVCurMB - pointer to the current macroblock motion vector; a value of 45 * NULL indicates unavailability. 46 * pSrcMVLeftMB - pointer to the source left macroblock motion vector; a 47 * value of NULLindicates unavailability. 48 * pSrcMVUpperMB - pointer to source upper macroblock motion vector; a 49 * value of NULL indicates unavailability. 50 * pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a 51 * value of NULL indicates unavailability. 52 * fcodeForward - an integer with values from 1 to 7; used in encoding 53 * motion vectors related to search range, as described in 54 * [ISO14496-2], subclause 7.6.3. 55 * MBType - macro block type, valid in the range 0 to 5 56 * 57 * Output Arguments: 58 * 59 * ppBitStream - updated pointer to the current byte in the bit stream 60 * buffer 61 * pBitOffset - updated index of the next available bit position in stream 62 * buffer referenced by *ppBitStream 63 * 64 * Return Value: 65 * 66 * OMX_Sts_NoErr - no error 67 * OMX_Sts_BadArgErr - bad arguments 68 * - At least one of the following pointers is NULL: ppBitStream, 69 * *ppBitStream, pBitOffset, pMVCurMB 70 * - *pBitOffset < 0, or *pBitOffset >7. 71 * - fcodeForward <= 0, or fcodeForward > 7, or MBType < 0. 72 * 73 */ 74 75OMXResult omxVCM4P2_EncodeMV( 76 OMX_U8 **ppBitStream, 77 OMX_INT *pBitOffset, 78 const OMXVCMotionVector * pMVCurMB, 79 const OMXVCMotionVector * pSrcMVLeftMB, 80 const OMXVCMotionVector * pSrcMVUpperMB, 81 const OMXVCMotionVector * pSrcMVUpperRightMB, 82 OMX_INT fcodeForward, 83 OMXVCM4P2MacroblockType MBType 84) 85{ 86 OMXVCMotionVector dstMVPred, diffMV; 87 OMXVCMotionVector dstMVPredME[12]; 88 /* Initialized to remove compilation warning */ 89 OMX_INT iBlk, i, count = 1; 90 OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData; 91 OMX_U8 scaleFactor, index; 92 93 /* Argument error checks */ 94 armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr); 95 armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr); 96 armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr); 97 armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr); 98 armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr); 99 armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \ 100 OMX_Sts_BadArgErr); 101 102 if ((MBType == OMX_VC_INTRA) || 103 (MBType == OMX_VC_INTRA_Q) 104 ) 105 { 106 /* No candidate vectors hence make them zero */ 107 for (i = 0; i < 12; i++) 108 { 109 dstMVPredME[i].dx = 0; 110 dstMVPredME[i].dy = 0; 111 } 112 113 return OMX_Sts_NoErr; 114 } 115 116 if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q)) 117 { 118 count = 4; 119 } 120 else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q)) 121 { 122 count = 1; 123 } 124 125 /* Calculating the scale factor */ 126 scaleFactor = 1 << (fcodeForward -1); 127 128 for (iBlk = 0; iBlk < count; iBlk++) 129 { 130 131 /* Find the predicted vector */ 132 omxVCM4P2_FindMVpred ( 133 pMVCurMB, 134 pSrcMVLeftMB, 135 pSrcMVUpperMB, 136 pSrcMVUpperRightMB, 137 &dstMVPred, 138 dstMVPredME, 139 iBlk ); 140 141 /* Calculating the differential motion vector (diffMV) */ 142 diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx; 143 diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy; 144 145 /* Calculating the mv_data and mv_residual for Horizantal MV */ 146 if (diffMV.dx == 0) 147 { 148 mvHorResidual = 0; 149 mvHorData = 0; 150 } 151 else 152 { 153 mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor; 154 mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1)) 155 / scaleFactor; 156 if (diffMV.dx < 0) 157 { 158 mvHorData = -mvHorData; 159 } 160 } 161 162 /* Calculating the mv_data and mv_residual for Vertical MV */ 163 if (diffMV.dy == 0) 164 { 165 mvVerResidual = 0; 166 mvVerData = 0; 167 } 168 else 169 { 170 mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor; 171 mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1)) 172 / scaleFactor; 173 if (diffMV.dy < 0) 174 { 175 mvVerData = -mvVerData; 176 } 177 } 178 179 /* Huffman encoding */ 180 181 /* The index is actually calculate as 182 index = ((float) (mvHorData/2) + 16) * 2, 183 meaning the MV data is halfed and then normalized 184 to begin with zero and then doubled to take care of indexing 185 the fractional part included */ 186 index = mvHorData + 32; 187 armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 188 if ((fcodeForward > 1) && (diffMV.dx != 0)) 189 { 190 armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1)); 191 } 192 193 /* The index is actually calculate as 194 index = ((float) (mvVerData/2) + 16) * 2, 195 meaning the MV data is halfed and then normalized 196 to begin with zero and then doubled to take care of indexing 197 the fractional part included */ 198 index = mvVerData + 32; 199 armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]); 200 if ((fcodeForward > 1) && (diffMV.dy != 0)) 201 { 202 armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1)); 203 } 204 } 205 206 return OMX_Sts_NoErr; 207} 208 209 210/* End of file */ 211 212 213