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 "macroblock.h"
00033 #include "me_distortion.h"
00034 #include "mv_search.h"
00035
00036
00037 static const MotionVector Diamond[4] = {{-4, 0}, {4, 0}, {0, -4}, {0, 4}};
00038 static const MotionVector Diamond_SubPelSearch[4] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
00039 static const MotionVector Hexagon[6] = {{-8, 0}, {8, 0},{-4, -8}, {4, 8}, {-4, 8}, {4 , -8}};
00040 static const short Big_Hexagon_X[16] = {-16, 16, 0, 0,-16, 16,-16, 16,-16, 16,-16, 16,-8, 8,-8, 8};
00041 static const short Big_Hexagon_Y[16] = { 0, 0,-16, 16,-4, 4, 4,-4,-8, 8, 8,-8,-12, 12, 12,-12};
00042
00043 static const short block_type_shift_factor[8] = {0, 0, 1, 1, 2, 3, 3, 1};
00044
00045
00046 #undef SEARCH_ONE_PIXEL_BIPRED
00047 #undef SEARCH_ONE_PIXEL
00048 #define SEARCH_ONE_PIXEL \
00049 if((iabs(cand.mv_x - center.mv_x)>>2) <= search_range && \
00050 (iabs(cand.mv_y - center.mv_y)>>2) <= search_range) \
00051 { \
00052 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred); \
00053 mcost += mv_block->computePredFPel( ref_picture, mv_block, min_mcost - mcost, &cand); \
00054 if (mcost < min_mcost) \
00055 { \
00056 best = cand; \
00057 min_mcost = mcost; \
00058 } \
00059 }
00060
00061 #define SEARCH_ONE_PIXEL_BIPRED \
00062 if ((iabs(cand.mv_x - center2.mv_x)>>2) <= search_range \
00063 && (iabs(cand.mv_y - center2.mv_x)>>2) <= search_range) \
00064 { \
00065 mcost = mv_cost (p_Img, lambda_factor, ¢er1, &pred1); \
00066 mcost += mv_cost (p_Img, lambda_factor, &cand, &pred2); \
00067 if (mcost < min_mcost) \
00068 { \
00069 mcost += mv_block->computeBiPredFPel(ref_picture1, ref_picture2, \
00070 mv_block, min_mcost - mcost, ¢er1, &cand); \
00071 if (mcost < min_mcost) \
00072 { \
00073 best = cand; \
00074 min_mcost = mcost; \
00075 } \
00076 } \
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 void smpUMHEX_init(ImageParameters *p_Img)
00088 {
00089 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00090 p_UMHexSMP->SymmetricalCrossSearchThreshold1 = 800;
00091 p_UMHexSMP->SymmetricalCrossSearchThreshold2 = 7000;
00092 p_UMHexSMP->ConvergeThreshold = 1000;
00093 p_UMHexSMP->SubPelThreshold1 = 1000;
00094 p_UMHexSMP->SubPelThreshold3 = 400;
00095 }
00096
00097
00098
00099
00100
00101
00102
00103 int smpUMHEX_get_mem(ImageParameters *p_Img)
00104 {
00105 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00106 int memory_size = 0;
00107 if (NULL==(p_UMHexSMP->flag_intra = calloc((p_Img->width>>4)+1, sizeof(byte))))
00108 no_mem_exit("smpUMHEX_get_mem: flag_intra");
00109
00110 memory_size += get_mem3Dint(&p_UMHexSMP->l0_cost, 9, p_Img->height >> 2, p_Img->width >> 2);
00111 memory_size += get_mem3Dint(&p_UMHexSMP->l1_cost, 9, p_Img->height >> 2, p_Img->width >> 2);
00112 memory_size += get_mem2D(&p_UMHexSMP->SearchState, 7, 7);
00113
00114 return memory_size;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 void smpUMHEX_free_mem(ImageParameters *p_Img)
00124 {
00125 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00126 free_mem3Dint(p_UMHexSMP->l0_cost );
00127 free_mem3Dint(p_UMHexSMP->l1_cost );
00128 free_mem2D(p_UMHexSMP->SearchState);
00129
00130 free (p_UMHexSMP->flag_intra);
00131 free (p_UMHexSMP);
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141 int
00142 smpUMHEXIntegerPelBlockMotionSearch (Macroblock *currMB,
00143 MotionVector *pred_mv,
00144 MEBlock *mv_block,
00145 int min_mcost,
00146 int lambda_factor
00147 )
00148 {
00149 ImageParameters *p_Img = currMB->p_Img;
00150 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00151 int blocktype = mv_block->blocktype;
00152 short blocksize_x = mv_block->blocksize_x;
00153 short blocksize_y = mv_block->blocksize_y;
00154 short pic_pix_x = mv_block->pos_x_padded;
00155 short pic_pix_y = mv_block->pos_y_padded;
00156
00157 int list = mv_block->list;
00158 int cur_list = list + currMB->list_offset;
00159 short ref = mv_block->ref_idx;
00160 StorablePicture *ref_picture = p_Img->listX[cur_list][ref];
00161 int search_range = mv_block->searchRange.max_x >> 2;
00162
00163 MotionVector *mv = &mv_block->mv[list];
00164 MotionVector iMinNow, cand, center, pred, best = {0, 0};
00165
00166 int search_step;
00167 int mcost;
00168
00169 uint16 i, j, m;
00170
00171 pic_pix_x = mv_block->pos_x_padded;
00172 pic_pix_y = mv_block->pos_y_padded;
00173 pred.mv_x = pic_pix_x + pred_mv->mv_x;
00174 pred.mv_y = pic_pix_y + pred_mv->mv_y;
00175 center.mv_x = pic_pix_x + mv->mv_x;
00176 center.mv_y = pic_pix_y + mv->mv_y;
00177
00178
00179
00180
00181 cand = center;
00182 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred);
00183
00184 mcost += mv_block->computePredFPel(ref_picture, mv_block, min_mcost - mcost, &cand);
00185
00186 if (mcost < min_mcost)
00187 {
00188 min_mcost = mcost;
00189 best = cand;
00190 }
00191
00192 iMinNow = best;
00193
00194
00195 if ((0 != pred_mv->mv_x) || (0 != pred_mv->mv_y))
00196 {
00197 cand.mv_x = pic_pix_x;
00198 cand.mv_y = pic_pix_y;
00199 SEARCH_ONE_PIXEL;
00200 iMinNow = best;
00201 }
00202
00203
00204
00205 if (min_mcost < (p_UMHexSMP->ConvergeThreshold >> block_type_shift_factor[blocktype]))
00206 {
00207 for (m = 0; m < 4; m++)
00208 {
00209 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00210 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00211 SEARCH_ONE_PIXEL;
00212 }
00213 mv->mv_x = (short) (best.mv_x - pic_pix_x);
00214 mv->mv_y = (short) (best.mv_y - pic_pix_y);
00215 return min_mcost;
00216 }
00217
00218
00219 iMinNow = best;
00220 for (m = 0; m < 4; m++)
00221 {
00222 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00223 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00224 SEARCH_ONE_PIXEL;
00225 }
00226
00227
00228
00229 if ( (blocktype == 1 &&
00230 min_mcost > (p_UMHexSMP->SymmetricalCrossSearchThreshold1 >> block_type_shift_factor[blocktype])) ||
00231 (min_mcost > (p_UMHexSMP->SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])) )
00232 {
00233 iMinNow = best;
00234
00235 for(i = 4; i <= 4 * search_range - 4; i+= 8)
00236 {
00237 search_step = i;
00238 cand.mv_x = (short) (iMinNow.mv_x + search_step);
00239 cand.mv_y = iMinNow.mv_y;
00240 SEARCH_ONE_PIXEL;
00241
00242 cand.mv_x = (short) (iMinNow.mv_x - search_step);
00243 SEARCH_ONE_PIXEL;
00244
00245 cand.mv_x = iMinNow.mv_x;
00246 cand.mv_y = (short) (iMinNow.mv_y + search_step);
00247 SEARCH_ONE_PIXEL;
00248
00249 cand.mv_y = (short) (iMinNow.mv_y - search_step);
00250 SEARCH_ONE_PIXEL;
00251 }
00252
00253
00254 iMinNow = best;
00255
00256 for (m = 0; m < 6; m++)
00257 {
00258 cand.mv_x = iMinNow.mv_x + Hexagon[m].mv_x;
00259 cand.mv_y = iMinNow.mv_y + Hexagon[m].mv_y;
00260 SEARCH_ONE_PIXEL;
00261 }
00262
00263 iMinNow = best;
00264
00265 for(i = 1; i <= search_range >> 2; i++)
00266 {
00267 for (m = 0; m < 16; m++)
00268 {
00269 cand.mv_x = iMinNow.mv_x + Big_Hexagon_X[m]*i;
00270 cand.mv_y = iMinNow.mv_y + Big_Hexagon_Y[m]*i;
00271 SEARCH_ONE_PIXEL;
00272 }
00273 }
00274 }
00275
00276
00277 if (blocktype > 1)
00278 {
00279 cand.mv_x = pic_pix_x + (p_UMHexSMP->pred_MV_uplayer_X / 4) * 4;
00280 cand.mv_y = pic_pix_y + (p_UMHexSMP->pred_MV_uplayer_Y / 4) * 4;
00281 SEARCH_ONE_PIXEL;
00282 }
00283
00284 if(center.mv_x != pic_pix_x || center.mv_y != pic_pix_y)
00285 {
00286 cand.mv_x = pic_pix_x;
00287 cand.mv_y = pic_pix_y;
00288 SEARCH_ONE_PIXEL;
00289
00290 iMinNow = best;
00291
00292 for (m = 0; m < 4; m++)
00293 {
00294 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00295 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00296 SEARCH_ONE_PIXEL;
00297 }
00298 }
00299
00300
00301
00302 if (min_mcost < (p_UMHexSMP->ConvergeThreshold >> block_type_shift_factor[blocktype]))
00303 {
00304 iMinNow = best;
00305
00306 for (m = 0; m < 4; m++)
00307 {
00308 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00309 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00310 SEARCH_ONE_PIXEL;
00311 }
00312 mv->mv_x = (short) (best.mv_x - pic_pix_x);
00313 mv->mv_y = (short) (best.mv_y - pic_pix_y);
00314 return min_mcost;
00315 }
00316
00317
00318 for(i = 0; i < search_range; i++)
00319 {
00320 iMinNow = best;
00321 for (m = 0; m < 6; m++)
00322 {
00323 cand.mv_x = iMinNow.mv_x + Hexagon[m].mv_x;
00324 cand.mv_y = iMinNow.mv_y + Hexagon[m].mv_y;
00325 SEARCH_ONE_PIXEL;
00326 }
00327
00328 if (best.mv_x == iMinNow.mv_x && best.mv_y == iMinNow.mv_y)
00329 {
00330 break;
00331 }
00332 }
00333
00334
00335 for(i = 0; i < search_range; i++)
00336 {
00337 iMinNow = best;
00338 for (m = 0; m < 4; m++)
00339 {
00340 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00341 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00342 SEARCH_ONE_PIXEL;
00343 }
00344
00345
00346 if (best.mv_x == iMinNow.mv_x && best.mv_y == iMinNow.mv_y)
00347 {
00348 break;
00349 }
00350 }
00351
00352 mv->mv_x = (short) (best.mv_x - pic_pix_x);
00353 mv->mv_y = (short) (best.mv_y - pic_pix_y);
00354
00355 for (j=(mv_block->pos_y2); j < (mv_block->pos_y2) + (blocksize_y>>2); j++)
00356 {
00357 for (i=(mv_block->pos_x2); i < (mv_block->pos_x2) + (blocksize_x>>2); i++)
00358 {
00359 if(mv_block->list == 0)
00360 {
00361 p_UMHexSMP->l0_cost[blocktype][j][i] = min_mcost;
00362 }
00363 else
00364 {
00365 p_UMHexSMP->l1_cost[blocktype][j][i] = min_mcost;
00366 }
00367 }
00368 }
00369
00370 return min_mcost;
00371 }
00372
00373
00374
00375
00376
00377
00378
00379 int
00380 smpUMHEXFullSubPelBlockMotionSearch (Macroblock *currMB,
00381 MotionVector *pred_mv,
00382 MEBlock *mv_block,
00383 int min_mcost,
00384 int lambda_factor
00385 )
00386 {
00387 ImageParameters *p_Img = currMB->p_Img;
00388 InputParameters *p_Inp = currMB->p_Inp;
00389 Slice *currSlice = currMB->p_slice;
00390 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00391 int pos, best_pos, mcost;
00392
00393 MotionVector cand;
00394
00395 int blocktype = mv_block->blocktype;
00396 int list = mv_block->list;
00397 int list_offset = currMB->list_offset;
00398 short ref = mv_block->ref_idx;
00399 MotionVector *mv = &mv_block->mv[list];
00400
00401 int check_position0 = (!p_Inp->rdopt && currSlice->slice_type!=B_SLICE && ref==0 && blocktype==1 && mv->mv_x==0 && mv->mv_y==0);
00402
00403 int max_pos2 = ( !p_Img->start_me_refinement_hp ? imax(1, mv_block->search_pos2) : mv_block->search_pos2);
00404 MotionVector cmv;
00405
00406 StorablePicture *ref_picture = p_Img->listX[list + list_offset][ref];
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 for (best_pos = 0, pos = p_Img->start_me_refinement_hp; pos < max_pos2; pos++)
00417 {
00418 cand.mv_x = mv->mv_x + p_Img->spiral_hpel_search[pos].mv_x;
00419 cand.mv_y = mv->mv_y + p_Img->spiral_hpel_search[pos].mv_y;
00420
00421
00422 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00423
00424 if (mcost >= min_mcost) continue;
00425
00426 cmv = pad_MVs(cand, mv_block);
00427
00428 mcost += mv_block->computePredQPel( ref_picture, mv_block, min_mcost - mcost, &cmv);
00429
00430 if (pos==0 && check_position0)
00431 {
00432 mcost -= WEIGHTED_COST (lambda_factor, 16);
00433 }
00434
00435 if (mcost < min_mcost)
00436 {
00437 min_mcost = mcost;
00438 best_pos = pos;
00439 }
00440 if (min_mcost < (p_UMHexSMP->SubPelThreshold3 >> block_type_shift_factor[blocktype]))
00441 {
00442 break;
00443 }
00444 }
00445
00446 if (best_pos)
00447 {
00448 add_mvs(mv, &p_Img->spiral_hpel_search[best_pos]);
00449 }
00450
00451 if ((mv->mv_x == 0) && (mv->mv_y == 0) && (pred_mv->mv_x == 0 && pred_mv->mv_y == 0) &&
00452 (min_mcost < (p_UMHexSMP->SubPelThreshold1 >> block_type_shift_factor[blocktype])) )
00453 {
00454 best_pos = 0;
00455 return min_mcost;
00456 }
00457
00458 if ( !p_Img->start_me_refinement_qp )
00459 min_mcost = INT_MAX;
00460
00461
00462
00463
00464
00465
00466
00467
00468 for (best_pos = 0, pos = p_Img->start_me_refinement_qp; pos < mv_block->search_pos4; pos++)
00469 {
00470 cand.mv_x = mv->mv_x + p_Img->spiral_search[pos].mv_x;
00471 cand.mv_y = mv->mv_y + p_Img->spiral_search[pos].mv_y;
00472
00473
00474 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00475
00476 if (mcost >= min_mcost) continue;
00477
00478 cmv = pad_MVs(cand, mv_block);
00479
00480 mcost += mv_block->computePredQPel( ref_picture, mv_block, min_mcost - mcost, &cmv);
00481
00482 if (mcost < min_mcost)
00483 {
00484 min_mcost = mcost;
00485 best_pos = pos;
00486 }
00487 if (min_mcost < (p_UMHexSMP->SubPelThreshold3 >> block_type_shift_factor[blocktype]))
00488 {
00489 break;
00490 }
00491 }
00492
00493 if (best_pos)
00494 {
00495 add_mvs(mv, &p_Img->spiral_search[best_pos]);
00496 }
00497
00498
00499 return min_mcost;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509 int
00510 smpUMHEXSubPelBlockMotionSearch (
00511 Macroblock *currMB,
00512 MotionVector *pred_mv,
00513 MEBlock *mv_block,
00514 int min_mcost,
00515 int lambda_factor
00516 )
00517 {
00518 ImageParameters *p_Img = currMB->p_Img;
00519 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00520 int mcost;
00521 MotionVector cand, iMinNow, currmv = {0, 0}, candWithPad;
00522
00523 int blocktype = mv_block->blocktype;
00524 int list = mv_block->list;
00525 int list_offset = currMB->list_offset;
00526 short ref = mv_block->ref_idx;
00527 MotionVector *mv = &mv_block->mv[list];
00528
00529 StorablePicture *ref_picture = p_Img->listX[list+list_offset][ref];
00530
00531 short dynamic_search_range = 3, i, m;
00532 int pred_frac_mv_x,pred_frac_mv_y,abort_search;
00533 int pred_frac_up_mv_x, pred_frac_up_mv_y;
00534
00535 pred_frac_mv_x = (pred_mv->mv_x - mv->mv_x) %4;
00536 pred_frac_mv_y = (pred_mv->mv_y - mv->mv_y) %4;
00537
00538 pred_frac_up_mv_x = (p_UMHexSMP->pred_MV_uplayer_X - mv->mv_x) & 0x03;
00539 pred_frac_up_mv_y = (p_UMHexSMP->pred_MV_uplayer_Y - mv->mv_y) & 0x03;
00540
00541 memset(p_UMHexSMP->SearchState[0], 0, (2 * dynamic_search_range + 1)*(2 * dynamic_search_range + 1));
00542
00543 p_UMHexSMP->SearchState[dynamic_search_range][dynamic_search_range] = 1;
00544 if( !p_Img->start_me_refinement_hp )
00545 {
00546 cand.mv_x = mv->mv_x;
00547 cand.mv_y = mv->mv_y;
00548 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00549 candWithPad = pad_MVs (cand, mv_block);
00550
00551 mcost += mv_block->computePredQPel( ref_picture, mv_block, min_mcost - mcost, &candWithPad);
00552 if (mcost < min_mcost)
00553 {
00554 min_mcost = mcost;
00555 currmv = cand;
00556 }
00557 }
00558 else
00559 {
00560 currmv = *mv;
00561 }
00562
00563
00564
00565 if ( ((mv->mv_x) == 0) && ((mv->mv_y) == 0) &&
00566 (pred_frac_mv_x == 0 && pred_frac_up_mv_x == 0) &&
00567 (pred_frac_mv_y == 0 && pred_frac_up_mv_y == 0) &&
00568 (min_mcost < (p_UMHexSMP->SubPelThreshold1 >> block_type_shift_factor[blocktype])) )
00569 {
00570 *mv = currmv;
00571 return min_mcost;
00572 }
00573
00574 if(pred_frac_mv_x || pred_frac_mv_y)
00575 {
00576 cand.mv_x = (short) (mv->mv_x + pred_frac_mv_x);
00577 cand.mv_y = (short) (mv->mv_y + pred_frac_mv_y);
00578 p_UMHexSMP->SearchState[cand.mv_y -mv->mv_y + dynamic_search_range][cand.mv_x - mv->mv_x + dynamic_search_range] = 1;
00579 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00580
00581 candWithPad = pad_MVs (cand, mv_block);
00582 mcost += mv_block->computePredQPel( ref_picture, mv_block, min_mcost - mcost, &candWithPad);
00583
00584 if (mcost < min_mcost)
00585 {
00586 min_mcost = mcost;
00587 currmv = cand;
00588 }
00589 }
00590
00591
00592 for(i = 0; i < dynamic_search_range; i++)
00593 {
00594 abort_search = 1;
00595
00596 iMinNow = currmv;
00597
00598 for (m = 0; m < 4; m++)
00599 {
00600 cand.mv_x = iMinNow.mv_x + Diamond_SubPelSearch[m].mv_x;
00601 cand.mv_y = iMinNow.mv_y + Diamond_SubPelSearch[m].mv_y;
00602
00603 if(iabs(cand.mv_x - mv->mv_x) <= dynamic_search_range && iabs(cand.mv_y - mv->mv_y) <= dynamic_search_range)
00604 {
00605 if(!p_UMHexSMP->SearchState[cand.mv_y - mv->mv_y + dynamic_search_range][cand.mv_x - mv->mv_x + dynamic_search_range])
00606 {
00607 p_UMHexSMP->SearchState[cand.mv_y - mv->mv_y + dynamic_search_range][cand.mv_x - mv->mv_x + dynamic_search_range] = 1;
00608 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00609 candWithPad = pad_MVs (cand, mv_block);
00610 mcost += mv_block->computePredQPel( ref_picture, mv_block, min_mcost - mcost, &candWithPad);
00611 if (mcost < min_mcost)
00612 {
00613 min_mcost = mcost;
00614 currmv = cand;
00615 abort_search = 0;
00616 }
00617 if (min_mcost < (p_UMHexSMP->SubPelThreshold3 >> block_type_shift_factor[blocktype]))
00618 {
00619 *mv = currmv;
00620 return min_mcost;
00621 }
00622 }
00623 }
00624 }
00625
00626 if (abort_search)
00627 {
00628 break;
00629 }
00630 }
00631
00632 *mv = currmv;
00633
00634
00635 return min_mcost;
00636 }
00637
00638
00639 int
00640 smpUMHEXSubPelBlockME (Macroblock *currMB,
00641 MotionVector *pred_mv,
00642 MEBlock *mv_block,
00643 int min_mcost,
00644 int* lambda_factor )
00645 {
00646 if(mv_block->blocktype > 1)
00647 {
00648 min_mcost = smpUMHEXSubPelBlockMotionSearch (currMB, pred_mv, mv_block, min_mcost, lambda_factor[Q_PEL]);
00649 }
00650 else
00651 {
00652 min_mcost = smpUMHEXFullSubPelBlockMotionSearch (currMB, pred_mv, mv_block, min_mcost, lambda_factor[Q_PEL]);
00653 }
00654
00655 return min_mcost;
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665 int
00666 smpUMHEXBipredIntegerPelBlockMotionSearch (Macroblock *currMB,
00667 int list,
00668 MotionVector *pred_mv1,
00669 MotionVector *pred_mv2,
00670 MotionVector *mv1,
00671 MotionVector *mv2,
00672 MEBlock *mv_block,
00673 int search_range,
00674 int min_mcost,
00675 int lambda_factor
00676 )
00677 {
00678 ImageParameters *p_Img = currMB->p_Img;
00679 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00680
00681 int search_step;
00682 int i, m;
00683 int mcost;
00684 short blocktype = mv_block->blocktype;
00685
00686 short pic_pix_x = mv_block->pos_x_padded;
00687 short pic_pix_y = mv_block->pos_y_padded;
00688 short ref = mv_block->ref_idx;
00689
00690 StorablePicture *ref_picture1 = p_Img->listX[list + currMB->list_offset][ref];
00691 StorablePicture *ref_picture2 = p_Img->listX[list == 0 ? 1 + currMB->list_offset: currMB->list_offset][ 0 ];
00692
00693 MotionVector iMinNow, best, cand, pred1, pred2, center1, center2;
00694 search_range >>= 2;
00695
00696 pred1.mv_x = mv_block->pos_x_padded + pred_mv1->mv_x;
00697 pred1.mv_y = mv_block->pos_y_padded + pred_mv1->mv_y;
00698 pred2.mv_x = mv_block->pos_x_padded + pred_mv2->mv_x;
00699 pred2.mv_y = mv_block->pos_y_padded + pred_mv2->mv_y;
00700
00701 center2.mv_x = mv_block->pos_x_padded + mv1->mv_x;
00702 center2.mv_y = mv_block->pos_y_padded + mv1->mv_y;
00703 center1.mv_x = mv_block->pos_x_padded + mv2->mv_x;
00704 center1.mv_y = mv_block->pos_y_padded + mv2->mv_y;
00705
00706
00707 best = cand = center2;
00708 mcost = mv_cost (p_Img, lambda_factor, ¢er1, &pred1);
00709 mcost += mv_cost (p_Img, lambda_factor, &cand, &pred2);
00710
00711 mcost += mv_block->computeBiPredFPel(ref_picture1, ref_picture2, mv_block,
00712 INT_MAX, ¢er1, &cand);
00713
00714 if (mcost < min_mcost)
00715 {
00716 min_mcost = mcost;
00717 best = cand;
00718 }
00719
00720 iMinNow = best;
00721 if (0 != pred_mv1->mv_x || 0 != pred_mv1->mv_y || 0 != pred_mv2->mv_x || 0 != pred_mv2->mv_y)
00722 {
00723 cand.mv_x = pic_pix_x;
00724 cand.mv_y = pic_pix_y;
00725 SEARCH_ONE_PIXEL_BIPRED;
00726 }
00727
00728
00729
00730 if ((min_mcost<<3) < (p_UMHexSMP->ConvergeThreshold >> (block_type_shift_factor[blocktype])))
00731 {
00732 for (m = 0; m < 4; m++)
00733 {
00734 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00735 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00736 SEARCH_ONE_PIXEL_BIPRED;
00737 }
00738
00739 mv1->mv_x = (short) (best.mv_x - pic_pix_x);
00740 mv1->mv_y = (short) (best.mv_y - pic_pix_y);
00741 return min_mcost;
00742 }
00743
00744
00745 for (m = 0; m < 4; m++)
00746 {
00747 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00748 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00749 SEARCH_ONE_PIXEL_BIPRED;
00750 }
00751
00752
00753
00754 if ((blocktype == 1 &&
00755 (min_mcost<<2) > (p_UMHexSMP->SymmetricalCrossSearchThreshold1 >> block_type_shift_factor[blocktype])) ||
00756 ((min_mcost<<2) > (p_UMHexSMP->SymmetricalCrossSearchThreshold2>>block_type_shift_factor[blocktype])))
00757 {
00758 iMinNow.mv_x = best.mv_x;
00759 iMinNow.mv_y = best.mv_y;
00760
00761 for (i = 8; i <= 4 * search_range; i+= 8)
00762 {
00763 search_step = i - 4;
00764 cand.mv_x = (short) (iMinNow.mv_x + search_step);
00765 cand.mv_y = iMinNow.mv_y;
00766 SEARCH_ONE_PIXEL_BIPRED;
00767 cand.mv_x = (short) (iMinNow.mv_x - search_step);
00768 SEARCH_ONE_PIXEL_BIPRED;
00769
00770 cand.mv_x = iMinNow.mv_x;
00771 cand.mv_y = (short) (iMinNow.mv_y + search_step);
00772 SEARCH_ONE_PIXEL_BIPRED;
00773 cand.mv_y = (short) (iMinNow.mv_y - search_step);
00774 SEARCH_ONE_PIXEL_BIPRED;
00775 }
00776
00777
00778 iMinNow.mv_x = best.mv_x;
00779 iMinNow.mv_y = best.mv_y;
00780 for (m = 0; m < 6; m++)
00781 {
00782 cand.mv_x = iMinNow.mv_x + Hexagon[m].mv_x;
00783 cand.mv_y = iMinNow.mv_y + Hexagon[m].mv_y;
00784 SEARCH_ONE_PIXEL_BIPRED;
00785 }
00786
00787 iMinNow = best;
00788 for(i = 1; i <= search_range / 4; i++)
00789 {
00790 for (m = 0; m < 16; m++)
00791 {
00792 cand.mv_x = (short) (iMinNow.mv_x + Big_Hexagon_X[m] * i);
00793 cand.mv_y = (short) (iMinNow.mv_y + Big_Hexagon_Y[m] * i);
00794 SEARCH_ONE_PIXEL_BIPRED;
00795 }
00796 }
00797 }
00798
00799
00800 if (blocktype > 1)
00801 {
00802 cand.mv_x = pic_pix_x + (p_UMHexSMP->pred_MV_uplayer_X / 4) * 4;
00803 cand.mv_y = pic_pix_y + (p_UMHexSMP->pred_MV_uplayer_Y / 4) * 4;
00804 SEARCH_ONE_PIXEL_BIPRED;
00805 }
00806
00807 if(center2.mv_x != pic_pix_x || center2.mv_x != pic_pix_y)
00808 {
00809 cand.mv_x = pic_pix_x;
00810 cand.mv_y = pic_pix_y;
00811 SEARCH_ONE_PIXEL_BIPRED;
00812
00813 iMinNow = best;
00814
00815 for (m = 0; m < 4; m++)
00816 {
00817 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00818 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00819 SEARCH_ONE_PIXEL_BIPRED;
00820 }
00821 }
00822
00823
00824
00825 if ((min_mcost<<2) < (p_UMHexSMP->ConvergeThreshold >> block_type_shift_factor[blocktype]))
00826 {
00827 iMinNow = best;
00828 for (m = 0; m < 4; m++)
00829 {
00830 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00831 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00832 SEARCH_ONE_PIXEL_BIPRED;
00833 }
00834 mv1->mv_x = (short) (best.mv_x - pic_pix_x);
00835 mv1->mv_y = (short) (best.mv_y - pic_pix_y);
00836 return min_mcost;
00837 }
00838
00839
00840 for (i = 0; i < search_range; i++)
00841 {
00842 iMinNow = best;
00843 for (m = 0; m < 6; m++)
00844 {
00845 cand.mv_x = iMinNow.mv_x + Hexagon[m].mv_x;
00846 cand.mv_y = iMinNow.mv_y + Hexagon[m].mv_y;
00847 SEARCH_ONE_PIXEL_BIPRED;
00848 }
00849
00850 if (best.mv_x == iMinNow.mv_x && best.mv_y == iMinNow.mv_y)
00851 {
00852 break;
00853 }
00854 }
00855
00856
00857 for (i = 0; i < search_range; i++)
00858 {
00859 iMinNow = best;
00860 for (m = 0; m < 4; m++)
00861 {
00862 cand.mv_x = iMinNow.mv_x + Diamond[m].mv_x;
00863 cand.mv_y = iMinNow.mv_y + Diamond[m].mv_y;
00864 SEARCH_ONE_PIXEL_BIPRED;
00865 }
00866
00867
00868 if (best.mv_x == iMinNow.mv_x && best.mv_y == iMinNow.mv_y)
00869 {
00870 break;
00871 }
00872 }
00873
00874 mv1->mv_x = (short) (best.mv_x - pic_pix_x);
00875 mv1->mv_y = (short) (best.mv_y - pic_pix_y);
00876 return min_mcost;
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886 void smpUMHEX_decide_intrabk_SAD(Macroblock *currMB)
00887 {
00888 Slice *currSlice = currMB->p_slice;
00889 ImageParameters *p_Img = currMB->p_Img;
00890 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00891
00892 if (currSlice->slice_type != I_SLICE)
00893 {
00894 if (currMB->pix_x == 0 && currMB->pix_y == 0)
00895 {
00896 p_UMHexSMP->flag_intra_SAD = 0;
00897 }
00898 else if (currMB->pix_x == 0)
00899 {
00900 p_UMHexSMP->flag_intra_SAD = p_UMHexSMP->flag_intra[(currMB->pix_x)>>4];
00901 }
00902 else if (currMB->pix_y == 0)
00903 {
00904 p_UMHexSMP->flag_intra_SAD = p_UMHexSMP->flag_intra[((currMB->pix_x)>>4)-1];
00905 }
00906 else
00907 {
00908 p_UMHexSMP->flag_intra_SAD = ((p_UMHexSMP->flag_intra[(currMB->pix_x)>>4])||
00909 (p_UMHexSMP->flag_intra[((currMB->pix_x)>>4)-1])||
00910 (p_UMHexSMP->flag_intra[((currMB->pix_x)>>4)+1])) ;
00911 }
00912 }
00913 return;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923 void smpUMHEX_skip_intrabk_SAD(Macroblock *currMB)
00924 {
00925 short i, j, k;
00926 ImageParameters *p_Img = currMB->p_Img;
00927 Slice *currSlice = currMB->p_slice;
00928 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00929
00930 if (p_Img->number > 0)
00931 {
00932 p_UMHexSMP->flag_intra[(currMB->pix_x)>>4] = (currMB->best_mode == 9 || currMB->best_mode == 10) ? 1 : 0;
00933 }
00934
00935 if (currSlice->slice_type != I_SLICE && (currMB->best_mode == 9 || currMB->best_mode == 10))
00936 {
00937 for (k=0; k < 9;k++)
00938 {
00939 for (j=0; j < 4; j++)
00940 {
00941 for (i=0; i < 4; i++)
00942 {
00943 p_UMHexSMP->l0_cost[k][j][i] = 0;
00944 p_UMHexSMP->l1_cost[k][j][i] = 0;
00945 }
00946 }
00947 }
00948 }
00949 return;
00950 }
00951
00952
00953
00954
00955
00956
00957
00958
00959 void smpUMHEX_setup(Macroblock *currMB,
00960 short ref,
00961 int list,
00962 int block_y,
00963 int block_x,
00964 int blocktype,
00965 short ******all_mv)
00966 {
00967 ImageParameters *p_Img = currMB->p_Img;
00968 UMHexSMPStruct *p_UMHexSMP = p_Img->p_UMHexSMP;
00969
00970 if (blocktype > 6)
00971 {
00972 p_UMHexSMP->pred_MV_uplayer_X = all_mv[list][ref][5][block_y][block_x][0];
00973 p_UMHexSMP->pred_MV_uplayer_Y = all_mv[list][ref][5][block_y][block_x][1];
00974 }
00975 else if (blocktype > 4)
00976 {
00977 p_UMHexSMP->pred_MV_uplayer_X = all_mv[list][ref][4][block_y][block_x][0];
00978 p_UMHexSMP->pred_MV_uplayer_Y = all_mv[list][ref][4][block_y][block_x][1];
00979 }
00980 else if (blocktype == 4)
00981 {
00982 p_UMHexSMP->pred_MV_uplayer_X = all_mv[list][ref][2][block_y][block_x][0];
00983 p_UMHexSMP->pred_MV_uplayer_Y = all_mv[list][ref][2][block_y][block_x][1];
00984 }
00985 else if (blocktype > 1)
00986 {
00987 p_UMHexSMP->pred_MV_uplayer_X = all_mv[list][ref][1][block_y][block_x][0];
00988 p_UMHexSMP->pred_MV_uplayer_Y = all_mv[list][ref][1][block_y][block_x][1];
00989 }
00990
00991 if (blocktype > 1)
00992 {
00993 if (blocktype > 6)
00994 {
00995 p_UMHexSMP->pred_SAD_uplayer = (list==1) ?
00996 (p_UMHexSMP->l1_cost[5][(currMB->block_y)+block_y][(currMB->block_x)+block_x])
00997 : (p_UMHexSMP->l0_cost[5][(currMB->block_y)+block_y][(currMB->block_x)+block_x]);
00998 p_UMHexSMP->pred_SAD_uplayer /= 2;
00999 }
01000 else if (blocktype > 4)
01001 {
01002 p_UMHexSMP->pred_SAD_uplayer = (list==1) ?
01003 (p_UMHexSMP->l1_cost[4][(currMB->block_y)+block_y][(currMB->block_x)+block_x])
01004 : (p_UMHexSMP->l0_cost[4][(currMB->block_y)+block_y][(currMB->block_x)+block_x]);
01005 p_UMHexSMP->pred_SAD_uplayer /= 2;
01006 }
01007 else if (blocktype == 4)
01008 {
01009 p_UMHexSMP->pred_SAD_uplayer = (list==1) ?
01010 (p_UMHexSMP->l1_cost[2][(currMB->block_y)+block_y][(currMB->block_x)+block_x])
01011 : (p_UMHexSMP->l0_cost[2][(currMB->block_y)+block_y][(currMB->block_x)+block_x]);
01012 p_UMHexSMP->pred_SAD_uplayer /= 2;
01013 }
01014 else
01015 {
01016 p_UMHexSMP->pred_SAD_uplayer = (list==1) ?
01017 (p_UMHexSMP->l1_cost[1][(currMB->block_y)+block_y][(currMB->block_x)+block_x])
01018 : (p_UMHexSMP->l0_cost[1][(currMB->block_y)+block_y][(currMB->block_x)+block_x]);
01019 p_UMHexSMP->pred_SAD_uplayer /= 2;
01020 }
01021
01022 p_UMHexSMP->pred_SAD_uplayer = p_UMHexSMP->flag_intra_SAD ? 0 : p_UMHexSMP->pred_SAD_uplayer;
01023 }
01024 }
01025