1 /** 2 * 3 * File Name: omxVCM4P2_MotionEstimationMB.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 motion search 16x16 macroblock 14 * 15 */ 16 17 #include "omxtypes.h" 18 #include "armOMX.h" 19 #include "omxVC.h" 20 21 #include "armVC.h" 22 #include "armCOMM.h" 23 24 /** 25 * Function: armVCM4P2_BlockMatch_16x16 26 * 27 * Description: 28 * 16x16 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_16x16. 29 * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_16x16 30 * 31 * Remarks: 32 * 33 * Parameters: 34 * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that 35 * corresponds to the location of the current macroblock in the current 36 * plane. 37 * [in] srcRefStep width of the reference plane 38 * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin. 39 * It's not limited to the image boundary, but depended on the padding. For example, 40 * if you pad 4 pixels outside the image border, then the value for left border 41 * can be -4 42 * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array, 43 * 256 entries); must be aligned on an 16-byte boundary. 44 * [in] pCurrPointPos position of the current macroblock in the current plane 45 * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV 46 * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable. 47 * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated 48 * and then initialized using omxVCM4P2_MEInit prior to calling the block matching 49 * function. 50 * [out] pDstMV pointer to estimated MV 51 * [out] pDstSAD pointer to minimum SAD 52 * * 53 * Return Value: 54 * OMX_Sts_NoErr - no error 55 * OMX_Sts_BadArgErr - bad arguments 56 * 57 */ 58 static OMXResult armVCM4P2_BlockMatch_16x16( 59 const OMX_U8 *pSrcRefBuf, 60 const OMX_INT srcRefStep, 61 const OMXRect *pRefRect, 62 const OMX_U8 *pSrcCurrBuf, 63 const OMXVCM4P2Coordinate *pCurrPointPos, 64 OMXVCMotionVector *pSrcPreMV, 65 OMX_INT *pSrcPreSAD, 66 void *pMESpec, 67 OMXVCMotionVector *pDstMV, 68 OMX_INT *pDstSAD 69 ) 70 { 71 OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec; 72 OMX_INT rndVal; 73 74 rndVal = pMEParams->rndVal; 75 76 omxVCM4P2_BlockMatch_Integer_16x16( 77 pSrcRefBuf, 78 srcRefStep, 79 pRefRect, 80 pSrcCurrBuf, 81 pCurrPointPos, 82 pSrcPreMV, 83 pSrcPreSAD, 84 pMEParams, 85 pDstMV, 86 pDstSAD); 87 88 if (pMEParams->halfPelSearchEnable) 89 { 90 omxVCM4P2_BlockMatch_Half_16x16( 91 pSrcRefBuf, 92 srcRefStep, 93 pRefRect, 94 pSrcCurrBuf, 95 pCurrPointPos, 96 rndVal, 97 pDstMV, 98 pDstSAD); 99 } 100 101 return OMX_Sts_NoErr; 102 } 103 104 /** 105 * Function: armVCM4P2_BlockMatch_8x8 106 * 107 * Description: 108 * 8x8 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_8x8. 109 * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_8x8 110 * 111 * Remarks: 112 * 113 * Parameters: 114 * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that 115 * corresponds to the location of the current macroblock in the current 116 * plane. 117 * [in] srcRefStep width of the reference plane 118 * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin. 119 * It's not limited to the image boundary, but depended on the padding. For example, 120 * if you pad 4 pixels outside the image border, then the value for left border 121 * can be -4 122 * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array, 123 * 256 entries); must be aligned on an 16-byte boundary. 124 * [in] pCurrPointPos position of the current macroblock in the current plane 125 * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV 126 * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable. 127 * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated 128 * and then initialized using omxVCM4P2_MEInit prior to calling the block matching 129 * function. 130 * [out] pDstMV pointer to estimated MV 131 * [out] pDstSAD pointer to minimum SAD 132 * * 133 * Return Value: 134 * OMX_Sts_NoErr - no error 135 * OMX_Sts_BadArgErr - bad arguments 136 * 137 */ 138 static OMXResult armVCM4P2_BlockMatch_8x8( 139 const OMX_U8 *pSrcRefBuf, 140 OMX_INT srcRefStep, 141 const OMXRect *pRefRect, 142 const OMX_U8 *pSrcCurrBuf, 143 const OMXVCM4P2Coordinate *pCurrPointPos, 144 OMXVCMotionVector *pSrcPreMV, 145 OMX_INT *pSrcPreSAD, 146 void *pMESpec, 147 OMXVCMotionVector *pSrcDstMV, 148 OMX_INT *pDstSAD 149 ) 150 { 151 OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec; 152 OMX_INT rndVal; 153 154 rndVal = pMEParams->rndVal; 155 156 omxVCM4P2_BlockMatch_Integer_8x8( 157 pSrcRefBuf, 158 srcRefStep, 159 pRefRect, 160 pSrcCurrBuf, 161 pCurrPointPos, 162 pSrcPreMV, 163 pSrcPreSAD, 164 pMEParams, 165 pSrcDstMV, 166 pDstSAD); 167 168 if (pMEParams->halfPelSearchEnable) 169 { 170 omxVCM4P2_BlockMatch_Half_8x8( 171 pSrcRefBuf, 172 srcRefStep, 173 pRefRect, 174 pSrcCurrBuf, 175 pCurrPointPos, 176 rndVal, 177 pSrcDstMV, 178 pDstSAD); 179 } 180 181 return OMX_Sts_NoErr; 182 } 183 184 185 /** 186 * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1) 187 * 188 * Description: 189 * Performs motion search for a 16x16 macroblock. Selects best motion search 190 * strategy from among inter-1MV, inter-4MV, and intra modes. Supports 191 * integer and half pixel resolution. 192 * 193 * Input Arguments: 194 * 195 * pSrcCurrBuf - pointer to the top-left corner of the current MB in the 196 * original picture plane; must be aligned on a 16-byte boundary. 197 * The function does not expect source data outside the region 198 * bounded by the MB to be available; for example it is not 199 * necessary for the caller to guarantee the availability of 200 * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB 201 * to be processed. 202 * srcCurrStep - width of the original picture plane, in terms of full 203 * pixels; must be a multiple of 16. 204 * pSrcRefBuf - pointer to the reference Y plane; points to the reference 205 * plane location corresponding to the location of the current 206 * macroblock in the current plane; must be aligned on a 16-byte 207 * boundary. 208 * srcRefStep - width of the reference picture plane, in terms of full 209 * pixels; must be a multiple of 16. 210 * pRefRect - reference plane valid region rectangle, specified relative to 211 * the image origin 212 * pCurrPointPos - position of the current macroblock in the current plane 213 * pMESpec - pointer to the vendor-specific motion estimation specification 214 * structure; must be allocated and then initialized using 215 * omxVCM4P2_MEInit prior to calling this function. 216 * pMBInfo - array, of dimension four, containing pointers to information 217 * associated with four nearby MBs: 218 * - pMBInfo[0] - pointer to left MB information 219 * - pMBInfo[1] - pointer to top MB information 220 * - pMBInfo[2] - pointer to top-left MB information 221 * - pMBInfo[3] - pointer to top-right MB information 222 * Any pointer in the array may be set equal to NULL if the 223 * corresponding MB doesn't exist. For each MB, the following structure 224 * members are used: 225 * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or 226 * OMX_VC_INTER4V 227 * - pMV0[2][2] - estimated motion vectors; represented 228 * in 1/2 pixel units 229 * - sliceID - number of the slice to which the MB belongs 230 * pSrcDstMBCurr - pointer to information structure for the current MB. 231 * The following entries should be set prior to calling the 232 * function: sliceID - the number of the slice the to which the 233 * current MB belongs. The structure elements cbpy and cbpc are 234 * ignored. 235 * 236 * Output Arguments: 237 * 238 * pSrcDstMBCurr - pointer to updated information structure for the current 239 * MB after MB-level motion estimation has been completed. The 240 * following structure members are updated by the ME function: 241 * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or 242 * OMX_VC_INTER4V. 243 * - pMV0[2][2] - estimated motion vectors; represented in 244 * terms of 1/2 pel units. 245 * - pMVPred[2][2] - predicted motion vectors; represented 246 * in terms of 1/2 pel units. 247 * The structure members cbpy and cbpc are not updated by the function. 248 * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs 249 * for INTER4V 250 * pDstBlockSAD - pointer to an array of SAD values for each of the four 251 * 8x8 luma blocks in the MB. The block SADs are in scan order for 252 * each MB. 253 * 254 * Return Value: 255 * 256 * OMX_Sts_NoErr - no error 257 * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the 258 * following conditions is true: 259 * - at least one of the following pointers is NULL: pSrcCurrBuf, 260 * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra, 261 * pSrcDstMBCurr, or pDstSAD. 262 * 263 */ 264 265 OMXResult omxVCM4P2_MotionEstimationMB ( 266 const OMX_U8 *pSrcCurrBuf, 267 OMX_S32 srcCurrStep, 268 const OMX_U8 *pSrcRefBuf, 269 OMX_S32 srcRefStep, 270 const OMXRect*pRefRect, 271 const OMXVCM4P2Coordinate *pCurrPointPos, 272 void *pMESpec, 273 const OMXVCM4P2MBInfoPtr *pMBInfo, 274 OMXVCM4P2MBInfo *pSrcDstMBCurr, 275 OMX_U16 *pDstSAD, 276 OMX_U16 *pDstBlockSAD 277 ) 278 { 279 280 OMX_INT intraSAD, average, count, index, x, y; 281 OMXVCMotionVector dstMV16x16; 282 OMX_INT dstSAD16x16; 283 OMX_INT dstSAD8x8; 284 OMXVCM4P2MEParams *pMEParams; 285 OMXVCM4P2Coordinate TempCurrPointPos; 286 OMXVCM4P2Coordinate *pTempCurrPointPos; 287 OMX_U8 aTempSrcCurrBuf[271]; 288 OMX_U8 *pTempSrcCurrBuf; 289 OMX_U8 *pDst; 290 OMX_U8 aDst[71]; 291 OMX_S32 dstStep = 8; 292 OMX_INT predictType; 293 OMX_S32 Sad; 294 const OMX_U8 *pTempSrcRefBuf; 295 OMXVCMotionVector* pSrcCandMV1[4]; 296 OMXVCMotionVector* pSrcCandMV2[4]; 297 OMXVCMotionVector* pSrcCandMV3[4]; 298 299 /* Argument error checks */ 300 armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr); 301 armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr); 302 armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr); 303 armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 304 armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 305 armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 306 armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); 307 armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr); 308 armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 309 310 311 pTempCurrPointPos = &(TempCurrPointPos); 312 pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf); 313 pMEParams = (OMXVCM4P2MEParams *)pMESpec; 314 pTempCurrPointPos->x = pCurrPointPos->x; 315 pTempCurrPointPos->y = pCurrPointPos->y; 316 pSrcDstMBCurr->mbType = OMX_VC_INTER; 317 318 /* Preparing a linear buffer for block match */ 319 for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16) 320 { 321 for(x = 0; x < 16; x++, count++, index++) 322 { 323 pTempSrcCurrBuf[count] = pSrcCurrBuf[index]; 324 } 325 } 326 for(y = 0, index = 0; y < 2; y++) 327 { 328 for(x = 0; x < 2; x++,index++) 329 { 330 if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA)) 331 { 332 pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]); 333 } 334 else 335 { 336 pSrcCandMV1[index] = NULL; 337 } 338 if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA)) 339 { 340 pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]); 341 } 342 else 343 { 344 pSrcCandMV2[index] = NULL; 345 } 346 if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA)) 347 { 348 pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]); 349 } 350 else 351 { 352 pSrcCandMV3[index] = NULL; 353 } 354 } 355 } 356 /* Calculating SAD at MV(0,0) */ 357 armVCCOMM_SAD(pTempSrcCurrBuf, 358 16, 359 pSrcRefBuf, 360 srcRefStep, 361 &Sad, 362 16, 363 16); 364 *pDstSAD = Sad; 365 366 /* Mode decision for NOT_CODED MB */ 367 if(*pDstSAD == 0) 368 { 369 pSrcDstMBCurr->pMV0[0][0].dx = 0; 370 pSrcDstMBCurr->pMV0[0][0].dy = 0; 371 *pDstSAD = 0; 372 return OMX_Sts_NoErr; 373 } 374 375 omxVCM4P2_FindMVpred( 376 &(pSrcDstMBCurr->pMV0[0][0]), 377 pSrcCandMV1[0], 378 pSrcCandMV2[0], 379 pSrcCandMV3[0], 380 &(pSrcDstMBCurr->pMVPred[0][0]), 381 NULL, 382 0); 383 384 /* Inter 1 MV */ 385 armVCM4P2_BlockMatch_16x16( 386 pSrcRefBuf, 387 srcRefStep, 388 pRefRect, 389 pTempSrcCurrBuf, 390 pCurrPointPos, 391 &(pSrcDstMBCurr->pMVPred[0][0]), 392 NULL, 393 pMEParams, 394 &dstMV16x16, 395 &dstSAD16x16); 396 397 /* Initialize all with 1 MV values */ 398 pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx; 399 pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy; 400 pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx; 401 pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy; 402 pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx; 403 pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy; 404 pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx; 405 pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy; 406 407 *pDstSAD = dstSAD16x16; 408 409 if (pMEParams->searchEnable8x8) 410 { 411 /* Inter 4MV */ 412 armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, 413 srcRefStep, pRefRect, 414 pTempSrcCurrBuf, pTempCurrPointPos, 415 &(pSrcDstMBCurr->pMVPred[0][0]), NULL, 416 pMEParams, &(pSrcDstMBCurr->pMV0[0][0]), 417 &dstSAD8x8 418 ); 419 pDstBlockSAD[0] = dstSAD8x8; 420 *pDstSAD = dstSAD8x8; 421 pTempCurrPointPos->x += 8; 422 pSrcRefBuf += 8; 423 omxVCM4P2_FindMVpred( 424 &(pSrcDstMBCurr->pMV0[0][1]), 425 pSrcCandMV1[1], 426 pSrcCandMV2[1], 427 pSrcCandMV3[1], 428 &(pSrcDstMBCurr->pMVPred[0][1]), 429 NULL, 430 1); 431 432 armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, 433 srcRefStep, pRefRect, 434 pTempSrcCurrBuf, pTempCurrPointPos, 435 &(pSrcDstMBCurr->pMVPred[0][1]), NULL, 436 pMEParams, &(pSrcDstMBCurr->pMV0[0][1]), 437 &dstSAD8x8 438 ); 439 pDstBlockSAD[1] = dstSAD8x8; 440 *pDstSAD += dstSAD8x8; 441 pTempCurrPointPos->x -= 8; 442 pTempCurrPointPos->y += 8; 443 pSrcRefBuf += (srcRefStep * 8) - 8; 444 445 omxVCM4P2_FindMVpred( 446 &(pSrcDstMBCurr->pMV0[1][0]), 447 pSrcCandMV1[2], 448 pSrcCandMV2[2], 449 pSrcCandMV3[2], 450 &(pSrcDstMBCurr->pMVPred[1][0]), 451 NULL, 452 2); 453 armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, 454 srcRefStep, pRefRect, 455 pTempSrcCurrBuf, pTempCurrPointPos, 456 &(pSrcDstMBCurr->pMVPred[1][0]), NULL, 457 pMEParams, &(pSrcDstMBCurr->pMV0[1][0]), 458 &dstSAD8x8 459 ); 460 pDstBlockSAD[2] = dstSAD8x8; 461 *pDstSAD += dstSAD8x8; 462 pTempCurrPointPos->x += 8; 463 pSrcRefBuf += 8; 464 omxVCM4P2_FindMVpred( 465 &(pSrcDstMBCurr->pMV0[1][1]), 466 pSrcCandMV1[3], 467 pSrcCandMV2[3], 468 pSrcCandMV3[3], 469 &(pSrcDstMBCurr->pMVPred[1][1]), 470 NULL, 471 3); 472 armVCM4P2_BlockMatch_8x8 (pSrcRefBuf, 473 srcRefStep, pRefRect, 474 pTempSrcCurrBuf, pTempCurrPointPos, 475 &(pSrcDstMBCurr->pMVPred[1][1]), NULL, 476 pMEParams, &(pSrcDstMBCurr->pMV0[1][1]), 477 &dstSAD8x8 478 ); 479 pDstBlockSAD[3] = dstSAD8x8; 480 *pDstSAD += dstSAD8x8; 481 482 483 /* Checking if 4MV is equal to 1MV */ 484 if ( 485 (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) || 486 (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) || 487 (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) || 488 (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) || 489 (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) || 490 (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) || 491 (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) || 492 (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy) 493 ) 494 { 495 /* select the 4 MV */ 496 pSrcDstMBCurr->mbType = OMX_VC_INTER4V; 497 } 498 } 499 500 /* finding the error in intra mode */ 501 for (count = 0, average = 0; count < 256 ; count++) 502 { 503 average = average + pTempSrcCurrBuf[count]; 504 } 505 average = average/256; 506 507 intraSAD = 0; 508 509 /* Intra SAD calculation */ 510 for (count = 0; count < 256 ; count++) 511 { 512 intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average)); 513 } 514 515 /* Using the MPEG4 VM formula for intra/inter mode decision 516 Var < (SAD - 2*NB) where NB = N^2 is the number of pixels 517 of the macroblock.*/ 518 519 if (intraSAD <= (*pDstSAD - 512)) 520 { 521 pSrcDstMBCurr->mbType = OMX_VC_INTRA; 522 pSrcDstMBCurr->pMV0[0][0].dx = 0; 523 pSrcDstMBCurr->pMV0[0][0].dy = 0; 524 *pDstSAD = intraSAD; 525 pDstBlockSAD[0] = 0xFFFF; 526 pDstBlockSAD[1] = 0xFFFF; 527 pDstBlockSAD[2] = 0xFFFF; 528 pDstBlockSAD[3] = 0xFFFF; 529 } 530 531 if(pSrcDstMBCurr->mbType == OMX_VC_INTER) 532 { 533 pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx; 534 535 if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1)) 536 { 537 predictType = OMX_VC_HALF_PIXEL_XY; 538 } 539 else if(dstMV16x16.dx & 0x1) 540 { 541 predictType = OMX_VC_HALF_PIXEL_X; 542 } 543 else if(dstMV16x16.dy & 0x1) 544 { 545 predictType = OMX_VC_HALF_PIXEL_Y; 546 } 547 else 548 { 549 predictType = OMX_VC_INTEGER_PIXEL; 550 } 551 552 pDst = armAlignTo8Bytes(&(aDst[0])); 553 /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */ 554 /* Block 0 */ 555 omxVCM4P2_MCReconBlock(pTempSrcRefBuf, 556 srcRefStep, 557 NULL, 558 pDst, 559 dstStep, 560 predictType, 561 pMEParams->rndVal); 562 563 armVCCOMM_SAD(pTempSrcCurrBuf, 564 16, 565 pDst, 566 dstStep, 567 &Sad, 568 8, 569 8); 570 pDstBlockSAD[0] = Sad; 571 572 /* Block 1 */ 573 omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8, 574 srcRefStep, 575 NULL, 576 pDst, 577 dstStep, 578 predictType, 579 pMEParams->rndVal); 580 581 armVCCOMM_SAD(pTempSrcCurrBuf + 8, 582 16, 583 pDst, 584 dstStep, 585 &Sad, 586 8, 587 8); 588 pDstBlockSAD[1] = Sad; 589 590 /* Block 2 */ 591 omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8), 592 srcRefStep, 593 NULL, 594 pDst, 595 dstStep, 596 predictType, 597 pMEParams->rndVal); 598 599 armVCCOMM_SAD(pTempSrcCurrBuf + (16*8), 600 16, 601 pDst, 602 dstStep, 603 &Sad, 604 8, 605 8); 606 pDstBlockSAD[2] = Sad; 607 608 /* Block 3 */ 609 omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8, 610 srcRefStep, 611 NULL, 612 pDst, 613 dstStep, 614 predictType, 615 pMEParams->rndVal); 616 617 armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8, 618 16, 619 pDst, 620 dstStep, 621 &Sad, 622 8, 623 8); 624 pDstBlockSAD[3] = Sad; 625 } 626 return OMX_Sts_NoErr; 627 } 628 629 /* End of file */ 630 631