00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <limits.h>
00027
00028 #include "global.h"
00029 #include "memalloc.h"
00030 #include "me_umhexsmp.h"
00031 #include "refbuf.h"
00032 #include "me_distortion.h"
00033 #include "mv-search.h"
00034
00035
00036 static const short Diamond_X[4] = {-1, 1, 0, 0};
00037 static const short Diamond_Y[4] = { 0, 0,-1, 1};
00038 static const short Hexagon_X[6] = {-2, 2,-1, 1,-1, 1};
00039 static const short Hexagon_Y[6] = { 0, 0,-2, 2, 2,-2};
00040 static const short Big_Hexagon_X[16] = {-4, 4, 0, 0,-4, 4,-4, 4,-4, 4,-4, 4,-2, 2,-2, 2};
00041 static const short Big_Hexagon_Y[16] = { 0, 0,-4, 4,-1, 1, 1,-1,-2, 2, 2,-2,-3, 3, 3,-3};
00042
00043 const short block_type_shift_factor[8] = {0, 0, 1, 1, 2, 3, 3, 1};
00044
00045 static StorablePicture *ref_pic_ptr;
00046 static int dist_method;
00047
00048 extern short* spiral_hpel_search_x;
00049 extern short* spiral_hpel_search_y;
00050 extern short* spiral_search_x;
00051 extern short* spiral_search_y;
00052
00053
00054 #define SEARCH_ONE_PIXEL_HELPER \
00055 if(iabs(cand_x - center_x) <= search_range && iabs(cand_y - center_y) <= search_range) \
00056 { \
00057 mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y); \
00058 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, \
00059 min_mcost - mcost, (cand_x + IMG_PAD_SIZE) << 2, (cand_y + IMG_PAD_SIZE) << 2); \
00060 if (mcost < min_mcost) \
00061 { \
00062 best_x = cand_x; \
00063 best_y = cand_y; \
00064 min_mcost = mcost; \
00065 } \
00066 }
00067
00068 #define SEARCH_ONE_PIXEL_BIPRED_HELPER \
00069 if (iabs(cand_x - center2_x) <= search_range && iabs(cand_y - center2_y) <= search_range) \
00070 { \
00071 mcost = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1); \
00072 mcost += MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x2, pred_y2); \
00073 if (mcost < min_mcost) \
00074 { \
00075 mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, \
00076 min_mcost - mcost, \
00077 (center1_x << 2) + IMG_PAD_SIZE_TIMES4, \
00078 (center1_y << 2) + IMG_PAD_SIZE_TIMES4, \
00079 (cand_x << 2) + IMG_PAD_SIZE_TIMES4, \
00080 (cand_y << 2) + IMG_PAD_SIZE_TIMES4); \
00081 if (mcost < min_mcost) \
00082 { \
00083 best_x = cand_x; \
00084 best_y = cand_y; \
00085 min_mcost = mcost; \
00086 } \
00087 } \
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 void smpUMHEX_init()
00099 {
00100 SymmetricalCrossSearchThreshold1 = 800;
00101 SymmetricalCrossSearchThreshold2 = 7000;
00102 ConvergeThreshold = 1000;
00103 SubPelThreshold1 = 1000;
00104 SubPelThreshold3 = 400;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113 int smpUMHEX_get_mem()
00114 {
00115 int memory_size = 0;
00116 if (NULL==(smpUMHEX_flag_intra = calloc((img->width>>4)+1, sizeof(byte))))
00117 no_mem_exit("smpUMHEX_get_mem: smpUMHEX_flag_intra");
00118
00119 memory_size += get_mem3Dint(&smpUMHEX_l0_cost, 9, img->height/4, img->width/4);
00120 memory_size += get_mem3Dint(&smpUMHEX_l1_cost, 9, img->height/4, img->width/4);
00121 memory_size += get_mem2D(&smpUMHEX_SearchState, 7, 7);
00122
00123 return memory_size;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132 void smpUMHEX_free_mem()
00133 {
00134 free_mem3Dint(smpUMHEX_l0_cost );
00135 free_mem3Dint(smpUMHEX_l1_cost );
00136 free_mem2D(smpUMHEX_SearchState);
00137
00138 free (smpUMHEX_flag_intra);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148 int
00149 smpUMHEXIntegerPelBlockMotionSearch (Macroblock *currMB,
00150 imgpel *orig_pic,
00151 short ref,
00152 int list,
00153 char ***refPic,
00154 short ****tmp_mv,
00155 int pic_pix_x,
00156 int pic_pix_y,
00157 int blocktype,
00158 MotionVector *pred_mv,
00159 MotionVector *mv,
00160 int search_range,
00161 int min_mcost,
00162 int lambda_factor,
00163 int apply_weights
00164 )
00165 {
00166 int mvshift = 2;
00167 int blocksize_y = params->blc_size[blocktype][1];
00168 int blocksize_x = params->blc_size[blocktype][0];
00169 int pred_x = (pic_pix_x << mvshift) + pred_mv->mv_x;
00170 int pred_y = (pic_pix_y << mvshift) + pred_mv->mv_y;
00171 int center_x = pic_pix_x + mv->mv_x;
00172 int center_y = pic_pix_y + mv->mv_y;
00173 int best_x = 0, best_y = 0;
00174 int search_step, iYMinNow, iXMinNow;
00175 int cand_x, cand_y, mcost;
00176
00177 unsigned short i, j, m;
00178
00179
00180
00181 dist_method = F_PEL + 3 * apply_weights;
00182
00183 ref_pic_ptr = listX[list + currMB->list_offset][ref];
00184
00185
00186 ref_pic_sub.luma = ref_pic_ptr->p_curr_img_sub;
00187
00188 img_width = ref_pic_ptr->size_x;
00189 img_height = ref_pic_ptr->size_y;
00190 width_pad = ref_pic_ptr->size_x_pad;
00191 height_pad = ref_pic_ptr->size_y_pad;
00192
00193 if (apply_weights)
00194 {
00195 weight_luma = wp_weight[list + currMB->list_offset][ref][0];
00196 offset_luma = wp_offset[list + currMB->list_offset][ref][0];
00197 }
00198
00199 if (ChromaMEEnable)
00200 {
00201 ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
00202 ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
00203 width_pad_cr = ref_pic_ptr->size_x_cr_pad;
00204 height_pad_cr = ref_pic_ptr->size_y_cr_pad;
00205
00206 if (apply_weights)
00207 {
00208 weight_cr[0] = wp_weight[list + currMB->list_offset][ref][1];
00209 weight_cr[1] = wp_weight[list + currMB->list_offset][ref][2];
00210 offset_cr[0] = wp_offset[list + currMB->list_offset][ref][1];
00211 offset_cr[1] = wp_offset[list + currMB->list_offset][ref][2];
00212 }
00213 }
00214
00215
00216 cand_x = center_x ;
00217 cand_y = center_y ;
00218 mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
00219
00220
00221 mcost += computeUniPred[dist_method](orig_pic, blocksize_y,blocksize_x, min_mcost - mcost,
00222 (cand_x << 2) + IMG_PAD_SIZE_TIMES4, (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
00223
00224 if (mcost < min_mcost)
00225 {
00226 min_mcost = mcost;
00227 best_x = cand_x;
00228 best_y = cand_y;
00229 }
00230
00231 iXMinNow = best_x;
00232 iYMinNow = best_y;
00233 if ((0 != pred_mv->mv_x) || (0 != pred_mv->mv_y))
00234 {
00235 cand_x = pic_pix_x;
00236 cand_y = pic_pix_y;
00237 SEARCH_ONE_PIXEL_HELPER
00238 }
00239
00240
00241
00242 if (min_mcost < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
00243 {
00244 for (m = 0; m < 4; m++)
00245 {
00246 cand_x = iXMinNow + Diamond_X[m];
00247 cand_y = iYMinNow + Diamond_Y[m];
00248 SEARCH_ONE_PIXEL_HELPER
00249 }
00250 mv->mv_x = (short) (best_x - pic_pix_x);
00251 mv->mv_y = (short) (best_y - pic_pix_y);
00252 return min_mcost;
00253 }
00254
00255
00256 for (m = 0; m < 4; m++)
00257 {
00258 cand_x = iXMinNow + Diamond_X[m];
00259 cand_y = iYMinNow + Diamond_Y[m];
00260 SEARCH_ONE_PIXEL_HELPER
00261 }
00262
00263
00264
00265 if ( (blocktype == 1 &&
00266 min_mcost > (SymmetricalCrossSearchThreshold1>>block_type_shift_factor[blocktype])) ||
00267 (min_mcost > (SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])) )
00268 {
00269 iXMinNow = best_x;
00270 iYMinNow = best_y;
00271
00272 for(i = 1; i <= search_range/2; i++)
00273 {
00274 search_step = (i<<1) - 1;
00275 cand_x = iXMinNow + search_step;
00276 cand_y = iYMinNow;
00277 SEARCH_ONE_PIXEL_HELPER
00278
00279 cand_x = iXMinNow - search_step;
00280 SEARCH_ONE_PIXEL_HELPER
00281
00282 cand_x = iXMinNow;
00283 cand_y = iYMinNow + search_step;
00284 SEARCH_ONE_PIXEL_HELPER
00285
00286 cand_y = iYMinNow - search_step;
00287 SEARCH_ONE_PIXEL_HELPER
00288 }
00289
00290
00291 iXMinNow = best_x;
00292 iYMinNow = best_y;
00293 for (m = 0; m < 6; m++)
00294 {
00295 cand_x = iXMinNow + Hexagon_X[m];
00296 cand_y = iYMinNow + Hexagon_Y[m];
00297 SEARCH_ONE_PIXEL_HELPER
00298 }
00299
00300 iXMinNow = best_x;
00301 iYMinNow = best_y;
00302 for(i = 1; i <= search_range/4; i++)
00303 {
00304 for (m = 0; m < 16; m++)
00305 {
00306 cand_x = iXMinNow + Big_Hexagon_X[m]*i;
00307 cand_y = iYMinNow + Big_Hexagon_Y[m]*i;
00308 SEARCH_ONE_PIXEL_HELPER
00309 }
00310 }
00311 }
00312
00313
00314 if (blocktype > 1)
00315 {
00316 cand_x = pic_pix_x + (smpUMHEX_pred_MV_uplayer_X/4);
00317 cand_y = pic_pix_y + (smpUMHEX_pred_MV_uplayer_Y/4);
00318 SEARCH_ONE_PIXEL_HELPER
00319 }
00320
00321 if(center_x != pic_pix_x || center_y != pic_pix_y)
00322 {
00323 cand_x = pic_pix_x;
00324 cand_y = pic_pix_y;
00325 SEARCH_ONE_PIXEL_HELPER
00326
00327 iXMinNow = best_x;
00328 iYMinNow = best_y;
00329
00330 for (m = 0; m < 4; m++)
00331 {
00332 cand_x = iXMinNow + Diamond_X[m];
00333 cand_y = iYMinNow + Diamond_Y[m];
00334 SEARCH_ONE_PIXEL_HELPER
00335 }
00336 }
00337
00338
00339
00340 if (min_mcost < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
00341 {
00342 iXMinNow = best_x;
00343 iYMinNow = best_y;
00344 for (m = 0; m < 4; m++)
00345 {
00346 cand_x = iXMinNow + Diamond_X[m];
00347 cand_y = iYMinNow + Diamond_Y[m];
00348 SEARCH_ONE_PIXEL_HELPER
00349 }
00350 mv->mv_x = (short) (best_x - pic_pix_x);
00351 mv->mv_y = (short) (best_y - pic_pix_y);
00352 return min_mcost;
00353 }
00354
00355
00356 for(i = 0; i < search_range; i++)
00357 {
00358 iXMinNow = best_x;
00359 iYMinNow = best_y;
00360 for (m = 0; m < 6; m++)
00361 {
00362 cand_x = iXMinNow + Hexagon_X[m];
00363 cand_y = iYMinNow + Hexagon_Y[m];
00364 SEARCH_ONE_PIXEL_HELPER
00365 }
00366
00367 if (best_x == iXMinNow && best_y == iYMinNow)
00368 {
00369 break;
00370 }
00371 }
00372
00373
00374 for(i = 0; i < search_range; i++)
00375 {
00376 iXMinNow = best_x;
00377 iYMinNow = best_y;
00378 for (m = 0; m < 4; m++)
00379 {
00380 cand_x = iXMinNow + Diamond_X[m];
00381 cand_y = iYMinNow + Diamond_Y[m];
00382 SEARCH_ONE_PIXEL_HELPER
00383 }
00384
00385
00386 if (best_x == iXMinNow && best_y == iYMinNow)
00387 {
00388 break;
00389 }
00390 }
00391
00392 mv->mv_x = (short) (best_x - pic_pix_x);
00393 mv->mv_y = (short) (best_y - pic_pix_y);
00394
00395 for (j=(pic_pix_y>>2); j < (pic_pix_y>>2) + (blocksize_y>>2); j++)
00396 {
00397 for (i=(pic_pix_x>>2); i < (pic_pix_x>>2) + (blocksize_x>>2); i++)
00398 {
00399 if(list == 0)
00400 {
00401 smpUMHEX_l0_cost[blocktype][j][i] = min_mcost;
00402 }
00403 else
00404 {
00405 smpUMHEX_l1_cost[blocktype][j][i] = min_mcost;
00406 }
00407 }
00408 }
00409
00410 return min_mcost;
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 int
00420 smpUMHEXFullSubPelBlockMotionSearch (imgpel* orig_pic,
00421 short ref,
00422 int list,
00423 int list_offset,
00424 int pic_pix_x,
00425 int pic_pix_y,
00426 int blocktype,
00427 MotionVector *pred_mv,
00428 MotionVector *mv,
00429 int search_pos2,
00430 int search_pos4,
00431 int min_mcost,
00432 int lambda_factor,
00433 int apply_weights
00434 )
00435 {
00436 int pos, best_pos, mcost;
00437
00438 int cand_mv_x, cand_mv_y;
00439
00440 int check_position0 = (!params->rdopt && img->type!=B_SLICE && ref==0 && blocktype==1 && mv->mv_x==0 && mv->mv_y==0);
00441 int blocksize_x = params->blc_size[blocktype][0];
00442 int blocksize_y = params->blc_size[blocktype][1];
00443 int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
00444 int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
00445 int max_pos2 = ( !start_me_refinement_hp ? imax(1,search_pos2) : search_pos2);
00446
00447 int cmv_x, cmv_y;
00448
00449 StorablePicture *ref_picture = listX[list + list_offset][ref];
00450
00451
00452 dist_method = Q_PEL + 3 * apply_weights;
00453
00454 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
00455
00456 img_width = ref_picture->size_x;
00457 img_height = ref_picture->size_y;
00458 width_pad = ref_picture->size_x_pad;
00459 height_pad = ref_picture->size_y_pad;
00460
00461 if (apply_weights)
00462 {
00463 weight_luma = wp_weight[list + list_offset][ref][0];
00464 offset_luma = wp_offset[list + list_offset][ref][0];
00465 }
00466
00467 if (ChromaMEEnable)
00468 {
00469 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
00470 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
00471 width_pad_cr = ref_picture->size_x_cr_pad;
00472 height_pad_cr = ref_picture->size_y_cr_pad;
00473
00474 if (apply_weights)
00475 {
00476 weight_cr[0] = wp_weight[list + list_offset][ref][1];
00477 weight_cr[1] = wp_weight[list + list_offset][ref][2];
00478 offset_cr[0] = wp_offset[list + list_offset][ref][1];
00479 offset_cr[1] = wp_offset[list + list_offset][ref][2];
00480 }
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490 for (best_pos = 0, pos = start_me_refinement_hp; pos < max_pos2; pos++)
00491 {
00492 cand_mv_x = mv->mv_x + (spiral_hpel_search_x[pos]);
00493 cand_mv_y = mv->mv_y + (spiral_hpel_search_y[pos]);
00494
00495
00496 mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00497
00498 if (mcost >= min_mcost) continue;
00499
00500 cmv_x = cand_mv_x + pic4_pix_x;
00501 cmv_y = cand_mv_y + pic4_pix_y;
00502
00503 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
00504
00505 if (pos==0 && check_position0)
00506 {
00507 mcost -= WEIGHTED_COST (lambda_factor, 16);
00508 }
00509
00510 if (mcost < min_mcost)
00511 {
00512 min_mcost = mcost;
00513 best_pos = pos;
00514 }
00515 if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
00516 {
00517 break;
00518 }
00519 }
00520
00521 if (best_pos)
00522 {
00523 mv->mv_x += (spiral_hpel_search_x [best_pos]);
00524 mv->mv_y += (spiral_hpel_search_y [best_pos]);
00525 }
00526
00527 if ((mv->mv_x == 0) && (mv->mv_y == 0) && (pred_mv->mv_x == 0 && pred_mv->mv_y == 0) &&
00528 (min_mcost < (SubPelThreshold1>>block_type_shift_factor[blocktype])) )
00529 {
00530 best_pos = 0;
00531 return min_mcost;
00532 }
00533
00534 if ( !start_me_refinement_qp )
00535 min_mcost = INT_MAX;
00536
00537
00538
00539
00540
00541
00542
00543
00544 for (best_pos = 0, pos = start_me_refinement_qp; pos < search_pos4; pos++)
00545 {
00546 cand_mv_x = mv->mv_x + spiral_search_x[pos];
00547 cand_mv_y = mv->mv_y + spiral_search_y[pos];
00548
00549
00550 mcost = MV_COST_SMP (lambda_factor, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00551
00552 if (mcost >= min_mcost) continue;
00553
00554 cmv_x = cand_mv_x + pic4_pix_x;
00555 cmv_y = cand_mv_y + pic4_pix_y;
00556
00557 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x, min_mcost - mcost, cmv_x, cmv_y);
00558
00559 if (mcost < min_mcost)
00560 {
00561 min_mcost = mcost;
00562 best_pos = pos;
00563 }
00564 if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
00565 {
00566 break;
00567 }
00568 }
00569
00570 if (best_pos)
00571 {
00572 mv->mv_x += spiral_search_x [best_pos];
00573 mv->mv_y += spiral_search_y [best_pos];
00574 }
00575
00576
00577 return min_mcost;
00578 }
00579
00580
00581
00582
00583
00584
00585
00586
00587 int
00588 smpUMHEXSubPelBlockMotionSearch (
00589 imgpel* orig_pic,
00590 short ref,
00591 int list,
00592 int list_offset,
00593 int pic_pix_x,
00594 int pic_pix_y,
00595 int blocktype,
00596 MotionVector *pred_mv,
00597 MotionVector *mv,
00598 int search_pos2,
00599 int search_pos4,
00600 int min_mcost,
00601 int lambda_factor,
00602 int apply_weights
00603 )
00604 {
00605 int mcost;
00606 int cand_mv_x, cand_mv_y;
00607
00608 StorablePicture *ref_picture = listX[list+list_offset][ref];
00609
00610 short mv_shift = 0;
00611 short blocksize_x = (short) params->blc_size[blocktype][0];
00612 short blocksize_y = (short) params->blc_size[blocktype][1];
00613 int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<<2);
00614 int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<<2);
00615
00616 int iXMinNow, iYMinNow;
00617 short dynamic_search_range, i, m;
00618 int currmv_x = 0, currmv_y = 0;
00619 int pred_frac_mv_x,pred_frac_mv_y,abort_search;
00620 int pred_frac_up_mv_x, pred_frac_up_mv_y;
00621
00622 dist_method = Q_PEL + 3 * apply_weights;
00623
00624 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
00625
00626 img_width = ref_pic_ptr->size_x;
00627 img_height = ref_pic_ptr->size_y;
00628 width_pad = ref_pic_ptr->size_x_pad;
00629 height_pad = ref_pic_ptr->size_y_pad;
00630
00631 if (apply_weights)
00632 {
00633 weight_luma = wp_weight[list + list_offset][ref][0];
00634 offset_luma = wp_offset[list + list_offset][ref][0];
00635 }
00636
00637 if (ChromaMEEnable)
00638 {
00639 ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
00640 ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
00641 width_pad_cr = ref_pic_ptr->size_x_cr_pad;
00642 height_pad_cr = ref_pic_ptr->size_y_cr_pad;
00643
00644 if (apply_weights)
00645 {
00646 weight_cr[0] = wp_weight[list + list_offset][ref][1];
00647 weight_cr[1] = wp_weight[list + list_offset][ref][2];
00648 offset_cr[0] = wp_offset[list + list_offset][ref][1];
00649 offset_cr[1] = wp_offset[list + list_offset][ref][2];
00650 }
00651 }
00652
00653 dynamic_search_range = 3;
00654 pred_frac_mv_x = (pred_mv->mv_x - mv->mv_x) % 4;
00655 pred_frac_mv_y = (pred_mv->mv_y - mv->mv_y) % 4;
00656
00657 pred_frac_up_mv_x = (smpUMHEX_pred_MV_uplayer_X - mv->mv_x) % 4;
00658 pred_frac_up_mv_y = (smpUMHEX_pred_MV_uplayer_Y - mv->mv_y) % 4;
00659
00660 memset(smpUMHEX_SearchState[0], 0,
00661 (2*dynamic_search_range+1)*(2*dynamic_search_range+1));
00662
00663 smpUMHEX_SearchState[dynamic_search_range][dynamic_search_range] = 1;
00664 if( !start_me_refinement_hp )
00665 {
00666 cand_mv_x = mv->mv_x;
00667 cand_mv_y = mv->mv_y;
00668 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00669 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00670 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00671 if (mcost < min_mcost)
00672 {
00673 min_mcost = mcost;
00674 currmv_x = cand_mv_x;
00675 currmv_y = cand_mv_y;
00676 }
00677 }
00678 else
00679 {
00680 currmv_x = mv->mv_x;
00681 currmv_y = mv->mv_y;
00682 }
00683
00684
00685
00686 if ( ((mv->mv_x) == 0) && ((mv->mv_y) == 0) &&
00687 (pred_frac_mv_x == 0 && pred_frac_up_mv_x == 0) &&
00688 (pred_frac_mv_y == 0 && pred_frac_up_mv_y == 0) &&
00689 (min_mcost < (SubPelThreshold1>>block_type_shift_factor[blocktype])) )
00690 {
00691 mv->mv_x = (short) currmv_x;
00692 mv->mv_y = (short) currmv_y;
00693 return min_mcost;
00694 }
00695
00696 if(pred_frac_mv_x || pred_frac_mv_y)
00697 {
00698 cand_mv_x = mv->mv_x + pred_frac_mv_x;
00699 cand_mv_y = mv->mv_y + pred_frac_mv_y;
00700 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00701 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00702 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00703
00704 smpUMHEX_SearchState[cand_mv_y -mv->mv_y + dynamic_search_range][cand_mv_x - mv->mv_x + dynamic_search_range] = 1;
00705 if (mcost < min_mcost)
00706 {
00707 min_mcost = mcost;
00708 currmv_x = cand_mv_x;
00709 currmv_y = cand_mv_y;
00710 }
00711 }
00712
00713
00714 for(i = 0; i < dynamic_search_range; i++)
00715 {
00716 abort_search = 1;
00717
00718 iXMinNow = currmv_x;
00719 iYMinNow = currmv_y;
00720 for (m = 0; m < 4; m++)
00721 {
00722 cand_mv_x = iXMinNow + Diamond_X[m];
00723 cand_mv_y = iYMinNow + Diamond_Y[m];
00724
00725 if(iabs(cand_mv_x - mv->mv_x) <= dynamic_search_range && iabs(cand_mv_y - mv->mv_y) <= dynamic_search_range)
00726 {
00727 if(!smpUMHEX_SearchState[cand_mv_y - mv->mv_y + dynamic_search_range][cand_mv_x - mv->mv_x + dynamic_search_range])
00728 {
00729 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00730 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00731 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00732
00733 smpUMHEX_SearchState[cand_mv_y - mv->mv_y + dynamic_search_range][cand_mv_x - mv->mv_x + dynamic_search_range] = 1;
00734
00735 if (mcost < min_mcost)
00736 {
00737 min_mcost = mcost;
00738 currmv_x = cand_mv_x;
00739 currmv_y = cand_mv_y;
00740 abort_search = 0;
00741 }
00742 if (min_mcost < (SubPelThreshold3>>block_type_shift_factor[blocktype]))
00743 {
00744 mv->mv_x = (short) currmv_x;
00745 mv->mv_y = (short) currmv_y;
00746 return min_mcost;
00747 }
00748 }
00749 }
00750 }
00751
00752 if (abort_search)
00753 {
00754 break;
00755 }
00756 }
00757
00758 mv->mv_x = (short) currmv_x;
00759 mv->mv_y = (short) currmv_y;
00760 return min_mcost;
00761 }
00762
00763
00764 int
00765 smpUMHEXSubPelBlockME (imgpel* orig_pic,
00766 short ref,
00767 int list,
00768 int list_offset,
00769 int pic_pix_x,
00770 int pic_pix_y,
00771 int blocktype,
00772 MotionVector *pred_mv,
00773 MotionVector *mv,
00774 int search_pos2,
00775 int search_pos4,
00776 int min_mcost,
00777 int* lambda_factor,
00778 int apply_weights
00779 )
00780 {
00781 if(blocktype > 1)
00782 {
00783 min_mcost = smpUMHEXSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y,
00784 blocktype, pred_mv, mv, 9, 9, min_mcost, lambda_factor[Q_PEL], apply_weights);
00785 }
00786 else
00787 {
00788 min_mcost = smpUMHEXFullSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y,
00789 blocktype, pred_mv, mv, 9, 9, min_mcost, lambda_factor[Q_PEL], apply_weights);
00790 }
00791
00792 return min_mcost;
00793 }
00794
00795
00796
00797
00798
00799
00800
00801
00802 int
00803 smpUMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB,
00804 imgpel* cur_pic,
00805 short ref,
00806 int list,
00807 char ***refPic,
00808 short ****tmp_mv,
00809 int pic_pix_x,
00810 int pic_pix_y,
00811 int blocktype,
00812 MotionVector *pred_mv1,
00813 MotionVector *pred_mv2,
00814 MotionVector *mv1,
00815 MotionVector *mv2,
00816 int search_range,
00817 int min_mcost,
00818 int iteration_no,
00819 int lambda_factor,
00820 int apply_weights
00821 )
00822 {
00823 int mvshift = 2;
00824
00825 int search_step, iYMinNow, iXMinNow;
00826 int i, m;
00827 int cand_x, cand_y, mcost;
00828 int blocksize_y = params->blc_size[blocktype][1];
00829 int blocksize_x = params->blc_size[blocktype][0];
00830 int pred_x1 = (pic_pix_x << 2) + pred_mv1->mv_x;
00831 int pred_y1 = (pic_pix_y << 2) + pred_mv1->mv_y;
00832 int pred_x2 = (pic_pix_x << 2) + pred_mv2->mv_x;
00833 int pred_y2 = (pic_pix_y << 2) + pred_mv2->mv_y;
00834 short center2_x = pic_pix_x + mv1->mv_x;
00835 short center2_y = pic_pix_y + mv1->mv_y;
00836 short center1_x = pic_pix_x + mv2->mv_x;
00837 short center1_y = pic_pix_y + mv2->mv_y;
00838 int best_x = center2_x;
00839 int best_y = center2_y;
00840
00841 short offset1 = (apply_weights ? (list == 0? wp_offset[currMB->list_offset ][ref][0]: wp_offset[currMB->list_offset + 1][0 ][ref]) : 0);
00842 short offset2 = (apply_weights ? (list == 0? wp_offset[currMB->list_offset + 1][ref][0]: wp_offset[currMB->list_offset ][0 ][ref]) : 0);
00843
00844 ref_pic1_sub.luma = listX[list + currMB->list_offset][ref]->p_curr_img_sub;
00845 ref_pic2_sub.luma = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->p_curr_img_sub;
00846
00847 img_width = listX[list + currMB->list_offset][ref]->size_x;
00848 img_height = listX[list + currMB->list_offset][ref]->size_y;
00849 width_pad = listX[list + currMB->list_offset][ref]->size_x_pad;
00850 height_pad = listX[list + currMB->list_offset][ref]->size_y_pad;
00851
00852 if (apply_weights)
00853 {
00854 weight1 = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][0] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][0];
00855 weight2 = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][0] : wbp_weight[currMB->list_offset ][0 ][ref][0];
00856 offsetBi=(offset1 + offset2 + 1)>>1;
00857 computeBiPred = computeBiPredSAD2;
00858 }
00859 else
00860 {
00861 weight1 = 1<<luma_log_weight_denom;
00862 weight2 = 1<<luma_log_weight_denom;
00863 offsetBi = 0;
00864 computeBiPred = computeBiPredSAD1;
00865 }
00866
00867 if (ChromaMEEnable )
00868 {
00869 ref_pic1_sub.crcb[0] = listX[list + currMB->list_offset][ref]->imgUV_sub[0];
00870 ref_pic1_sub.crcb[1] = listX[list + currMB->list_offset][ref]->imgUV_sub[1];
00871 ref_pic2_sub.crcb[0] = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->imgUV_sub[0];
00872 ref_pic2_sub.crcb[1] = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->imgUV_sub[1];
00873 width_pad_cr = listX[list + currMB->list_offset][ref]->size_x_cr_pad;
00874 height_pad_cr = listX[list + currMB->list_offset][ref]->size_y_cr_pad;
00875 if (apply_weights)
00876 {
00877 weight1_cr[0] = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][1] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][1];
00878 weight1_cr[1] = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][2] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][2];
00879 weight2_cr[0] = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][1] : wbp_weight[currMB->list_offset ][0 ][ref][1];
00880 weight2_cr[1] = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][2] : wbp_weight[currMB->list_offset ][0 ][ref][2];
00881 offsetBi_cr[0] = (list == 0)
00882 ? (wp_offset[currMB->list_offset ][ref][1] + wp_offset[currMB->list_offset + LIST_1][ref][1] + 1) >> 1
00883 : (wp_offset[currMB->list_offset + LIST_1][0 ][1] + wp_offset[currMB->list_offset ][0 ][1] + 1) >> 1;
00884 offsetBi_cr[1] = (list == 0)
00885 ? (wp_offset[currMB->list_offset ][ref][2] + wp_offset[currMB->list_offset + LIST_1][ref][2] + 1) >> 1
00886 : (wp_offset[currMB->list_offset + LIST_1][0 ][2] + wp_offset[currMB->list_offset ][0 ][2] + 1) >> 1;
00887 }
00888 else
00889 {
00890 weight1_cr[0] = 1<<chroma_log_weight_denom;
00891 weight1_cr[1] = 1<<chroma_log_weight_denom;
00892 weight2_cr[0] = 1<<chroma_log_weight_denom;
00893 weight2_cr[1] = 1<<chroma_log_weight_denom;
00894 offsetBi_cr[0] = 0;
00895 offsetBi_cr[1] = 0;
00896 }
00897 }
00898
00899
00900 cand_x = center2_x ;
00901 cand_y = center2_y ;
00902 mcost = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
00903 mcost += MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x2, pred_y2);
00904
00905 mcost += computeBiPred(cur_pic,
00906 blocksize_y, blocksize_x, INT_MAX,
00907 (center1_x << 2) + IMG_PAD_SIZE_TIMES4,
00908 (center1_y << 2) + IMG_PAD_SIZE_TIMES4,
00909 (cand_x << 2) + IMG_PAD_SIZE_TIMES4,
00910 (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
00911
00912 if (mcost < min_mcost)
00913 {
00914 min_mcost = mcost;
00915 best_x = cand_x;
00916 best_y = cand_y;
00917 }
00918
00919 iXMinNow = best_x;
00920 iYMinNow = best_y;
00921 if (0 != pred_mv1->mv_x || 0 != pred_mv1->mv_y || 0 != pred_mv2->mv_x || 0 != pred_mv2->mv_y)
00922 {
00923 cand_x = pic_pix_x;
00924 cand_y = pic_pix_y;
00925 SEARCH_ONE_PIXEL_BIPRED_HELPER;
00926 }
00927
00928
00929
00930 if ((min_mcost<<3) < (ConvergeThreshold>>(block_type_shift_factor[blocktype])))
00931 {
00932 for (m = 0; m < 4; m++)
00933 {
00934 cand_x = iXMinNow + Diamond_X[m];
00935 cand_y = iYMinNow + Diamond_Y[m];
00936 SEARCH_ONE_PIXEL_BIPRED_HELPER;
00937 }
00938 mv1->mv_x = best_x - pic_pix_x;
00939 mv1->mv_y = best_y - pic_pix_y;
00940 return min_mcost;
00941 }
00942
00943
00944 for (m = 0; m < 4; m++)
00945 {
00946 cand_x = iXMinNow + Diamond_X[m];
00947 cand_y = iYMinNow + Diamond_Y[m];
00948 SEARCH_ONE_PIXEL_BIPRED_HELPER;
00949 }
00950
00951
00952
00953 if ((blocktype == 1 &&
00954 (min_mcost<<2) > (SymmetricalCrossSearchThreshold1>>block_type_shift_factor[blocktype])) ||
00955 ((min_mcost<<2) > (SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])))
00956 {
00957 iXMinNow = best_x;
00958 iYMinNow = best_y;
00959
00960 for (i = 1; i <= search_range / 2; i++)
00961 {
00962 search_step = (i<<1) - 1;
00963 cand_x = iXMinNow + search_step;
00964 cand_y = iYMinNow;
00965 SEARCH_ONE_PIXEL_BIPRED_HELPER
00966
00967 cand_x = iXMinNow - search_step;
00968 SEARCH_ONE_PIXEL_BIPRED_HELPER
00969
00970 cand_x = iXMinNow;
00971 cand_y = iYMinNow + search_step;
00972 SEARCH_ONE_PIXEL_BIPRED_HELPER
00973
00974 cand_y = iYMinNow - search_step;
00975 SEARCH_ONE_PIXEL_BIPRED_HELPER
00976 }
00977
00978
00979 iXMinNow = best_x;
00980 iYMinNow = best_y;
00981 for (m = 0; m < 6; m++)
00982 {
00983 cand_x = iXMinNow + Hexagon_X[m];
00984 cand_y = iYMinNow + Hexagon_Y[m];
00985 SEARCH_ONE_PIXEL_BIPRED_HELPER
00986 }
00987
00988 iXMinNow = best_x;
00989 iYMinNow = best_y;
00990 for(i = 1; i <= search_range / 4; i++)
00991 {
00992 for (m = 0; m < 16; m++)
00993 {
00994 cand_x = iXMinNow + Big_Hexagon_X[m] * i;
00995 cand_y = iYMinNow + Big_Hexagon_Y[m] * i;
00996 SEARCH_ONE_PIXEL_BIPRED_HELPER
00997 }
00998 }
00999 }
01000
01001
01002 if (blocktype > 1)
01003 {
01004 cand_x = pic_pix_x + (smpUMHEX_pred_MV_uplayer_X / 4);
01005 cand_y = pic_pix_y + (smpUMHEX_pred_MV_uplayer_Y / 4);
01006 SEARCH_ONE_PIXEL_BIPRED_HELPER
01007 }
01008
01009 if(center2_x != pic_pix_x || center2_y != pic_pix_y)
01010 {
01011 cand_x = pic_pix_x;
01012 cand_y = pic_pix_y;
01013 SEARCH_ONE_PIXEL_BIPRED_HELPER
01014
01015 iXMinNow = best_x;
01016 iYMinNow = best_y;
01017
01018 for (m = 0; m < 4; m++)
01019 {
01020 cand_x = iXMinNow + Diamond_X[m];
01021 cand_y = iYMinNow + Diamond_Y[m];
01022 SEARCH_ONE_PIXEL_BIPRED_HELPER
01023 }
01024 }
01025
01026
01027
01028 if ((min_mcost<<2) < (ConvergeThreshold>>block_type_shift_factor[blocktype]))
01029 {
01030 iXMinNow = best_x;
01031 iYMinNow = best_y;
01032 for (m = 0; m < 4; m++)
01033 {
01034 cand_x = iXMinNow + Diamond_X[m];
01035 cand_y = iYMinNow + Diamond_Y[m];
01036 SEARCH_ONE_PIXEL_BIPRED_HELPER
01037 }
01038 mv1->mv_x = (short) (best_x - pic_pix_x);
01039 mv1->mv_y = (short) (best_y - pic_pix_y);
01040 return min_mcost;
01041 }
01042
01043
01044 for (i = 0; i < search_range; i++)
01045 {
01046 iXMinNow = best_x;
01047 iYMinNow = best_y;
01048 for (m = 0; m < 6; m++)
01049 {
01050 cand_x = iXMinNow + Hexagon_X[m];
01051 cand_y = iYMinNow + Hexagon_Y[m];
01052 SEARCH_ONE_PIXEL_BIPRED_HELPER
01053 }
01054
01055 if (best_x == iXMinNow && best_y == iYMinNow)
01056 {
01057 break;
01058 }
01059 }
01060
01061
01062 for (i = 0; i < search_range; i++)
01063 {
01064 iXMinNow = best_x;
01065 iYMinNow = best_y;
01066 for (m = 0; m < 4; m++)
01067 {
01068 cand_x = iXMinNow + Diamond_X[m];
01069 cand_y = iYMinNow + Diamond_Y[m];
01070 SEARCH_ONE_PIXEL_BIPRED_HELPER
01071 }
01072
01073
01074 if (best_x == iXMinNow && best_y == iYMinNow)
01075 {
01076 break;
01077 }
01078 }
01079
01080 mv1->mv_x = (short) (best_x - pic_pix_x);
01081 mv1->mv_y = (short) (best_y - pic_pix_y);
01082 return min_mcost;
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
01092 void smpUMHEX_decide_intrabk_SAD()
01093 {
01094 if (img->type != I_SLICE)
01095 {
01096 if (img->pix_x == 0 && img->pix_y == 0)
01097 {
01098 smpUMHEX_flag_intra_SAD = 0;
01099 }
01100 else if (img->pix_x == 0)
01101 {
01102 smpUMHEX_flag_intra_SAD = smpUMHEX_flag_intra[(img->pix_x)>>4];
01103 }
01104 else if (img->pix_y == 0)
01105 {
01106 smpUMHEX_flag_intra_SAD = smpUMHEX_flag_intra[((img->pix_x)>>4)-1];
01107 }
01108 else
01109 {
01110 smpUMHEX_flag_intra_SAD = ((smpUMHEX_flag_intra[(img->pix_x)>>4])||
01111 (smpUMHEX_flag_intra[((img->pix_x)>>4)-1])||
01112 (smpUMHEX_flag_intra[((img->pix_x)>>4)+1])) ;
01113 }
01114 }
01115 return;
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125 void smpUMHEX_skip_intrabk_SAD(int best_mode, int ref_max)
01126 {
01127 short i, j, k;
01128
01129 if (img->number > 0)
01130 {
01131 smpUMHEX_flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1 : 0;
01132 }
01133
01134 if (img->type != I_SLICE && (best_mode == 9 || best_mode == 10))
01135 {
01136 for (i=0; i < 4; i++)
01137 {
01138 for (j=0; j < 4; j++)
01139 {
01140 for (k=0; k < 9;k++)
01141 {
01142 smpUMHEX_l0_cost[k][j][i] = 0;
01143 smpUMHEX_l1_cost[k][j][i] = 0;
01144 }
01145 }
01146 }
01147 }
01148 return;
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158 void smpUMHEX_setup(short ref,
01159 int list,
01160 int block_y,
01161 int block_x,
01162 int blocktype,
01163 short ******all_mv)
01164 {
01165 if (blocktype > 6)
01166 {
01167 smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][5][block_y][block_x][0];
01168 smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][5][block_y][block_x][1];
01169 }
01170 else if (blocktype > 4)
01171 {
01172 smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][4][block_y][block_x][0];
01173 smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][4][block_y][block_x][1];
01174 }
01175 else if (blocktype == 4)
01176 {
01177 smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][2][block_y][block_x][0];
01178 smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][2][block_y][block_x][1];
01179 }
01180 else if (blocktype > 1)
01181 {
01182 smpUMHEX_pred_MV_uplayer_X = all_mv[list][ref][1][block_y][block_x][0];
01183 smpUMHEX_pred_MV_uplayer_Y = all_mv[list][ref][1][block_y][block_x][1];
01184 }
01185
01186 if (blocktype > 1)
01187 {
01188 if (blocktype > 6)
01189 {
01190 smpUMHEX_pred_SAD_uplayer = (list==1) ?
01191 (smpUMHEX_l1_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
01192 : (smpUMHEX_l0_cost[5][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
01193 smpUMHEX_pred_SAD_uplayer /= 2;
01194 }
01195 else if (blocktype > 4)
01196 {
01197 smpUMHEX_pred_SAD_uplayer = (list==1) ?
01198 (smpUMHEX_l1_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
01199 : (smpUMHEX_l0_cost[4][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
01200 smpUMHEX_pred_SAD_uplayer /= 2;
01201 }
01202 else if (blocktype == 4)
01203 {
01204 smpUMHEX_pred_SAD_uplayer = (list==1) ?
01205 (smpUMHEX_l1_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
01206 : (smpUMHEX_l0_cost[2][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
01207 smpUMHEX_pred_SAD_uplayer /= 2;
01208 }
01209 else
01210 {
01211 smpUMHEX_pred_SAD_uplayer = (list==1) ?
01212 (smpUMHEX_l1_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x])
01213 : (smpUMHEX_l0_cost[1][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
01214 smpUMHEX_pred_SAD_uplayer /= 2;
01215 }
01216
01217 smpUMHEX_pred_SAD_uplayer = smpUMHEX_flag_intra_SAD ? 0 : smpUMHEX_pred_SAD_uplayer;
01218 }
01219 }
01220