1 /** 2 * 3 * File Name: omxVCM4P2_MCReconBlock.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 * Description: 12 * MPEG4 motion compensation prediction for an 8x8 block using 13 * interpolation 14 * 15 */ 16 17 #include "omxtypes.h" 18 #include "armOMX.h" 19 #include "omxVC.h" 20 21 #include "armCOMM.h" 22 23 /** 24 * Function: armVCM4P2_HalfPelVer 25 * 26 * Description: 27 * Performs half pel motion compensation for an 8x8 block using vertical 28 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2. 29 * 30 * Remarks: 31 * 32 * Parameters: 33 * [in] pSrc pointer to the block in the reference plane. 34 * [in] srcStep distance between the start of consecutive lines 35 * in the reference plane, in bytes; must be a multiple 36 * of 8. 37 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 38 * [out] pDst pointer to the linaer 8x8 destination buffer; 39 * 40 */ 41 static OMXVoid armVCM4P2_HalfPelVer( 42 const OMX_U8 *pSrc, 43 OMX_INT srcStep, 44 OMX_U8 *pDst, 45 OMX_INT rndVal) 46 { 47 const OMX_U8 *pTempSrc1; 48 const OMX_U8 *pTempSrc2; 49 OMX_INT y, x; 50 51 pTempSrc1 = pSrc; 52 pTempSrc2 = pSrc + srcStep; 53 srcStep -= 8; 54 for (y = 0; y < 8; y++) 55 { 56 for (x = 0; x < 8; x++) 57 { 58 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1; 59 } 60 pTempSrc1 += srcStep; 61 pTempSrc2 += srcStep; 62 } 63 } 64 65 /** 66 * Function: armVCM4P2_HalfPelHor 67 * 68 * Description: 69 * Performs half pel motion compensation for an 8x8 block using horizontal 70 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2. 71 * 72 * Remarks: 73 * 74 * Parameters: 75 * [in] pSrc pointer to the block in the reference plane. 76 * [in] srcStep distance between the start of consecutive lines 77 * in the reference plane, in bytes; must be a multiple 78 * of 8. 79 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 80 * [out] pDst pointer to the linaer 8x8 destination buffer; 81 * 82 */ 83 static OMXVoid armVCM4P2_HalfPelHor( 84 const OMX_U8 *pSrc, 85 OMX_INT srcStep, 86 OMX_U8 *pDst, 87 OMX_INT rndVal) 88 { 89 const OMX_U8 *pTempSrc1; 90 const OMX_U8 *pTempSrc2; 91 OMX_INT y, x; 92 93 pTempSrc1 = pSrc; 94 pTempSrc2 = pTempSrc1 + 1; 95 96 srcStep -= 8; 97 for (y=0; y<8; y++) 98 { 99 for (x=0; x<8; x++) 100 { 101 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1; 102 } 103 pTempSrc1 += srcStep; 104 pTempSrc2 += srcStep; 105 } 106 } 107 108 109 /** 110 * Function: armVCM4P2_HalfPelVerHor 111 * 112 * Description: 113 * Performs half pel motion compensation for an 8x8 block using both 114 * horizontal and vertical interpolation described in ISO/IEC 14496-2, 115 * subclause 7.6.2. 116 * 117 * Remarks: 118 * 119 * Parameters: 120 * [in] pSrc pointer to the block in the reference plane. 121 * [in] srcStep distance between the start of consecutive lines 122 * in the reference plane, in bytes; must be a multiple 123 * of 8. 124 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 125 * [out] pDst pointer to the linaer 8x8 destination buffer; 126 * 127 */ 128 static OMXVoid armVCM4P2_HalfPelVerHor( 129 const OMX_U8 *pSrc, 130 OMX_INT srcStep, 131 OMX_U8 *pDst, 132 OMX_INT rndVal) 133 { 134 const OMX_U8 *pTempSrc1; 135 const OMX_U8 *pTempSrc2; 136 const OMX_U8 *pTempSrc3; 137 const OMX_U8 *pTempSrc4; 138 OMX_INT y, x; 139 140 pTempSrc1 = pSrc; 141 pTempSrc2 = pSrc + srcStep; 142 pTempSrc3 = pSrc + 1; 143 pTempSrc4 = pSrc + srcStep + 1; 144 145 srcStep -= 8; 146 for (y=0; y<8; y++) 147 { 148 for (x=0; x<8; x++) 149 { 150 *pDst++ = ((*pTempSrc1++ + *pTempSrc2++ + *pTempSrc3++ + *pTempSrc4++) + 151 2 - rndVal) >> 2; 152 } 153 pTempSrc1 += srcStep; 154 pTempSrc2 += srcStep; 155 pTempSrc3 += srcStep; 156 pTempSrc4 += srcStep; 157 } 158 } 159 160 /** 161 * Function: armVCM4P2_MCReconBlock_NoRes 162 * 163 * Description: 164 * Do motion compensation and copy the result to the current block. 165 * 166 * Remarks: 167 * 168 * Parameters: 169 * [in] pSrc pointer to the block in the reference plane. 170 * [in] srcStep distance between the start of consecutive lines 171 * in the reference plane, in bytes; must be a multiple 172 * of 8. 173 * [in] dstStep distance between the start of consecutive lines in the 174 * destination plane, in bytes; must be a multiple of 8. 175 * [in] predictType bilinear interpolation type, as defined in section 6.2.1.2. 176 * [in] rndVal rounding control parameter: 0 - disabled; 1 - enabled. 177 * [out] pDst pointer to the destination buffer; must be 8-byte aligned. 178 * If prediction residuals are added then output intensities 179 * are clipped to the range [0,255]. 180 * 181 */ 182 static OMXVoid armVCM4P2_MCReconBlock_NoRes( 183 const OMX_U8 *pSrc, 184 OMX_INT srcStep, 185 OMX_U8 *pDst, 186 OMX_INT dstStep) 187 { 188 OMX_U8 x,y,count,index; 189 190 /* Copying the ref 8x8 blk to the curr blk */ 191 for (y = 0, count = 0, index = 0; y < 8; y++,index += (srcStep -8), count += (dstStep - 8)) 192 { 193 for (x = 0; x < 8; x++, count++,index++) 194 { 195 pDst[count] = pSrc[index]; 196 } 197 } 198 } 199 200 /** 201 * Function: armVCM4P2_MCReconBlock_Res 202 * 203 * Description: 204 * Reconstructs INTER block by summing the motion compensation results 205 * and the results of the inverse transformation (prediction residuals). 206 * Output intensities are clipped to the range [0,255]. 207 * 208 * Remarks: 209 * 210 * Parameters: 211 * [in] pSrc pointer to the block in the reference plane. 212 * [in] pSrcResidue pointer to a buffer containing the 16-bit prediction 213 * residuals. If the pointer is NULL,then no prediction 214 * is done, only motion compensation, i.e., the block is 215 * moved with interpolation. 216 * [in] dstStep distance between the start of consecutive lines in the 217 * destination plane, in bytes; must be a multiple of 8. 218 * [out] pDst pointer to the destination buffer; must be 8-byte aligned. 219 * If prediction residuals are added then output intensities 220 * are clipped to the range [0,255]. 221 * 222 */ 223 static OMXVoid armVCM4P2_MCReconBlock_Res( 224 const OMX_U8 *pSrc, 225 const OMX_S16 *pSrcResidue, 226 OMX_U8 *pDst, 227 OMX_INT dstStep) 228 { 229 230 OMX_U8 x,y; 231 OMX_INT temp; 232 233 for(y = 0; y < 8; y++) 234 { 235 for(x = 0; x < 8; x++) 236 { 237 temp = pSrc[x] + pSrcResidue[x]; 238 pDst[x] = armClip(0,255,temp); 239 } 240 pDst += dstStep; 241 pSrc += 8; 242 pSrcResidue += 8; 243 } 244 } 245 246 /** 247 * Function: omxVCM4P2_MCReconBlock (6.2.5.5.1) 248 * 249 * Description: 250 * Performs motion compensation prediction for an 8x8 block using 251 * interpolation described in [ISO14496-2], subclause 7.6.2. 252 * 253 * Input Arguments: 254 * 255 * pSrc - pointer to the block in the reference plane. 256 * srcStep - distance between the start of consecutive lines in the 257 * reference plane, in bytes; must be a multiple of 8. 258 * dstStep - distance between the start of consecutive lines in the 259 * destination plane, in bytes; must be a multiple of 8. 260 * pSrcResidue - pointer to a buffer containing the 16-bit prediction 261 * residuals; must be 16-byte aligned. If the pointer is NULL, then 262 * no prediction is done, only motion compensation, i.e., the block 263 * is moved with interpolation. 264 * predictType - bilinear interpolation type, as defined in section 265 * 6.2.1.2. 266 * rndVal - rounding control parameter: 0 - disabled; 1 - enabled. 267 * 268 * Output Arguments: 269 * 270 * pDst - pointer to the destination buffer; must be 8-byte aligned. If 271 * prediction residuals are added then output intensities are 272 * clipped to the range [0,255]. 273 * 274 * Return Value: 275 * 276 * OMX_Sts_NoErr - no error 277 * OMX_Sts_BadArgErr - bad arguments; returned under any of the following 278 * conditions: 279 * - pDst is not 8-byte aligned. 280 * - pSrcResidue is not 16-byte aligned. 281 * - one or more of the following pointers is NULL: pSrc or pDst. 282 * - either srcStep or dstStep is not a multiple of 8. 283 * - invalid type specified for the parameter predictType. 284 * - the parameter rndVal is not equal either to 0 or 1. 285 * 286 */ 287 OMXResult omxVCM4P2_MCReconBlock( 288 const OMX_U8 *pSrc, 289 OMX_INT srcStep, 290 const OMX_S16 *pSrcResidue, 291 OMX_U8 *pDst, 292 OMX_INT dstStep, 293 OMX_INT predictType, 294 OMX_INT rndVal) 295 { 296 /* Definitions and Initializations*/ 297 OMX_U8 pTempDst[64]; 298 299 /* Argument error checks */ 300 armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr); 301 armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr); 302 armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr); 303 armRetArgErrIf(!armIs16ByteAligned(pSrcResidue), OMX_Sts_BadArgErr); 304 armRetArgErrIf(((dstStep % 8) || (srcStep % 8)), OMX_Sts_BadArgErr); 305 armRetArgErrIf(((predictType != OMX_VC_INTEGER_PIXEL) && 306 (predictType != OMX_VC_HALF_PIXEL_X) && 307 (predictType != OMX_VC_HALF_PIXEL_Y) && 308 (predictType != OMX_VC_HALF_PIXEL_XY) 309 ),OMX_Sts_BadArgErr); 310 armRetArgErrIf(((rndVal != 0) && (rndVal != 1)),OMX_Sts_BadArgErr); 311 312 switch(predictType) 313 { 314 case OMX_VC_INTEGER_PIXEL: 315 armVCM4P2_MCReconBlock_NoRes(pSrc, 316 srcStep, 317 &(pTempDst[0]), 318 8); 319 break; 320 case OMX_VC_HALF_PIXEL_X: 321 armVCM4P2_HalfPelHor(pSrc, 322 srcStep, 323 &(pTempDst[0]), 324 rndVal); 325 break; 326 case OMX_VC_HALF_PIXEL_Y: 327 armVCM4P2_HalfPelVer(pSrc, 328 srcStep, 329 &(pTempDst[0]), 330 rndVal); 331 break; 332 case OMX_VC_HALF_PIXEL_XY: 333 armVCM4P2_HalfPelVerHor(pSrc, 334 srcStep, 335 &(pTempDst[0]), 336 rndVal); 337 break; 338 } 339 340 if(pSrcResidue == NULL) 341 { 342 armVCM4P2_MCReconBlock_NoRes(&(pTempDst[0]), 343 8, 344 pDst, 345 dstStep); 346 } 347 else 348 { 349 armVCM4P2_MCReconBlock_Res(&(pTempDst[0]), 350 pSrcResidue, 351 pDst, 352 dstStep); 353 } 354 355 return OMX_Sts_NoErr; 356 } 357 358