00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "contributors.h"
00018 #include <limits.h>
00019
00020 #include "global.h"
00021 #include "image.h"
00022 #include "memalloc.h"
00023 #include "mb_access.h"
00024 #include "refbuf.h"
00025
00026 #include "me_distortion.h"
00027 #include "me_fullsearch.h"
00028 #include "conformance.h"
00029 #include "mv-search.h"
00030
00031
00032 extern short* spiral_search_x;
00033 extern short* spiral_search_y;
00034
00035
00036
00037
00038
00039 static int **search_setup_done;
00040 static int **search_center_x;
00041 static int **search_center_y;
00042 static int **pos_00;
00043 static distpel *****BlockSAD;
00044 static int **max_search_range;
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 void InitializeFastFullIntegerSearch (void)
00062 {
00063 int i, j, k, list;
00064 int search_range = params->search_range;
00065 int max_pos = (2*search_range+1) * (2*search_range+1);
00066
00067 if ((BlockSAD = (distpel*****)malloc (2 * sizeof(distpel****))) == NULL)
00068 no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
00069
00070 for (list=0; list<2;list++)
00071 {
00072 if ((BlockSAD[list] = (distpel****)malloc ((img->max_num_references) * sizeof(distpel***))) == NULL)
00073 no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
00074 for (i = 0; i < img->max_num_references; i++)
00075 {
00076 if ((BlockSAD[list][i] = (distpel***)malloc (8 * sizeof(distpel**))) == NULL)
00077 no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
00078 for (j = 1; j < 8; j++)
00079 {
00080 if ((BlockSAD[list][i][j] = (distpel**)malloc (16 * sizeof(distpel*))) == NULL)
00081 no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
00082 for (k = 0; k < 16; k++)
00083 {
00084 if ((BlockSAD[list][i][j][k] = (distpel*)malloc (max_pos * sizeof(distpel))) == NULL)
00085 no_mem_exit ("InitializeFastFullIntegerSearch: BlockSAD");
00086 }
00087 }
00088 }
00089 }
00090
00091 if ((search_setup_done = (int**)malloc (2*sizeof(int*)))==NULL)
00092 no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
00093 if ((search_center_x = (int**)malloc (2*sizeof(int*)))==NULL)
00094 no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
00095 if ((search_center_y = (int**)malloc (2*sizeof(int*)))==NULL)
00096 no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
00097 if ((pos_00 = (int**)malloc (2*sizeof(int*)))==NULL)
00098 no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
00099 if ((max_search_range = (int**)malloc (2*sizeof(int*)))==NULL)
00100 no_mem_exit ("InitializeFastFullIntegerSearch: max_search_range");
00101
00102 for (list=0; list<2; list++)
00103 {
00104 if ((search_setup_done[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
00105 no_mem_exit ("InitializeFastFullIntegerSearch: search_setup_done");
00106 if ((search_center_x[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
00107 no_mem_exit ("InitializeFastFullIntegerSearch: search_center_x");
00108 if ((search_center_y[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
00109 no_mem_exit ("InitializeFastFullIntegerSearch: search_center_y");
00110 if ((pos_00[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
00111 no_mem_exit ("InitializeFastFullIntegerSearch: pos_00");
00112 if ((max_search_range[list] = (int*)malloc ((img->max_num_references)*sizeof(int)))==NULL)
00113 no_mem_exit ("InitializeFastFullIntegerSearch: max_search_range");
00114 }
00115
00116
00117 if (params->full_search == 2)
00118 {
00119 for (list=0;list<2;list++)
00120 for (i=0; i<img->max_num_references; i++)
00121 max_search_range[list][i] = search_range;
00122 }
00123 else
00124 {
00125 for (list=0;list<2;list++)
00126 {
00127 max_search_range[list][0] = search_range;
00128 for (i=1; i< img->max_num_references; i++) max_search_range[list][i] = search_range / 2;
00129 }
00130 }
00131 }
00132
00133
00134
00135
00136
00137
00138
00139 void
00140 ClearFastFullIntegerSearch ()
00141 {
00142 int i, j, k, list;
00143
00144 for (list=0; list<2; list++)
00145 {
00146 for (i = 0; i < img->max_num_references; i++)
00147 {
00148 for (j = 1; j < 8; j++)
00149 {
00150 for (k = 0; k < 16; k++)
00151 {
00152 free (BlockSAD[list][i][j][k]);
00153 }
00154 free (BlockSAD[list][i][j]);
00155 }
00156 free (BlockSAD[list][i]);
00157 }
00158 free (BlockSAD[list]);
00159 }
00160 free (BlockSAD);
00161
00162 for (list=0; list<2; list++)
00163 {
00164 free (search_setup_done[list]);
00165 free (search_center_x[list]);
00166 free (search_center_y[list]);
00167 free (pos_00[list]);
00168 free (max_search_range[list]);
00169 }
00170 free (search_setup_done);
00171 free (search_center_x);
00172 free (search_center_y);
00173 free (pos_00);
00174 free (max_search_range);
00175
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 void ResetFastFullIntegerSearch ()
00187 {
00188 int list;
00189 for (list=0; list<2; list++)
00190 memset(&search_setup_done [list][0], 0, img->max_num_references * sizeof(int));
00191 }
00192
00193
00194
00195
00196
00197
00198 void
00199 SetupLargerBlocks (int list, int refindex, int max_pos)
00200 {
00201 #define ADD_UP_BLOCKS() _o=*_bo; _i=*_bi; _j=*_bj; for(pos=0;pos<max_pos;pos++) _o[pos] = _i[pos] + _j[pos];
00202 #define INCREMENT(inc) _bo+=inc; _bi+=inc; _bj+=inc;
00203
00204 int pos;
00205 distpel **_bo, **_bi, **_bj;
00206 register distpel *_o, *_i, *_j;
00207
00208
00209 _bo = BlockSAD[list][refindex][6];
00210 _bi = BlockSAD[list][refindex][7];
00211 _bj = _bi + 4;
00212 ADD_UP_BLOCKS(); INCREMENT(1);
00213 ADD_UP_BLOCKS(); INCREMENT(1);
00214 ADD_UP_BLOCKS(); INCREMENT(1);
00215 ADD_UP_BLOCKS(); INCREMENT(5);
00216 ADD_UP_BLOCKS(); INCREMENT(1);
00217 ADD_UP_BLOCKS(); INCREMENT(1);
00218 ADD_UP_BLOCKS(); INCREMENT(1);
00219 ADD_UP_BLOCKS();
00220
00221
00222 _bo = BlockSAD[list][refindex][5];
00223 _bi = BlockSAD[list][refindex][7];
00224 _bj = _bi + 1;
00225 ADD_UP_BLOCKS(); INCREMENT(2);
00226 ADD_UP_BLOCKS(); INCREMENT(2);
00227 ADD_UP_BLOCKS(); INCREMENT(2);
00228 ADD_UP_BLOCKS(); INCREMENT(2);
00229 ADD_UP_BLOCKS(); INCREMENT(2);
00230 ADD_UP_BLOCKS(); INCREMENT(2);
00231 ADD_UP_BLOCKS(); INCREMENT(2);
00232 ADD_UP_BLOCKS();
00233
00234
00235 _bo = BlockSAD[list][refindex][4];
00236 _bi = BlockSAD[list][refindex][6];
00237 _bj = _bi + 1;
00238 ADD_UP_BLOCKS(); INCREMENT(2);
00239 ADD_UP_BLOCKS(); INCREMENT(6);
00240 ADD_UP_BLOCKS(); INCREMENT(2);
00241 ADD_UP_BLOCKS();
00242
00243
00244 _bo = BlockSAD[list][refindex][3];
00245 _bi = BlockSAD[list][refindex][4];
00246 _bj = _bi + 8;
00247 ADD_UP_BLOCKS(); INCREMENT(2);
00248 ADD_UP_BLOCKS();
00249
00250
00251 _bo = BlockSAD[list][refindex][2];
00252 _bi = BlockSAD[list][refindex][4];
00253 _bj = _bi + 2;
00254 ADD_UP_BLOCKS(); INCREMENT(8);
00255 ADD_UP_BLOCKS();
00256
00257
00258 _bo = BlockSAD[list][refindex][1];
00259 _bi = BlockSAD[list][refindex][3];
00260 _bj = _bi + 2;
00261 ADD_UP_BLOCKS();
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271 #define GEN_ME 0
00272 #if GEN_ME
00273 void SetupFastFullPelSearch (Macroblock *currMb, short ref, int list)
00274 {
00275 short pmv[2];
00276 MotionVector mv;
00277 static imgpel orig_pels[768];
00278
00279 imgpel *srcptr = orig_pels;
00280 int offset_x, offset_y, range_partly_outside, ref_x, ref_y, pos, abs_x, abs_y, bindex, blky;
00281 int max_width, max_height;
00282 int img_width, img_height;
00283
00284 StorablePicture *ref_picture;
00285 distpel** block_sad = BlockSAD[list][ref][7];
00286 int search_range = max_search_range[list][ref];
00287 int max_pos = (2*search_range+1) * (2*search_range+1);
00288
00289 int list_offset = img->mb_data[img->current_mb_nr].list_offset;
00290
00291 int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
00292 (active_pps->weighted_bipred_idc && (img->type == B_SLICE))) && params->UseWeightedReferenceME;
00293 int abs_y4, abs_x4;
00294
00295 int i, j, k;
00296 int level_dist = F_PEL + apply_weights * 3;
00297 int pixel_x, pixel_y;
00298
00299
00300 for ( j= img->opix_y; j < img->opix_y + MB_BLOCK_SIZE; j +=BLOCK_SIZE)
00301 {
00302 for (pixel_y = j; pixel_y < j + BLOCK_SIZE; pixel_y++)
00303 {
00304 memcpy( srcptr, &pCurImg[pixel_y][img->opix_x], BLOCK_SIZE * sizeof(imgpel));
00305 memcpy( srcptr + 16, &pCurImg[pixel_y][img->opix_x + BLOCK_SIZE], BLOCK_SIZE * sizeof(imgpel));
00306 memcpy( srcptr + 32, &pCurImg[pixel_y][img->opix_x + 2 * BLOCK_SIZE], BLOCK_SIZE * sizeof(imgpel));
00307 memcpy( srcptr + 48, &pCurImg[pixel_y][img->opix_x + 3 * BLOCK_SIZE], BLOCK_SIZE * sizeof(imgpel));
00308 srcptr += BLOCK_SIZE;
00309 }
00310 srcptr += 48;
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 if (ChromaMEEnable)
00321 {
00322 imgpel *auxptr;
00323 int uv;
00324 int bsx_c = BLOCK_SIZE >> (chroma_shift_x - 2);
00325 int bsy_c = BLOCK_SIZE >> (chroma_shift_y - 2);
00326 int pic_pix_x_c = img->opix_x >> (chroma_shift_x - 2);
00327 int pic_pix_y_c = img->opix_y >> (chroma_shift_y - 2);
00328
00329
00330
00331 for (uv = 1; uv < 3; uv++)
00332 {
00333 srcptr = auxptr = orig_pels + (256 << (uv - 1));
00334 for ( pixel_y = 0, i = 0; i < (BLOCK_SIZE >> (chroma_shift_y - 2)); i++, pixel_y += bsy_c )
00335 {
00336 for ( pixel_x = 0, k = 0; k < (BLOCK_SIZE >> (chroma_shift_x - 2)); k++, pixel_x += bsx_c )
00337 {
00338 srcptr = auxptr;
00339 for (j = 0; j < bsy_c; j++)
00340 {
00341 memcpy( srcptr, &pImgOrg[uv][pic_pix_y_c + pixel_y + j][pic_pix_x_c + pixel_x], bsx_c * sizeof(imgpel));
00342 srcptr += bsx_c;
00343 }
00344 auxptr += MB_BLOCK_SIZE;
00345 }
00346 }
00347 }
00348 }
00349
00350
00351 ref_picture = listX[list+list_offset][ref];
00352
00353
00354 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
00355
00356 if (apply_weights)
00357 {
00358 weight_luma = wp_weight[list + list_offset][ref][0];
00359 offset_luma = wp_offset[list + list_offset][ref][0];
00360 }
00361
00362 if ( ChromaMEEnable)
00363 {
00364 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
00365 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
00366 width_pad_cr = ref_picture->size_x_cr_pad;
00367 height_pad_cr = ref_picture->size_y_cr_pad;
00368 if (apply_weights)
00369 {
00370 weight_cr[0] = wp_weight[list + list_offset][ref][1];
00371 weight_cr[1] = wp_weight[list + list_offset][ref][2];
00372 offset_cr[0] = wp_offset[list + list_offset][ref][1];
00373 offset_cr[1] = wp_offset[list + list_offset][ref][2];
00374 }
00375 }
00376
00377 max_width = ref_picture->size_x - 17;
00378 max_height = ref_picture->size_y - 17;
00379
00380 img_width = ref_picture->size_x;
00381 img_height = ref_picture->size_y;
00382 width_pad = ref_picture->size_x_pad;
00383 height_pad = ref_picture->size_y_pad;
00384
00385
00386 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, 0, 0, 16);
00387 GetMotionVectorPredictor (currMB, &block_a, &block_b, &block_c, pmv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, 0, 0, 16, 16);
00388
00389 mv.mv_x = pmv[0] / 4;
00390 mv.mv_y = pmv[1] / 4;
00391
00392 if (!params->rdopt)
00393 {
00394
00395 mv.mv_x = iClip3(-search_range, search_range, mv.mv_x);
00396 mv.mv_y = iClip3(-search_range, search_range, mv.mv_y);
00397 }
00398
00399 clip_mv_range(img, search_range, &mv, F_PEL);
00400
00401 search_center_x[list][ref] = mv.mv_x + img->opix_x;
00402 search_center_y[list][ref] = mv.mv_y + img->opix_y;
00403
00404 offset_x = search_center_x[list][ref];
00405 offset_y = search_center_y[list][ref];
00406
00407
00408
00409 if (offset_x >= search_range && offset_x <= max_width - search_range &&
00410 offset_y >= search_range && offset_y <= max_height - search_range )
00411 {
00412 range_partly_outside = 0;
00413 }
00414 else
00415 {
00416 range_partly_outside = 1;
00417 }
00418
00419
00420 if (!params->rdopt)
00421 {
00422 ref_x = img->opix_x - offset_x;
00423 ref_y = img->opix_y - offset_y;
00424
00425 for (pos = 0; pos < max_pos; pos++)
00426 {
00427 if (ref_x == spiral_search_x[pos] &&
00428 ref_y == spiral_search_y[pos])
00429 {
00430 pos_00[list][ref] = pos;
00431 break;
00432 }
00433 }
00434 }
00435
00436
00437 for (pos = 0; pos < max_pos; pos++)
00438 {
00439 abs_y = offset_y + spiral_search_y[pos];
00440 abs_x = offset_x + spiral_search_x[pos];
00441
00442 abs_y4 = (abs_y + IMG_PAD_SIZE) << 2;
00443 abs_x4 = (abs_x + IMG_PAD_SIZE) << 2;
00444
00445 srcptr = orig_pels;
00446 bindex = 0;
00447 for (blky = 0; blky < 4; blky++)
00448 {
00449 block_sad[bindex++][pos] = computeUniPred[level_dist](srcptr, 4, 4, INT_MAX, abs_x4, abs_y4);
00450 srcptr += 16;
00451 block_sad[bindex++][pos] = computeUniPred[level_dist](srcptr, 4, 4, INT_MAX, abs_x4 + 16, abs_y4);
00452 srcptr += 16;
00453 block_sad[bindex++][pos] = computeUniPred[level_dist](srcptr, 4, 4, INT_MAX, abs_x4 + 32, abs_y4);
00454 srcptr += 16;
00455 block_sad[bindex++][pos] = computeUniPred[level_dist](srcptr, 4, 4, INT_MAX, abs_x4 + 48, abs_y4);
00456 srcptr += 16;
00457 abs_y4 += 16;
00458 }
00459 }
00460
00461
00462 SetupLargerBlocks (list, ref, max_pos);
00463
00464
00465 search_setup_done[list][ref] = 1;
00466 }
00467
00468 #else
00469 void SetupFastFullPelSearch (Macroblock *currMB, short ref, int list)
00470 {
00471 short pmv[2];
00472 static imgpel orig_pels[768];
00473 imgpel *srcptr = orig_pels, *refptr;
00474 int k, x, y;
00475 int abs_y4, abs_x4;
00476 int offset_x, offset_y, range_partly_outside, ref_x, ref_y, pos, abs_x, abs_y, bindex, blky;
00477 int LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
00478 int max_width, max_height;
00479 int img_width, img_height;
00480 static PixelPos block_a, block_b, block_c, block_d;
00481
00482 StorablePicture *ref_picture;
00483 distpel** block_sad = BlockSAD[list][ref][7];
00484 int search_range = max_search_range[list][ref];
00485 int max_pos = (2*search_range+1) * (2*search_range+1);
00486
00487 int list_offset = img->mb_data[img->current_mb_nr].list_offset;
00488 int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
00489 (active_pps->weighted_bipred_idc && (img->type == B_SLICE))) && params->UseWeightedReferenceME;
00490 int weighted_pel;
00491 int *dist_method = params->MEErrorMetric[0] ? img->quad : byte_abs;
00492
00493 ref_picture = listX[list+list_offset][ref];
00494
00495 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
00496
00497 max_width = ref_picture->size_x - 17;
00498 max_height = ref_picture->size_y - 17;
00499
00500 img_width = ref_picture->size_x;
00501 img_height = ref_picture->size_y;
00502 width_pad = ref_picture->size_x_pad;
00503 height_pad = ref_picture->size_y_pad;
00504
00505 if (apply_weights)
00506 {
00507 weight_luma = wp_weight[list + list_offset][ref][0];
00508 offset_luma = wp_offset[list + list_offset][ref][0];
00509 }
00510
00511 if ( ChromaMEEnable)
00512 {
00513 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
00514 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
00515 width_pad_cr = ref_picture->size_x_cr_pad;
00516 height_pad_cr = ref_picture->size_y_cr_pad;
00517
00518 if (apply_weights)
00519 {
00520 weight_cr[0] = wp_weight[list + list_offset][ref][1];
00521 weight_cr[1] = wp_weight[list + list_offset][ref][2];
00522 offset_cr[0] = wp_offset[list + list_offset][ref][1];
00523 offset_cr[1] = wp_offset[list + list_offset][ref][2];
00524 }
00525 }
00526
00527
00528 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, 0, 0, 16);
00529 GetMotionVectorPredictor (currMB, &block_a, &block_b, &block_c, pmv, enc_picture->motion.ref_idx[list], enc_picture->motion.mv[list], ref, 0, 0, 16, 16);
00530
00531 search_center_x[list][ref] = pmv[0] / 4;
00532 search_center_y[list][ref] = pmv[1] / 4;
00533
00534 if (!params->rdopt)
00535 {
00536
00537 search_center_x[list][ref] = iClip3(-search_range, search_range, search_center_x[list][ref]);
00538 search_center_y[list][ref] = iClip3(-search_range, search_range, search_center_y[list][ref]);
00539 }
00540
00541 search_center_x[list][ref] = iClip3(img->MaxHmvR[0] + search_range, img->MaxHmvR[1] - search_range, search_center_x[list][ref]);
00542 search_center_y[list][ref] = iClip3(img->MaxVmvR[0] + search_range, img->MaxVmvR[1] - search_range, search_center_y[list][ref]);
00543
00544 search_center_x[list][ref] += img->opix_x;
00545 search_center_y[list][ref] += img->opix_y;
00546
00547 offset_x = search_center_x[list][ref];
00548 offset_y = search_center_y[list][ref];
00549
00550
00551
00552 for (y = img->opix_y; y < img->opix_y+MB_BLOCK_SIZE; y++)
00553 {
00554 memcpy(srcptr, &pCurImg[y][img->opix_x], MB_BLOCK_SIZE * sizeof(imgpel));
00555 srcptr += MB_BLOCK_SIZE;
00556 }
00557 if ( ChromaMEEnable)
00558 {
00559 for (k = 1; k < 3; k++)
00560 {
00561 for (y = img->opix_c_y; y < img->opix_c_y + img->mb_cr_size_y; y++)
00562 {
00563 memcpy(srcptr, &pImgOrg[k][y][img->opix_c_x], img->mb_cr_size_x * sizeof(imgpel));
00564 srcptr += img->mb_cr_size_x;
00565 }
00566 }
00567 }
00568
00569
00570 if (offset_x >= search_range && offset_x <= max_width - search_range &&
00571 offset_y >= search_range && offset_y <= max_height - search_range )
00572 {
00573 range_partly_outside = 0;
00574 }
00575 else
00576 {
00577 range_partly_outside = 1;
00578 }
00579
00580
00581 if (!params->rdopt)
00582 {
00583 ref_x = img->opix_x - offset_x;
00584 ref_y = img->opix_y - offset_y;
00585
00586 for (pos = 0; pos < max_pos; pos++)
00587 {
00588 if (ref_x == spiral_search_x[pos] &&
00589 ref_y == spiral_search_y[pos])
00590 {
00591 pos_00[list][ref] = pos;
00592 break;
00593 }
00594 }
00595 }
00596
00597
00598 for (pos = 0; pos < max_pos; pos++)
00599 {
00600 abs_y = offset_y + spiral_search_y[pos];
00601 abs_x = offset_x + spiral_search_x[pos];
00602
00603 abs_y4 = (abs_y + IMG_PAD_SIZE) << 2;
00604 abs_x4 = (abs_x + IMG_PAD_SIZE) << 2;
00605
00606 if (apply_weights)
00607 {
00608 srcptr = orig_pels;
00609 bindex = 0;
00610
00611 refptr = UMVLine4X (ref_pic_sub.luma, abs_y4, abs_x4, height_pad, width_pad);
00612
00613 for (blky = 0; blky < 4; blky++)
00614 {
00615 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00616
00617 for (y = 0; y < 4; y++)
00618 {
00619 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00620 LineSadBlk0 += dist_method [weighted_pel - *srcptr++];
00621 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00622 LineSadBlk0 += dist_method [weighted_pel - *srcptr++];
00623 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00624 LineSadBlk0 += dist_method [weighted_pel - *srcptr++];
00625 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00626 LineSadBlk0 += dist_method [weighted_pel - *srcptr++];
00627 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00628 LineSadBlk1 += dist_method [weighted_pel - *srcptr++];
00629 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00630 LineSadBlk1 += dist_method [weighted_pel - *srcptr++];
00631 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00632 LineSadBlk1 += dist_method [weighted_pel - *srcptr++];
00633 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00634 LineSadBlk1 += dist_method [weighted_pel - *srcptr++];
00635 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00636 LineSadBlk2 += dist_method [weighted_pel - *srcptr++];
00637 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00638 LineSadBlk2 += dist_method [weighted_pel - *srcptr++];
00639 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00640 LineSadBlk2 += dist_method [weighted_pel - *srcptr++];
00641 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00642 LineSadBlk2 += dist_method [weighted_pel - *srcptr++];
00643 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00644 LineSadBlk3 += dist_method [weighted_pel - *srcptr++];
00645 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00646 LineSadBlk3 += dist_method [weighted_pel - *srcptr++];
00647 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00648 LineSadBlk3 += dist_method [weighted_pel - *srcptr++];
00649 weighted_pel = iClip1( img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00650 LineSadBlk3 += dist_method [weighted_pel - *srcptr++];
00651 refptr += img_padded_size_x - MB_BLOCK_SIZE;
00652 }
00653
00654 block_sad[bindex++][pos] = LineSadBlk0;
00655 block_sad[bindex++][pos] = LineSadBlk1;
00656 block_sad[bindex++][pos] = LineSadBlk2;
00657 block_sad[bindex++][pos] = LineSadBlk3;
00658 }
00659 if (ChromaMEEnable)
00660 {
00661 int max_imgpel_value_uv = img->max_imgpel_value_comp[1];
00662 for (k = 0; k < 2; k ++)
00663 {
00664 bindex = 0;
00665
00666 refptr = UMVLine8X_chroma (ref_pic_sub.crcb[k], abs_y4, abs_x4, height_pad_cr, width_pad_cr);
00667 for (blky = 0; blky < 4; blky++)
00668 {
00669 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00670
00671 for (y = 0; y < img->mb_cr_size_y; y+=BLOCK_SIZE)
00672 {
00673 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00674 {
00675 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00676 LineSadBlk0 += dist_method [weighted_pel - *srcptr++];
00677 }
00678 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00679 {
00680 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00681 LineSadBlk1 += dist_method [weighted_pel - *srcptr++];
00682 }
00683 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00684 {
00685 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00686 LineSadBlk2 += dist_method [weighted_pel - *srcptr++];
00687 }
00688 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00689 {
00690 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00691 LineSadBlk3 += dist_method [weighted_pel - *srcptr++];
00692 }
00693 refptr += img_cr_padded_size_x - img->mb_cr_size_x;
00694 }
00695
00696 block_sad[bindex++][pos] += LineSadBlk0;
00697 block_sad[bindex++][pos] += LineSadBlk1;
00698 block_sad[bindex++][pos] += LineSadBlk2;
00699 block_sad[bindex++][pos] += LineSadBlk3;
00700 }
00701 }
00702 }
00703 }
00704 else
00705 {
00706 srcptr = orig_pels;
00707 bindex = 0;
00708
00709 refptr = UMVLine4X (ref_pic_sub.luma, abs_y4, abs_x4, height_pad, width_pad);
00710
00711 for (blky = 0; blky < 4; blky++)
00712 {
00713 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00714
00715 for (y = 0; y < 4; y++)
00716 {
00717 LineSadBlk0 += dist_method [*refptr++ - *srcptr++];
00718 LineSadBlk0 += dist_method [*refptr++ - *srcptr++];
00719 LineSadBlk0 += dist_method [*refptr++ - *srcptr++];
00720 LineSadBlk0 += dist_method [*refptr++ - *srcptr++];
00721 LineSadBlk1 += dist_method [*refptr++ - *srcptr++];
00722 LineSadBlk1 += dist_method [*refptr++ - *srcptr++];
00723 LineSadBlk1 += dist_method [*refptr++ - *srcptr++];
00724 LineSadBlk1 += dist_method [*refptr++ - *srcptr++];
00725 LineSadBlk2 += dist_method [*refptr++ - *srcptr++];
00726 LineSadBlk2 += dist_method [*refptr++ - *srcptr++];
00727 LineSadBlk2 += dist_method [*refptr++ - *srcptr++];
00728 LineSadBlk2 += dist_method [*refptr++ - *srcptr++];
00729 LineSadBlk3 += dist_method [*refptr++ - *srcptr++];
00730 LineSadBlk3 += dist_method [*refptr++ - *srcptr++];
00731 LineSadBlk3 += dist_method [*refptr++ - *srcptr++];
00732 LineSadBlk3 += dist_method [*refptr++ - *srcptr++];
00733 refptr += img_padded_size_x - MB_BLOCK_SIZE;
00734 }
00735
00736 block_sad[bindex++][pos] = LineSadBlk0;
00737 block_sad[bindex++][pos] = LineSadBlk1;
00738 block_sad[bindex++][pos] = LineSadBlk2;
00739 block_sad[bindex++][pos] = LineSadBlk3;
00740 }
00741
00742 if (ChromaMEEnable)
00743 {
00744 for (k = 0; k < 2; k ++)
00745 {
00746 bindex = 0;
00747
00748 refptr = UMVLine8X_chroma (ref_pic_sub.crcb[k], abs_y4, abs_x4, height_pad_cr, width_pad_cr);
00749 for (blky = 0; blky < 4; blky++)
00750 {
00751 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00752
00753 for (y = 0; y < img->mb_cr_size_y; y+=BLOCK_SIZE)
00754 {
00755 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00756 {
00757 LineSadBlk0 += dist_method [*refptr++ - *srcptr++];
00758 }
00759 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00760 {
00761 LineSadBlk1 += dist_method [*refptr++ - *srcptr++];
00762 }
00763 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00764 {
00765 LineSadBlk2 += dist_method [*refptr++ - *srcptr++];
00766 }
00767 for (x = 0; x < img->mb_cr_size_x; x += BLOCK_SIZE)
00768 {
00769 LineSadBlk3 += dist_method [*refptr++ - *srcptr++];
00770 }
00771 refptr += img_cr_padded_size_x - img->mb_cr_size_x;
00772 }
00773
00774 block_sad[bindex++][pos] += LineSadBlk0;
00775 block_sad[bindex++][pos] += LineSadBlk1;
00776 block_sad[bindex++][pos] += LineSadBlk2;
00777 block_sad[bindex++][pos] += LineSadBlk3;
00778 }
00779 }
00780 }
00781 }
00782 }
00783
00784
00785 SetupLargerBlocks (list, ref, max_pos);
00786
00787
00788 search_setup_done[list][ref] = 1;
00789 }
00790 #endif
00791
00792
00793
00794
00795
00796
00797
00798 int
00799 FastFullPelBlockMotionSearch (Macroblock *currMB,
00800 imgpel* orig_pic,
00801 short ref,
00802 int list,
00803 char ***refPic,
00804 short ****tmp_mv,
00805 int pic_pix_x,
00806 int pic_pix_y,
00807 int blocktype,
00808 MotionVector *pred_mv,
00809 MotionVector *mv,
00810 int search_range,
00811 int min_mcost,
00812 int lambda_factor,
00813 int apply_weights
00814 )
00815 {
00816 int pos, offset_x, offset_y, cand_x, cand_y, mcost;
00817 int max_pos = (2*search_range+1)*(2*search_range+1);
00818 int best_pos = 0;
00819 int block_index;
00820 distpel* block_sad;
00821
00822 block_index = (pic_pix_y-img->opix_y)+((pic_pix_x-img->opix_x)>>2);
00823 block_sad = BlockSAD[list][ref][blocktype][block_index];
00824
00825
00826 if (!search_setup_done[list][ref])
00827 {
00828 SetupFastFullPelSearch (currMB, ref, list);
00829 }
00830
00831 offset_x = search_center_x[list][ref] - img->opix_x;
00832 offset_y = search_center_y[list][ref] - img->opix_y;
00833
00834
00835 if (!params->rdopt)
00836 {
00837 mcost = block_sad[pos_00[list][ref]] + MV_COST_SMP (lambda_factor, 0, 0, pred_mv->mv_x, pred_mv->mv_y);
00838
00839 if (mcost < min_mcost)
00840 {
00841 min_mcost = mcost;
00842 best_pos = pos_00[list][ref];
00843 }
00844 }
00845
00846
00847 for (pos=0; pos<max_pos; pos++, block_sad++)
00848 {
00849
00850 if (*block_sad < min_mcost)
00851 {
00852
00853 cand_x = (offset_x + spiral_search_x[pos])<<2;
00854 cand_y = (offset_y + spiral_search_y[pos])<<2;
00855 mcost = *block_sad;
00856 mcost += MV_COST_SMP (lambda_factor, cand_x, cand_y, pred_mv->mv_x, pred_mv->mv_y);
00857
00858
00859 if (mcost < min_mcost)
00860 {
00861 min_mcost = mcost;
00862 best_pos = pos;
00863 }
00864 }
00865 }
00866
00867
00868 mv->mv_x = offset_x + spiral_search_x[best_pos];
00869 mv->mv_y = offset_y + spiral_search_y[best_pos];
00870 return min_mcost;
00871 }
00872