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