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_umhex.h"
00031 #include "refbuf.h"
00032 #include "mb_access.h"
00033 #include "image.h"
00034 #include "enc_statistics.h"
00035 #include "me_distortion.h"
00036 #include "mv-search.h"
00037
00038 #define Q_BITS 15
00039 #define MIN_IMG_WIDTH 176
00040 extern int* byte_abs;
00041
00042 extern short* spiral_search_x;
00043 extern short* spiral_search_y;
00044
00045
00046 static const int Diamond_x[4] = {-1, 0, 1, 0};
00047 static const int Diamond_y[4] = {0, 1, 0, -1};
00048 static const int Hexagon_x[6] = {2, 1, -1, -2, -1, 1};
00049 static const int Hexagon_y[6] = {0, -2, -2, 0, 2, 2};
00050 static const int Big_Hexagon_x[16] = {0,-2, -4,-4,-4, -4, -4, -2, 0, 2, 4, 4, 4, 4, 4, 2};
00051 static const int Big_Hexagon_y[16] = {4, 3, 2, 1, 0, -1, -2, -3, -4, -3, -2, -1, 0, 1, 2, 3};
00052
00053
00054 static int pred_MV_ref_flag;
00055 static int dist_method;
00056 static StorablePicture *ref_pic_ptr;
00057
00058 static const int Multi_Ref_Thd[8] = {0, 300, 120, 120, 60, 30, 30, 15};
00059 static const int Big_Hexagon_Thd[8] = {0, 3000, 1500, 1500, 800, 400, 400, 200};
00060 static const int Median_Pred_Thd[8] = {0, 750, 350, 350, 170, 80, 80, 40};
00061 static const int Threshold_DSR[8] = {0, 2200, 1000, 1000, 500, 250, 250, 120};
00062
00063 static int BlockType_LUT[4][4];
00064 static int Median_Pred_Thd_MB[8];
00065 static int Big_Hexagon_Thd_MB[8];
00066 static int Multi_Ref_Thd_MB[8];
00067
00068 extern const int quant_coef[6][4][4];
00069
00070
00071 void UMHEX_DefineThreshold()
00072 {
00073 AlphaFourth_1[1] = 0.01f;
00074 AlphaFourth_1[2] = 0.01f;
00075 AlphaFourth_1[3] = 0.01f;
00076 AlphaFourth_1[4] = 0.02f;
00077 AlphaFourth_1[5] = 0.03f;
00078 AlphaFourth_1[6] = 0.03f;
00079 AlphaFourth_1[7] = 0.04f;
00080
00081 AlphaFourth_2[1] = 0.06f;
00082 AlphaFourth_2[2] = 0.07f;
00083 AlphaFourth_2[3] = 0.07f;
00084 AlphaFourth_2[4] = 0.08f;
00085 AlphaFourth_2[5] = 0.12f;
00086 AlphaFourth_2[6] = 0.11f;
00087 AlphaFourth_2[7] = 0.15f;
00088
00089 UMHEX_DefineThresholdMB();
00090
00091 BlockType_LUT[0][0] = 7;
00092 BlockType_LUT[0][1] = 6;
00093 BlockType_LUT[1][0] = 5;
00094 BlockType_LUT[1][1] = 4;
00095 BlockType_LUT[1][3] = 3;
00096 BlockType_LUT[3][1] = 2;
00097 BlockType_LUT[3][3] = 1;
00098
00099 return;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 void UMHEX_DefineThresholdMB()
00111 {
00112 int gb_qp_per = (params->qp[0][P_SLICE])/6;
00113 int gb_qp_rem = (params->qp[0][P_SLICE])%6;
00114
00115 int gb_q_bits = Q_BITS+gb_qp_per;
00116 int gb_qp_const,Thresh4x4;
00117
00118 float Quantize_step;
00119 int i;
00120
00121 float scale_factor = (float)((1-params->UMHexScale*0.1)+params->UMHexScale*0.1*(img->width/MIN_IMG_WIDTH));
00122
00123 float QP_factor = (float)((1.0-0.90*(params->qp[0][P_SLICE]/51.0f)));
00124
00125 gb_qp_const=(1<<gb_q_bits)/6;
00126 Thresh4x4 = ((1<<gb_q_bits) - gb_qp_const)/quant_coef[gb_qp_rem][0][0];
00127 Quantize_step = Thresh4x4/(4*5.61f)*2.0f*scale_factor;
00128 Bsize[7]=(16*16)*Quantize_step;
00129
00130 Bsize[6]=Bsize[7]*4;
00131 Bsize[5]=Bsize[7]*4;
00132 Bsize[4]=Bsize[5]*4;
00133 Bsize[3]=Bsize[4]*4;
00134 Bsize[2]=Bsize[4]*4;
00135 Bsize[1]=Bsize[2]*4;
00136
00137 for(i=1;i<8;i++)
00138 {
00139
00140 Median_Pred_Thd_MB[i] = (int) (Median_Pred_Thd[i]* scale_factor*QP_factor);
00141
00142 Big_Hexagon_Thd_MB[i] = (int) (Big_Hexagon_Thd[i]* scale_factor*QP_factor);
00143
00144 Multi_Ref_Thd_MB[i] = (int) (Multi_Ref_Thd[i] * scale_factor*QP_factor);
00145
00146 Threshold_DSR_MB[i] = (int) (Threshold_DSR[i] * scale_factor*QP_factor);
00147 }
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 int UMHEX_get_mem()
00157 {
00158 int memory_size = 0;
00159 if (NULL==(flag_intra = calloc ((img->width>>4)+1,sizeof(byte)))) no_mem_exit("UMHEX_get_mem: flag_intra");
00160
00161 memory_size += get_mem2D(&McostState, 2*params->search_range+1, 2*params->search_range+1);
00162 memory_size += get_mem4Dint(&(fastme_ref_cost), img->max_num_references, 9, 4, 4);
00163 memory_size += get_mem3Dint(&(fastme_l0_cost), 9, img->height/4, img->width/4);
00164 memory_size += get_mem3Dint(&(fastme_l1_cost), 9, img->height/4, img->width/4);
00165 memory_size += get_mem2D(&SearchState,7,7);
00166 memory_size += get_mem2Dint(&(fastme_best_cost), 7, img->width/4);
00167 if(params->BiPredMotionEstimation == 1)
00168 {
00169 memory_size += get_mem3Dint(&(fastme_l0_cost_bipred), 9, img->height/4, img->width/4);
00170 memory_size += get_mem3Dint(&(fastme_l1_cost_bipred), 9, img->height/4, img->width/4);
00171 }
00172
00173 return memory_size;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 void UMHEX_free_mem()
00183 {
00184 free_mem2D(McostState);
00185 free_mem4Dint(fastme_ref_cost);
00186 free_mem3Dint(fastme_l0_cost );
00187 free_mem3Dint(fastme_l1_cost);
00188 free_mem2D(SearchState);
00189 free_mem2Dint(fastme_best_cost);
00190 free (flag_intra);
00191 if(params->BiPredMotionEstimation == 1)
00192 {
00193 free_mem3Dint(fastme_l0_cost_bipred);
00194 free_mem3Dint(fastme_l1_cost_bipred);
00195 }
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int
00229 UMHEXIntegerPelBlockMotionSearch (Macroblock *currMB,
00230 imgpel *orig_pic,
00231 short ref,
00232 int list,
00233 char ***refPic,
00234 short ****tmp_mv,
00235 int pic_pix_x,
00236 int pic_pix_y,
00237 int blocktype,
00238 MotionVector *pred_mv,
00239 MotionVector *mv,
00240 int search_range,
00241 int min_mcost,
00242 int lambda_factor,
00243 int apply_weights
00244 )
00245 {
00246 int mvshift = 2;
00247 int blocksize_y = params->blc_size[blocktype][1];
00248 int blocksize_x = params->blc_size[blocktype][0];
00249 int pred_x = (pic_pix_x << mvshift) + pred_mv->mv_x;
00250 int pred_y = (pic_pix_y << mvshift) + pred_mv->mv_y;
00251 int center_x = pic_pix_x + mv->mv_x;
00252 int center_y = pic_pix_y + mv->mv_y;
00253 int best_x = 0, best_y = 0;
00254 int search_step, iYMinNow, iXMinNow;
00255 int pos, cand_x, cand_y, mcost;
00256 int i,m,j;
00257 float betaFourth_1,betaFourth_2;
00258 int temp_Big_Hexagon_x[16];
00259 int temp_Big_Hexagon_y[16];
00260 short mb_x = pic_pix_x - img->opix_x;
00261 short mb_y = pic_pix_y - img->opix_y;
00262 short pic_pix_x2 = pic_pix_x >> 2;
00263 short block_x = (mb_x >> 2);
00264 short block_y = (mb_y >> 2);
00265 int ET_Thred = Median_Pred_Thd_MB[blocktype];
00266 int *SAD_prediction = fastme_best_cost[blocktype-1];
00267
00268
00269 dist_method = F_PEL + 3 * apply_weights;
00270
00271 ref_pic_ptr = listX[list+currMB->list_offset][ref];
00272
00273
00274
00275 ref_pic_sub.luma = ref_pic_ptr->p_curr_img_sub;
00276
00277 img_width = ref_pic_ptr->size_x;
00278 img_height = ref_pic_ptr->size_y;
00279 width_pad = ref_pic_ptr->size_x_pad;
00280 height_pad = ref_pic_ptr->size_y_pad;
00281
00282 if (apply_weights)
00283 {
00284 weight_luma = wp_weight[list + currMB->list_offset][ref][0];
00285 offset_luma = wp_offset[list + currMB->list_offset][ref][0];
00286 }
00287
00288 if (ChromaMEEnable)
00289 {
00290 ref_pic_sub.crcb[0] = ref_pic_ptr->imgUV_sub[0];
00291 ref_pic_sub.crcb[1] = ref_pic_ptr->imgUV_sub[1];
00292 width_pad_cr = ref_pic_ptr->size_x_cr_pad;
00293 height_pad_cr = ref_pic_ptr->size_y_cr_pad;
00294
00295 if (apply_weights)
00296 {
00297 weight_cr[0] = wp_weight[list + currMB->list_offset][ref][1];
00298 weight_cr[1] = wp_weight[list + currMB->list_offset][ref][2];
00299 offset_cr[0] = wp_offset[list + currMB->list_offset][ref][1];
00300 offset_cr[1] = wp_offset[list + currMB->list_offset][ref][2];
00301 }
00302 }
00303
00304
00305 memset(McostState[0],0,(2*params->search_range+1)*(2*params->search_range+1));
00306
00307
00308
00309 cand_x = center_x ;
00310 cand_y = center_y ;
00311 mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
00312
00313 mcost += computeUniPred[dist_method](orig_pic, blocksize_y,blocksize_x, min_mcost - mcost,
00314 (cand_x << 2) + IMG_PAD_SIZE_TIMES4, (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
00315
00316 McostState[search_range][search_range] = 1;
00317 if (mcost < min_mcost)
00318 {
00319 min_mcost = mcost;
00320 best_x = cand_x;
00321 best_y = cand_y;
00322 }
00323
00324 iXMinNow = best_x;
00325 iYMinNow = best_y;
00326 for (m = 0; m < 4; m++)
00327 {
00328 cand_x = iXMinNow + Diamond_x[m];
00329 cand_y = iYMinNow + Diamond_y[m];
00330 SEARCH_ONE_PIXEL
00331 }
00332
00333 if(center_x != pic_pix_x || center_y != pic_pix_y)
00334 {
00335 cand_x = pic_pix_x ;
00336 cand_y = pic_pix_y ;
00337 SEARCH_ONE_PIXEL
00338
00339 iXMinNow = best_x;
00340 iYMinNow = best_y;
00341 for (m = 0; m < 4; m++)
00342 {
00343 cand_x = iXMinNow + Diamond_x[m];
00344 cand_y = iYMinNow + Diamond_y[m];
00345 SEARCH_ONE_PIXEL
00346 }
00347 }
00348
00349
00350 if(ref>0 && img->structure == FRAME && min_mcost > ET_Thred && SAD_prediction[pic_pix_x2]<Multi_Ref_Thd_MB[blocktype])
00351 goto terminate_step;
00352
00353
00354 if( min_mcost < ET_Thred)
00355 {
00356 goto terminate_step;
00357 }
00358 else
00359 {
00360
00361 UMHEX_setup(ref, list, block_y, block_x, blocktype, img->all_mv );
00362 ET_Thred = Big_Hexagon_Thd_MB[blocktype];
00363
00364
00365
00366
00367 if (pred_SAD == 0)
00368 {
00369 betaFourth_1=0;
00370 betaFourth_2=0;
00371 }
00372 else
00373 {
00374 betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
00375 betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
00376
00377 }
00378
00379 }
00380
00381
00382 if(blocktype>1)
00383 {
00384 cand_x = pic_pix_x + (pred_MV_uplayer[0]/4);
00385 cand_y = pic_pix_y + (pred_MV_uplayer[1]/4);
00386 SEARCH_ONE_PIXEL
00387 }
00388
00389
00390
00391 if(pred_MV_ref_flag == 1)
00392 {
00393 cand_x = pic_pix_x + (pred_MV_ref[0]/4);
00394 cand_y = pic_pix_y + (pred_MV_ref[1]/4);
00395 SEARCH_ONE_PIXEL
00396 }
00397
00398 iXMinNow = best_x;
00399 iYMinNow = best_y;
00400 for (m = 0; m < 4; m++)
00401 {
00402 cand_x = iXMinNow + Diamond_x[m];
00403 cand_y = iYMinNow + Diamond_y[m];
00404 SEARCH_ONE_PIXEL
00405 }
00406
00407
00408 EARLY_TERMINATION
00409
00410 if(blocktype>6)
00411 goto fourth_1_step;
00412 else
00413 goto sec_step;
00414
00415 sec_step:
00416 iXMinNow = best_x;
00417 iYMinNow = best_y;
00418
00419 for(i = 1; i < search_range; i+=2)
00420 {
00421 search_step = i;
00422 cand_x = iXMinNow + search_step;
00423 cand_y = iYMinNow ;
00424 SEARCH_ONE_PIXEL
00425 cand_x = iXMinNow - search_step;
00426 cand_y = iYMinNow ;
00427 SEARCH_ONE_PIXEL
00428 }
00429 for(i = 1; i < (search_range/2);i+=2)
00430 {
00431 search_step = i;
00432 cand_x = iXMinNow ;
00433 cand_y = iYMinNow + search_step;
00434 SEARCH_ONE_PIXEL
00435 cand_x = iXMinNow ;
00436 cand_y = iYMinNow - search_step;
00437 SEARCH_ONE_PIXEL
00438 }
00439
00440
00441
00442 EARLY_TERMINATION
00443
00444 iXMinNow = best_x;
00445 iYMinNow = best_y;
00446
00447
00448
00449 for(pos=1;pos<25;pos++)
00450 {
00451 cand_x = iXMinNow + spiral_search_x[pos];
00452 cand_y = iYMinNow + spiral_search_y[pos];
00453 SEARCH_ONE_PIXEL
00454 }
00455
00456
00457 EARLY_TERMINATION
00458
00459
00460 memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
00461 memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
00462 for(i=1;i<=(search_range/4); i++)
00463 {
00464
00465 for (m = 0; m < 16; m++)
00466 {
00467 cand_x = iXMinNow + temp_Big_Hexagon_x[m];
00468 cand_y = iYMinNow + temp_Big_Hexagon_y[m];
00469 temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
00470 temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];
00471
00472 SEARCH_ONE_PIXEL
00473 }
00474
00475 if(min_mcost < ET_Thred)
00476 {
00477 goto terminate_step;
00478 }
00479 }
00480
00481
00482
00483
00484 fourth_1_step:
00485 for(i = 0; i < search_range; i++)
00486 {
00487 iXMinNow = best_x;
00488 iYMinNow = best_y;
00489 for (m = 0; m < 6; m++)
00490 {
00491 cand_x = iXMinNow + Hexagon_x[m];
00492 cand_y = iYMinNow + Hexagon_y[m];
00493 SEARCH_ONE_PIXEL
00494 }
00495
00496 if (best_x == iXMinNow && best_y == iYMinNow)
00497 {
00498 break;
00499 }
00500 }
00501 fourth_2_step:
00502
00503 for(i = 0; i < search_range; i++)
00504 {
00505 iXMinNow = best_x;
00506 iYMinNow = best_y;
00507 for (m = 0; m < 4; m++)
00508 {
00509 cand_x = iXMinNow + Diamond_x[m];
00510 cand_y = iYMinNow + Diamond_y[m];
00511 SEARCH_ONE_PIXEL
00512 }
00513 if(best_x == iXMinNow && best_y == iYMinNow)
00514 break;
00515 }
00516
00517 terminate_step:
00518
00519
00520
00521 for (i=0; i < (blocksize_x>>2); i++)
00522 {
00523 for (j=0; j < (blocksize_y>>2); j++)
00524 {
00525 if(list == 0)
00526 {
00527 fastme_ref_cost[ref][blocktype][block_y+j][block_x+i] = min_mcost;
00528 if (ref==0)
00529 fastme_l0_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
00530 }
00531 else
00532 {
00533 fastme_l1_cost[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
00534 }
00535 }
00536 }
00537
00538 if ((ref==0) || (SAD_prediction[pic_pix_x2] > min_mcost))
00539 SAD_prediction[pic_pix_x2] = min_mcost;
00540
00541 mv->mv_x = (short) (best_x - pic_pix_x);
00542 mv->mv_y = (short) (best_y - pic_pix_y);
00543 return min_mcost;
00544 }
00545
00546
00547 int
00548 UMHEXSubPelBlockMotionSearch (imgpel* orig_pic,
00549 short ref,
00550 int list,
00551 int list_offset,
00552 int pic_pix_x,
00553 int pic_pix_y,
00554 int blocktype,
00555 MotionVector *pred_mv,
00556 MotionVector *mv,
00557 int search_pos2,
00558 int search_pos4,
00559 int min_mcost,
00560 int lambda_factor,
00561 int apply_weights
00562 )
00563 {
00564 static int Diamond_x[4] = {-1, 0, 1, 0};
00565 static int Diamond_y[4] = {0, 1, 0, -1};
00566 int mcost;
00567 int cand_mv_x, cand_mv_y;
00568
00569 StorablePicture *ref_picture = listX[list+list_offset][ref];
00570 int mv_shift = 0;
00571 int blocksize_x = params->blc_size[blocktype][0];
00572 int blocksize_y = params->blc_size[blocktype][1];
00573 int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
00574 int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
00575
00576 int search_range_dynamic,iXMinNow,iYMinNow,i;
00577 int m,currmv_x = 0,currmv_y = 0;
00578 int pred_frac_mv_x,pred_frac_mv_y,abort_search;
00579
00580 int pred_frac_up_mv_x, pred_frac_up_mv_y;
00581
00582 dist_method = Q_PEL + 3 * apply_weights;
00583
00584 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
00585
00586 img_width = ref_picture->size_x;
00587 img_height = ref_picture->size_y;
00588 width_pad = ref_picture->size_x_pad;
00589 height_pad = ref_picture->size_y_pad;
00590
00591 if (apply_weights)
00592 {
00593 weight_luma = wp_weight[list + list_offset][ref][0];
00594 offset_luma = wp_offset[list + list_offset][ref][0];
00595 }
00596
00597 if (ChromaMEEnable )
00598 {
00599 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
00600 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
00601 width_pad_cr = ref_picture->size_x_cr_pad;
00602 height_pad_cr = ref_picture->size_y_cr_pad;
00603
00604 if (apply_weights)
00605 {
00606 weight_cr[0] = wp_weight[list + list_offset][ref][1];
00607 weight_cr[1] = wp_weight[list + list_offset][ref][2];
00608 offset_cr[0] = wp_offset[list + list_offset][ref][1];
00609 offset_cr[1] = wp_offset[list + list_offset][ref][2];
00610 }
00611 }
00612
00613 search_range_dynamic = 3;
00614 pred_frac_mv_x = (pred_mv->mv_x - mv->mv_x)%4;
00615 pred_frac_mv_y = (pred_mv->mv_y - mv->mv_y)%4;
00616
00617 pred_frac_up_mv_x = (pred_MV_uplayer[0] - mv->mv_x)%4;
00618 pred_frac_up_mv_y = (pred_MV_uplayer[1] - mv->mv_y)%4;
00619
00620
00621 memset(SearchState[0],0,(2*search_range_dynamic+1)*(2*search_range_dynamic+1));
00622
00623 if( !start_me_refinement_hp )
00624 {
00625 cand_mv_x = mv->mv_x;
00626 cand_mv_y = mv->mv_y;
00627 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00628
00629 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00630 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00631
00632 SearchState[search_range_dynamic][search_range_dynamic] = 1;
00633 if (mcost < min_mcost)
00634 {
00635 min_mcost = mcost;
00636 currmv_x = cand_mv_x;
00637 currmv_y = cand_mv_y;
00638 }
00639 }
00640 else
00641 {
00642 SearchState[search_range_dynamic][search_range_dynamic] = 1;
00643 currmv_x = mv->mv_x;
00644 currmv_y = mv->mv_y;
00645 }
00646
00647 if(pred_frac_mv_x!=0 || pred_frac_mv_y!=0)
00648 {
00649 cand_mv_x = mv->mv_x + pred_frac_mv_x;
00650 cand_mv_y = mv->mv_y + pred_frac_mv_y;
00651 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00652 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00653 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00654 SearchState[cand_mv_y -mv->mv_y + search_range_dynamic][cand_mv_x - mv->mv_x + search_range_dynamic] = 1;
00655 if (mcost < min_mcost)
00656 {
00657 min_mcost = mcost;
00658 currmv_x = cand_mv_x;
00659 currmv_y = cand_mv_y;
00660 }
00661 }
00662
00663
00664 iXMinNow = currmv_x;
00665 iYMinNow = currmv_y;
00666 for(i=0;i<search_range_dynamic;i++)
00667 {
00668 abort_search=1;
00669 for (m = 0; m < 4; m++)
00670 {
00671 cand_mv_x = iXMinNow + Diamond_x[m];
00672 cand_mv_y = iYMinNow + Diamond_y[m];
00673
00674 if(iabs(cand_mv_x - mv->mv_x) <=search_range_dynamic && iabs(cand_mv_y - mv->mv_y)<= search_range_dynamic)
00675 {
00676 if(!SearchState[cand_mv_y -mv->mv_y+ search_range_dynamic][cand_mv_x -mv->mv_x+ search_range_dynamic])
00677 {
00678 mcost = MV_COST (lambda_factor, mv_shift, cand_mv_x, cand_mv_y, pred_mv->mv_x, pred_mv->mv_y);
00679 mcost += computeUniPred[dist_method]( orig_pic, blocksize_y, blocksize_x,
00680 min_mcost - mcost, cand_mv_x + pic4_pix_x, cand_mv_y + pic4_pix_y);
00681 SearchState[cand_mv_y - mv->mv_y + search_range_dynamic][cand_mv_x - mv->mv_x + search_range_dynamic] = 1;
00682 if (mcost < min_mcost)
00683 {
00684 min_mcost = mcost;
00685 currmv_x = cand_mv_x;
00686 currmv_y = cand_mv_y;
00687 abort_search = 0;
00688 }
00689 }
00690 }
00691 }
00692 iXMinNow = currmv_x;
00693 iYMinNow = currmv_y;
00694 if(abort_search)
00695 break;
00696 }
00697
00698 mv->mv_x = currmv_x;
00699 mv->mv_y = currmv_y;
00700
00701
00702 return min_mcost;
00703 }
00704
00705 int
00706 UMHEXSubPelBlockME (imgpel* orig_pic,
00707 short ref,
00708 int list,
00709 int list_offset,
00710 int pic_pix_x,
00711 int pic_pix_y,
00712 int blocktype,
00713 MotionVector *pred_mv,
00714 MotionVector *mv,
00715 int search_pos2,
00716 int search_pos4,
00717 int min_mcost,
00718 int* lambda,
00719 int apply_weights
00720 )
00721 {
00722 if(blocktype >3)
00723 {
00724 min_mcost = UMHEXSubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y, blocktype,
00725 pred_mv, mv, 9, 9, min_mcost, lambda[Q_PEL], apply_weights);
00726 }
00727 else
00728 {
00729 min_mcost = SubPelBlockMotionSearch (orig_pic, ref, list, list_offset, pic_pix_x, pic_pix_y, blocktype,
00730 pred_mv, mv, 9, 9, min_mcost, lambda, apply_weights);
00731 }
00732
00733 return min_mcost;
00734 }
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748 void UMHEX_decide_intrabk_SAD()
00749 {
00750 if (img->type != I_SLICE)
00751 {
00752 if (img->pix_x == 0 && img->pix_y == 0)
00753 {
00754 flag_intra_SAD = 0;
00755 }
00756 else if (img->pix_x == 0)
00757 {
00758 flag_intra_SAD = flag_intra[(img->pix_x)>>4];
00759 }
00760 else if (img->pix_y == 0)
00761 {
00762 flag_intra_SAD = flag_intra[((img->pix_x)>>4)-1];
00763 }
00764 else
00765 {
00766 flag_intra_SAD = ((flag_intra[(img->pix_x)>>4])||(flag_intra[((img->pix_x)>>4)-1])||(flag_intra[((img->pix_x)>>4)+1])) ;
00767 }
00768 }
00769 return;
00770 }
00771
00772 void UMHEX_skip_intrabk_SAD(int best_mode, int ref_max)
00773 {
00774 int i,j,k, ref;
00775 if (img->number > 0)
00776 flag_intra[(img->pix_x)>>4] = (best_mode == 9 || best_mode == 10) ? 1:0;
00777 if (img->type != I_SLICE && (best_mode == 9 || best_mode == 10))
00778 {
00779 for (i=0; i < 4; i++)
00780 {
00781 for (j=0; j < 4; j++)
00782 {
00783 for (k=0; k < 9;k++)
00784 {
00785 fastme_l0_cost[k][j][i] = 0;
00786 fastme_l1_cost[k][j][i] = 0;
00787 for (ref=0; ref<ref_max;ref++)
00788 {
00789 fastme_ref_cost[ref][k][j][i] = 0;
00790 }
00791 }
00792 }
00793 }
00794
00795 }
00796 return;
00797 }
00798
00799
00800 void UMHEX_setup(short ref, int list, int block_y, int block_x, int blocktype, short ******all_mv)
00801 {
00802 int N_Bframe=0;
00803 int n_Bframe=0;
00804 int temp_blocktype = 0;
00805 int indication_blocktype[8]={0,0,1,1,2,4,4,5};
00806 N_Bframe = params->NumberBFrames;
00807 n_Bframe =(N_Bframe) ? (stats->frame_ctr[B_SLICE]%(N_Bframe+1)): 0;
00808
00809
00810
00811
00812 if (blocktype>1)
00813 {
00814 temp_blocktype = indication_blocktype[blocktype];
00815 pred_MV_uplayer[0] = all_mv[list][ref][temp_blocktype][block_y][block_x][0];
00816 pred_MV_uplayer[1] = all_mv[list][ref][temp_blocktype][block_y][block_x][1];
00817 }
00818
00819
00820
00821 pred_MV_ref_flag = 0;
00822 if(list==0)
00823 {
00824 if (img->field_picture)
00825 {
00826 if ( ref > 1)
00827 {
00828 pred_MV_ref[0] = all_mv[0][ref-2][blocktype][block_y][block_x][0];
00829 pred_MV_ref[0] = (int)(pred_MV_ref[0]*((ref>>1)+1)/(float)((ref>>1)));
00830 pred_MV_ref[1] = all_mv[0][ref-2][blocktype][block_y][block_x][1];
00831 pred_MV_ref[1] = (int)(pred_MV_ref[1]*((ref>>1)+1)/(float)((ref>>1)));
00832 pred_MV_ref_flag = 1;
00833 }
00834 if (img->type == B_SLICE && (ref==0 || ref==1) )
00835 {
00836 pred_MV_ref[0] =(int) (all_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
00837 pred_MV_ref[1] =(int) (all_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
00838 pred_MV_ref_flag = 1;
00839 }
00840 }
00841 else
00842 {
00843 if ( ref > 0)
00844 {
00845 pred_MV_ref[0] = all_mv[0][ref-1][blocktype][block_y][block_x][0];
00846 pred_MV_ref[0] = (int)(pred_MV_ref[0]*(ref+1)/(float)(ref));
00847 pred_MV_ref[1] = all_mv[0][ref-1][blocktype][block_y][block_x][1];
00848 pred_MV_ref[1] = (int)(pred_MV_ref[1]*(ref+1)/(float)(ref));
00849 pred_MV_ref_flag = 1;
00850 }
00851 if (img->type == B_SLICE && (ref==0))
00852 {
00853 pred_MV_ref[0] =(int) (all_mv[1][0][blocktype][block_y][block_x][0] * (-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
00854 pred_MV_ref[1] =(int) (all_mv[1][0][blocktype][block_y][block_x][1] * (-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
00855 pred_MV_ref_flag = 1;
00856 }
00857 }
00858 }
00859
00860 if (list==0 && ref>0)
00861 {
00862
00863 if (flag_intra_SAD)
00864 {
00865 pred_SAD = 0;
00866 }
00867 else
00868 {
00869 if (img->field_picture)
00870 {
00871 if (ref > 1)
00872 {
00873 pred_SAD = fastme_ref_cost[ref-2][blocktype][block_y][block_x];
00874 }
00875 else
00876 {
00877 pred_SAD = fastme_ref_cost[0][blocktype][block_y][block_x];
00878 }
00879 }
00880 else
00881 {
00882 pred_SAD = fastme_ref_cost[ref-1][blocktype][block_y][block_x];
00883 }
00884
00885 }
00886 }
00887 else if (blocktype>1)
00888 {
00889 if (flag_intra_SAD)
00890 {
00891 pred_SAD = 0;
00892 }
00893 else
00894 {
00895 pred_SAD = (list==1) ? (fastme_l1_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
00896 pred_SAD /= 2;
00897 }
00898 }
00899 else pred_SAD = 0 ;
00900
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918 int
00919 UMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB,
00920 imgpel* cur_pic,
00921 short ref,
00922 int list,
00923 char ***refPic,
00924 short ****tmp_mv,
00925 int pic_pix_x,
00926 int pic_pix_y,
00927 int blocktype,
00928 MotionVector *pred_mv1,
00929 MotionVector *pred_mv2,
00930 MotionVector *mv1,
00931 MotionVector *mv2,
00932 int search_range,
00933 int min_mcost,
00934 int iteration_no,
00935 int lambda_factor,
00936 int apply_weights
00937 )
00938 {
00939 int temp_Big_Hexagon_x[16];
00940 int temp_Big_Hexagon_y[16];
00941 int mvshift = 2;
00942
00943 int search_step,iYMinNow, iXMinNow;
00944 int i,m,j;
00945 float betaFourth_1,betaFourth_2;
00946 int pos, cand_x, cand_y,mcost;
00947 int blocksize_y = params->blc_size[blocktype][1];
00948 int blocksize_x = params->blc_size[blocktype][0];
00949 int pred_x1 = (pic_pix_x << 2) + pred_mv1->mv_x;
00950 int pred_y1 = (pic_pix_y << 2) + pred_mv1->mv_y;
00951 int pred_x2 = (pic_pix_x << 2) + pred_mv2->mv_x;
00952 int pred_y2 = (pic_pix_y << 2) + pred_mv2->mv_y;
00953 short center2_x = pic_pix_x + mv1->mv_x;
00954 short center2_y = pic_pix_y + mv1->mv_y;
00955 short center1_x = pic_pix_x + mv2->mv_x;
00956 short center1_y = pic_pix_y + mv2->mv_y;
00957 short mb_x = pic_pix_x - img->opix_x;
00958 short mb_y = pic_pix_y - img->opix_y;
00959 short block_x = (mb_x >> 2);
00960 short block_y = (mb_y >> 2);
00961 int best_x = center2_x;
00962 int best_y = center2_y;
00963 int ET_Thred = Median_Pred_Thd_MB[blocktype];
00964
00965 short offset1 = (apply_weights ? (list == 0? wp_offset[currMB->list_offset ][ref][0]: wp_offset[currMB->list_offset + 1][0 ][ref]) : 0);
00966 short offset2 = (apply_weights ? (list == 0? wp_offset[currMB->list_offset + 1][ref][0]: wp_offset[currMB->list_offset ][0 ][ref]) : 0);
00967
00968 ref_pic1_sub.luma = listX[list + currMB->list_offset][ref]->p_curr_img_sub;
00969 ref_pic2_sub.luma = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->p_curr_img_sub;
00970
00971 img_width = listX[list + currMB->list_offset][ref]->size_x;
00972 img_height = listX[list + currMB->list_offset][ref]->size_y;
00973 width_pad = listX[list + currMB->list_offset][ref]->size_x_pad;
00974 height_pad = listX[list + currMB->list_offset][ref]->size_y_pad;
00975
00976 if (apply_weights)
00977 {
00978 weight1 = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][0] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][0];
00979 weight2 = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][0] : wbp_weight[currMB->list_offset ][0 ][ref][0];
00980 offsetBi=(offset1 + offset2 + 1)>>1;
00981 computeBiPred = computeBiPredSAD2;
00982 }
00983 else
00984 {
00985 weight1 = 1<<luma_log_weight_denom;
00986 weight2 = 1<<luma_log_weight_denom;
00987 offsetBi = 0;
00988 computeBiPred = computeBiPredSAD1;
00989 }
00990
00991 if (ChromaMEEnable )
00992 {
00993 ref_pic1_sub.crcb[0] = listX[list + currMB->list_offset][ref]->imgUV_sub[0];
00994 ref_pic1_sub.crcb[1] = listX[list + currMB->list_offset][ref]->imgUV_sub[1];
00995 ref_pic2_sub.crcb[0] = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->imgUV_sub[0];
00996 ref_pic2_sub.crcb[1] = listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ]->imgUV_sub[1];
00997 width_pad_cr = listX[list + currMB->list_offset][ref]->size_x_cr_pad;
00998 height_pad_cr = listX[list + currMB->list_offset][ref]->size_y_cr_pad;
00999 if (apply_weights)
01000 {
01001 weight1_cr[0] = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][1] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][1];
01002 weight1_cr[1] = list == 0 ? wbp_weight[currMB->list_offset ][ref][0][2] : wbp_weight[currMB->list_offset + LIST_1][0 ][ref][2];
01003 weight2_cr[0] = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][1] : wbp_weight[currMB->list_offset ][0 ][ref][1];
01004 weight2_cr[1] = list == 0 ? wbp_weight[currMB->list_offset + LIST_1][ref][0][2] : wbp_weight[currMB->list_offset ][0 ][ref][2];
01005 offsetBi_cr[0] = (list == 0)
01006 ? (wp_offset[currMB->list_offset ][ref][1] + wp_offset[currMB->list_offset + LIST_1][ref][1] + 1) >> 1
01007 : (wp_offset[currMB->list_offset + LIST_1][0 ][1] + wp_offset[currMB->list_offset ][0 ][1] + 1) >> 1;
01008 offsetBi_cr[1] = (list == 0)
01009 ? (wp_offset[currMB->list_offset ][ref][2] + wp_offset[currMB->list_offset + LIST_1][ref][2] + 1) >> 1
01010 : (wp_offset[currMB->list_offset + LIST_1][0 ][2] + wp_offset[currMB->list_offset ][0 ][2] + 1) >> 1;
01011 }
01012 else
01013 {
01014 weight1_cr[0] = 1<<chroma_log_weight_denom;
01015 weight1_cr[1] = 1<<chroma_log_weight_denom;
01016 weight2_cr[0] = 1<<chroma_log_weight_denom;
01017 weight2_cr[1] = 1<<chroma_log_weight_denom;
01018 offsetBi_cr[0] = 0;
01019 offsetBi_cr[1] = 0;
01020 }
01021 }
01022
01023
01024
01025
01026 memset(McostState[0],0,(2*search_range+1)*(2*search_range+1));
01027
01028
01029 cand_x = center2_x ;
01030 cand_y = center2_y ;
01031 mcost = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
01032 mcost += MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x2, pred_y2);
01033
01034 mcost += computeBiPred( cur_pic,
01035 blocksize_y, blocksize_x, INT_MAX,
01036 (center1_x << 2) + IMG_PAD_SIZE_TIMES4,
01037 (center1_y << 2) + IMG_PAD_SIZE_TIMES4,
01038 (cand_x << 2) + IMG_PAD_SIZE_TIMES4,
01039 (cand_y << 2) + IMG_PAD_SIZE_TIMES4);
01040
01041 McostState[search_range][search_range] = 1;
01042
01043 if (mcost < min_mcost)
01044 {
01045 min_mcost = mcost;
01046 best_x = cand_x;
01047 best_y = cand_y;
01048 }
01049
01050 iXMinNow = best_x;
01051 iYMinNow = best_y;
01052 for (m = 0; m < 4; m++)
01053 {
01054 cand_x = iXMinNow + Diamond_x[m];
01055 cand_y = iYMinNow + Diamond_y[m];
01056 SEARCH_ONE_PIXEL_BIPRED;
01057 }
01058
01059 if(center2_x != pic_pix_x || center2_y != pic_pix_y)
01060 {
01061 cand_x = pic_pix_x ;
01062 cand_y = pic_pix_y ;
01063
01064 SEARCH_ONE_PIXEL_BIPRED;
01065
01066 iXMinNow = best_x;
01067 iYMinNow = best_y;
01068 for (m = 0; m < 4; m++)
01069 {
01070 cand_x = iXMinNow + Diamond_x[m];
01071 cand_y = iYMinNow + Diamond_y[m];
01072 SEARCH_ONE_PIXEL_BIPRED;
01073 }
01074 }
01075
01076
01077 if( min_mcost < ET_Thred)
01078 {
01079 goto terminate_step;
01080 }
01081 else
01082 {
01083 int N_Bframe=0;
01084 int n_Bframe=0;
01085 short****** bipred_mv = img->bipred_mv[list];
01086 N_Bframe = params->NumberBFrames;
01087 n_Bframe = stats->frame_ctr[B_SLICE]%(N_Bframe+1);
01088
01089
01090
01091
01092
01093
01094
01095
01096 if(list==0)
01097 {
01098 if (img->field_picture)
01099 {
01100 pred_MV_ref[0] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
01101 pred_MV_ref[1] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
01102 }
01103 else
01104 {
01105 pred_MV_ref[0] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
01106 pred_MV_ref[1] =(int) (bipred_mv[1][0][blocktype][block_y][block_x][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
01107 }
01108 }
01109
01110
01111 pred_SAD =imin(imin(SAD_a,SAD_b),SAD_c);
01112 ET_Thred = Big_Hexagon_Thd_MB[blocktype];
01113
01114
01115 if (pred_SAD == 0)
01116 {
01117 betaFourth_1=0;
01118 betaFourth_2=0;
01119 }
01120 else
01121 {
01122 betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
01123 betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
01124 }
01125 }
01126
01127
01128
01129
01130
01131
01132
01133 if(list == 0)
01134 {
01135 cand_x = pic_pix_x + (pred_MV_ref[0]/4);
01136 cand_y = pic_pix_y + (pred_MV_ref[1]/4);
01137 SEARCH_ONE_PIXEL_BIPRED;
01138 }
01139
01140
01141
01142 iXMinNow = best_x;
01143 iYMinNow = best_y;
01144 for (m = 0; m < 4; m++)
01145 {
01146 cand_x = iXMinNow + Diamond_x[m];
01147 cand_y = iYMinNow + Diamond_y[m];
01148 SEARCH_ONE_PIXEL_BIPRED;
01149 }
01150
01151
01152 EARLY_TERMINATION;
01153
01154
01155
01156 iXMinNow = best_x;
01157 iYMinNow = best_y;
01158
01159 for(i = 1; i < search_range; i+=2)
01160 {
01161 search_step = i;
01162 cand_x = iXMinNow + search_step;
01163 cand_y = iYMinNow ;
01164 SEARCH_ONE_PIXEL_BIPRED;
01165 cand_x = iXMinNow - search_step;
01166 cand_y = iYMinNow ;
01167 SEARCH_ONE_PIXEL_BIPRED;
01168 }
01169
01170 for(i = 1; i < (search_range/2);i+=2)
01171 {
01172 search_step = i;
01173 cand_x = iXMinNow ;
01174 cand_y = iYMinNow + search_step;
01175 SEARCH_ONE_PIXEL_BIPRED;
01176 cand_x = iXMinNow ;
01177 cand_y = iYMinNow - search_step;
01178 SEARCH_ONE_PIXEL_BIPRED;
01179 }
01180
01181 EARLY_TERMINATION;
01182
01183
01184 iXMinNow = best_x;
01185 iYMinNow = best_y;
01186
01187 for(pos=1;pos<25;pos++)
01188 {
01189 cand_x = iXMinNow + spiral_search_x[pos];
01190 cand_y = iYMinNow + spiral_search_y[pos];
01191 SEARCH_ONE_PIXEL_BIPRED;
01192 }
01193
01194
01195 EARLY_TERMINATION;
01196
01197
01198 memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
01199 memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
01200 for(i=1;i<=(params->search_range>>2); i++)
01201 {
01202
01203 for (m = 0; m < 16; m++)
01204 {
01205 cand_x = iXMinNow + temp_Big_Hexagon_x[m];
01206 cand_y = iYMinNow + temp_Big_Hexagon_y[m];
01207 temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
01208 temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];
01209
01210 SEARCH_ONE_PIXEL_BIPRED;
01211 }
01212 if(min_mcost < ET_Thred)
01213 {
01214 goto terminate_step;
01215
01216 }
01217 }
01218
01219 fourth_1_step:
01220
01221 for(i=0; i < search_range; i++)
01222 {
01223 iXMinNow = best_x;
01224 iYMinNow = best_y;
01225 for (m = 0; m < 6; m++)
01226 {
01227 cand_x = iXMinNow + Hexagon_x[m];
01228 cand_y = iYMinNow + Hexagon_y[m];
01229 SEARCH_ONE_PIXEL_BIPRED;
01230 }
01231 if(best_x == iXMinNow && best_y == iYMinNow)
01232 break;
01233 }
01234 fourth_2_step:
01235
01236 for(i = 0; i < search_range; i++)
01237 {
01238 iXMinNow = best_x;
01239 iYMinNow = best_y;
01240 for (m = 0; m < 4; m++)
01241 {
01242 cand_x = iXMinNow + Diamond_x[m];
01243 cand_y = iYMinNow + Diamond_y[m];
01244 SEARCH_ONE_PIXEL_BIPRED;
01245 }
01246 if(best_x == iXMinNow && best_y == iYMinNow)
01247 break;
01248 }
01249
01250 terminate_step:
01251 for (i=0; i < (blocksize_x>>2); i++)
01252 {
01253 for (j=0; j < (blocksize_y>>2); j++)
01254 {
01255 if(list == 0)
01256 {
01257 fastme_l0_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
01258 }
01259 else
01260 {
01261 fastme_l1_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
01262 }
01263 }
01264 }
01265
01266 mv1->mv_x = best_x - pic_pix_x;
01267 mv1->mv_y = best_y - pic_pix_y;
01268
01269 return min_mcost;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278 void UMHEXSetMotionVectorPredictor (Macroblock *currMB,
01279 short pmv[2],
01280 char **refPic,
01281 short ***tmp_mv,
01282 short ref_frame,
01283 int list,
01284 int mb_x,
01285 int mb_y,
01286 int blockshape_x,
01287 int blockshape_y,
01288 int *search_range)
01289 {
01290 int mv_a, mv_b, mv_c, pred_vec=0;
01291 int mvPredType, rFrameL, rFrameU, rFrameUR;
01292 int hv;
01293
01294 PixelPos block_a, block_b, block_c, block_d;
01295
01296
01297 int *** fastme_l0_cost_flag = (bipred_flag ? fastme_l0_cost_bipred:fastme_l0_cost);
01298 int *** fastme_l1_cost_flag = (bipred_flag ? fastme_l1_cost_bipred:fastme_l1_cost);
01299
01300
01301
01302 int dsr_temp_search_range[2];
01303 int dsr_mv_avail, dsr_mv_max, dsr_mv_sum, dsr_small_search_range;
01304 int *mb_size = img->mb_size[IS_LUMA];
01305
01306
01307 SAD_a=0;
01308 SAD_b=0;
01309 SAD_c=0;
01310 SAD_d=0;
01311
01312 get4x4Neighbour(currMB, mb_x - 1 , mb_y , mb_size, &block_a);
01313 get4x4Neighbour(currMB, mb_x , mb_y - 1, mb_size, &block_b);
01314 get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, &block_c);
01315 get4x4Neighbour(currMB, mb_x - 1 , mb_y - 1, mb_size, &block_d);
01316
01317 if (mb_y > 0)
01318 {
01319 if (mb_x < 8)
01320 {
01321 if (mb_y==8)
01322 {
01323 if (blockshape_x == 16) block_c.available = 0;
01324 }
01325 else
01326 {
01327 if (mb_x+blockshape_x == 8) block_c.available = 0;
01328 }
01329 }
01330 else
01331 {
01332 if (mb_x+blockshape_x == 16) block_c.available = 0;
01333 }
01334 }
01335
01336 if (!block_c.available)
01337 {
01338 block_c=block_d;
01339 }
01340
01341 mvPredType = MVPRED_MEDIAN;
01342
01343 if (!img->MbaffFrameFlag)
01344 {
01345 rFrameL = block_a.available ? refPic[block_a.pos_y][block_a.pos_x] : -1;
01346 rFrameU = block_b.available ? refPic[block_b.pos_y][block_b.pos_x] : -1;
01347 rFrameUR = block_c.available ? refPic[block_c.pos_y][block_c.pos_x] : -1;
01348 }
01349 else
01350 {
01351 if (img->mb_data[img->current_mb_nr].mb_field)
01352 {
01353 rFrameL = block_a.available
01354 ? (img->mb_data[block_a.mb_addr].mb_field
01355 ? refPic[block_a.pos_y][block_a.pos_x]
01356 : refPic[block_a.pos_y][block_a.pos_x] * 2) : -1;
01357 rFrameU = block_b.available
01358 ? (img->mb_data[block_b.mb_addr].mb_field
01359 ? refPic[block_b.pos_y][block_b.pos_x]
01360 : refPic[block_b.pos_y][block_b.pos_x] * 2) : -1;
01361 rFrameUR = block_c.available
01362 ? (img->mb_data[block_c.mb_addr].mb_field
01363 ? refPic[block_c.pos_y][block_c.pos_x]
01364 : refPic[block_c.pos_y][block_c.pos_x] * 2) : -1;
01365 }
01366 else
01367 {
01368 rFrameL = block_a.available
01369 ? (img->mb_data[block_a.mb_addr].mb_field
01370 ? refPic[block_a.pos_y][block_a.pos_x] >>1
01371 : refPic[block_a.pos_y][block_a.pos_x]) : -1;
01372 rFrameU = block_b.available ?
01373 img->mb_data[block_b.mb_addr].mb_field ?
01374 refPic[block_b.pos_y][block_b.pos_x] >>1:
01375 refPic[block_b.pos_y][block_b.pos_x] :
01376 -1;
01377 rFrameUR = block_c.available ?
01378 img->mb_data[block_c.mb_addr].mb_field ?
01379 refPic[block_c.pos_y][block_c.pos_x] >>1:
01380 refPic[block_c.pos_y][block_c.pos_x] :
01381 -1;
01382 }
01383 }
01384
01385
01386
01387
01388 if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_L;
01389 else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame) mvPredType = MVPRED_U;
01390 else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame) mvPredType = MVPRED_UR;
01391
01392 if(blockshape_x == 8 && blockshape_y == 16)
01393 {
01394 if(mb_x == 0)
01395 {
01396 if(rFrameL == ref_frame)
01397 mvPredType = MVPRED_L;
01398 }
01399 else
01400 {
01401 if( rFrameUR == ref_frame)
01402 mvPredType = MVPRED_UR;
01403 }
01404 }
01405 else if(blockshape_x == 16 && blockshape_y == 8)
01406 {
01407 if(mb_y == 0)
01408 {
01409 if(rFrameU == ref_frame)
01410 mvPredType = MVPRED_U;
01411 }
01412 else
01413 {
01414 if(rFrameL == ref_frame)
01415 mvPredType = MVPRED_L;
01416 }
01417 }
01418
01419
01420 if((params->UMHexDSR == 1 || params->BiPredMotionEstimation == 1))
01421 {
01422 SAD_a = block_a.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x])) : 0;
01423 SAD_b = block_b.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x])) : 0;
01424 SAD_d = block_d.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x])) : 0;
01425 SAD_c = block_c.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x])) : SAD_d;
01426 }
01427 for (hv=0; hv < 2; hv++)
01428 {
01429 if (!img->MbaffFrameFlag || hv==0)
01430 {
01431 mv_a = block_a.available ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] : 0;
01432 mv_b = block_b.available ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] : 0;
01433 mv_c = block_c.available ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] : 0;
01434 }
01435 else
01436 {
01437 if (img->mb_data[img->current_mb_nr].mb_field)
01438 {
01439 mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field
01440 ? tmp_mv[block_a.pos_y][block_a.pos_x][hv]
01441 : tmp_mv[block_a.pos_y][block_a.pos_x][hv] / 2
01442 : 0;
01443 mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field
01444 ? tmp_mv[block_b.pos_y][block_b.pos_x][hv]
01445 : tmp_mv[block_b.pos_y][block_b.pos_x][hv] / 2
01446 : 0;
01447 mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field
01448 ? tmp_mv[block_c.pos_y][block_c.pos_x][hv]
01449 : tmp_mv[block_c.pos_y][block_c.pos_x][hv] / 2
01450 : 0;
01451 }
01452 else
01453 {
01454 mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field
01455 ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] * 2
01456 : tmp_mv[block_a.pos_y][block_a.pos_x][hv]
01457 : 0;
01458 mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field
01459 ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] * 2
01460 : tmp_mv[block_b.pos_y][block_b.pos_x][hv]
01461 : 0;
01462 mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field
01463 ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] * 2
01464 : tmp_mv[block_c.pos_y][block_c.pos_x][hv]
01465 : 0;
01466 }
01467 }
01468
01469 switch (mvPredType)
01470 {
01471 case MVPRED_MEDIAN:
01472 if(!(block_b.available || block_c.available))
01473 {
01474 pred_vec = mv_a;
01475 }
01476 else
01477 {
01478 pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
01479 }
01480 break;
01481 case MVPRED_L:
01482 pred_vec = mv_a;
01483 break;
01484 case MVPRED_U:
01485 pred_vec = mv_b;
01486 break;
01487 case MVPRED_UR:
01488 pred_vec = mv_c;
01489 break;
01490 default:
01491 break;
01492 }
01493
01494 pmv[hv] = pred_vec;
01495
01496 if (params->UMHexDSR)
01497 {
01498 dsr_mv_avail=block_a.available+block_b.available+block_c.available;
01499 if(dsr_mv_avail < 2)
01500 {
01501 dsr_temp_search_range[hv] = params->search_range;
01502 }
01503 else
01504 {
01505 dsr_mv_max = imax(iabs(mv_a),imax(iabs(mv_b),iabs(mv_c)));
01506 dsr_mv_sum = (iabs(mv_a)+iabs(mv_b)+iabs(mv_c));
01507 if(dsr_mv_sum == 0) dsr_small_search_range = (params->search_range + 4) >> 3;
01508 else if(dsr_mv_sum > 3 ) dsr_small_search_range = (params->search_range + 2) >>2;
01509 else dsr_small_search_range = (3*params->search_range + 8) >> 4;
01510 dsr_temp_search_range[hv]=imin(params->search_range,imax(dsr_small_search_range,dsr_mv_max<<1));
01511 if(imax(SAD_a,imax(SAD_b,SAD_c)) > Threshold_DSR_MB[UMHEX_blocktype])
01512 dsr_temp_search_range[hv] = params->search_range;
01513 }
01514 }
01515 }
01516
01517
01518 if (params->UMHexDSR)
01519 {
01520 dsr_new_search_range = imax(dsr_temp_search_range[0],dsr_temp_search_range[1]);
01521
01522 if (params->full_search == 2)
01523 *search_range = dsr_new_search_range;
01524 else if (params->full_search == 1)
01525 *search_range = dsr_new_search_range / (imin(ref_frame,1)+1);
01526 else
01527 *search_range = dsr_new_search_range / ((imin(ref_frame,1)+1) * imin(2,BlockType_LUT[(blockshape_y >> 2) - 1][(blockshape_x >> 2) - 1]));
01528 }
01529 }
01530