00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "contributors.h"
00017
00018 #include <limits.h>
00019
00020 #include "global.h"
00021 #include "image.h"
00022 #include "memalloc.h"
00023 #include "mb_access.h"
00024 #include "refbuf.h"
00025 #include "macroblock.h"
00026 #include "me_distortion.h"
00027 #include "me_epzs.h"
00028 #include "mv_search.h"
00029
00030 static const MotionVector search_point_hp[10] = {{0,0},{-2,0}, {0,2}, {2,0}, {0,-2}, {-2,2}, {2,2}, {2,-2}, {-2,-2}, {-2,2}};
00031 static const MotionVector search_point_qp[10] = {{0,0},{-1,0}, {0,1}, {1,0}, {0,-1}, {-1,1}, {1,1}, {1,-1}, {-1,-1}, {-1,1}};
00032
00033
00034
00035
00036
00037
00038
00039 int
00040 EPZSSubPelBlockMotionSearch (Macroblock *currMB,
00041 MotionVector *pred,
00042 MEBlock *mv_block,
00043 int min_mcost,
00044 int* lambda
00045 )
00046 {
00047 ImageParameters *p_Img = currMB->p_Img;
00048 EPZSParameters *p_EPZS = currMB->p_slice->p_EPZS;
00049 int pos, best_pos = 0, second_pos = 0, mcost;
00050 int second_mcost = INT_MAX;
00051 int max_pos2 = ( (!p_Img->start_me_refinement_hp || !p_Img->start_me_refinement_qp) ? imax(1, mv_block->search_pos2) : mv_block->search_pos2);
00052
00053 int list = mv_block->list;
00054 int cur_list = list + currMB->list_offset;
00055 short ref = mv_block->ref_idx;
00056 StorablePicture *ref_picture = p_Img->listX[cur_list][ref];
00057 MotionVector *mv = &mv_block->mv[list];
00058 MotionVector cand;
00059 MotionVector padded_mv = pad_MVs (*mv, mv_block);
00060 MotionVector pred_mv = pad_MVs (*pred, mv_block);
00061
00062 int start_pos = 5, end_pos = max_pos2;
00063 int lambda_factor = lambda[H_PEL];
00064 int lambda_dist = (((lambda_factor) * (2)) >> LAMBDA_ACCURACY_BITS);
00065 int sub_threshold = p_EPZS->subthres[mv_block->blocktype] + lambda_dist;
00066
00067
00068
00069
00070
00071
00072
00073
00074 for (best_pos = 0, pos = p_Img->start_me_refinement_hp; pos < 5; ++pos)
00075 {
00076 cand = add_MVs(search_point_hp[pos], &padded_mv);
00077
00078
00079 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred_mv);
00080
00081 mcost += mv_block->computePredHPel(ref_picture, mv_block, INT_MAX, &cand);
00082
00083 if (mcost < min_mcost)
00084 {
00085 second_mcost = min_mcost;
00086 second_pos = best_pos;
00087 min_mcost = mcost;
00088 best_pos = pos;
00089 }
00090 else if (mcost < second_mcost)
00091 {
00092 second_mcost = mcost;
00093 second_pos = pos;
00094 }
00095 }
00096
00097 if (best_pos ==0 && (pred->mv_x == mv->mv_x) && (pred->mv_y == mv->mv_y) && min_mcost < sub_threshold)
00098 return min_mcost;
00099
00100 if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
00101 {
00102 if (best_pos != 0 && second_pos != 0)
00103 {
00104 switch (best_pos ^ second_pos)
00105 {
00106 case 1:
00107 start_pos = 6;
00108 end_pos = 7;
00109 break;
00110 case 3:
00111 start_pos = 5;
00112 end_pos = 6;
00113 break;
00114 case 5:
00115 start_pos = 8;
00116 end_pos = 9;
00117 break;
00118 case 7:
00119 start_pos = 7;
00120 end_pos = 8;
00121 break;
00122 default:
00123 break;
00124 }
00125 }
00126 else
00127 {
00128 switch (best_pos + second_pos)
00129 {
00130 case 0:
00131 start_pos = 5;
00132 end_pos = 5;
00133 break;
00134 case 1:
00135 start_pos = 8;
00136 end_pos = 10;
00137 break;
00138 case 2:
00139 start_pos = 5;
00140 end_pos = 7;
00141 break;
00142 case 5:
00143 start_pos = 6;
00144 end_pos = 8;
00145 break;
00146 case 7:
00147 start_pos = 7;
00148 end_pos = 9;
00149 break;
00150 default:
00151 break;
00152 }
00153 }
00154
00155 for (pos = start_pos; pos < end_pos; ++pos)
00156 {
00157 cand = add_MVs(search_point_hp[pos], &padded_mv);
00158
00159
00160 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred_mv);
00161
00162 if (mcost >= min_mcost)
00163 continue;
00164
00165 mcost += mv_block->computePredHPel( ref_picture, mv_block, min_mcost - mcost, &cand);
00166
00167 if (mcost < min_mcost)
00168 {
00169 min_mcost = mcost;
00170 best_pos = pos;
00171 }
00172 }
00173 }
00174
00175 if (best_pos)
00176 {
00177 add_mvs(mv, &search_point_hp[best_pos]);
00178 padded_mv = pad_MVs (*mv, mv_block);
00179 }
00180
00181 if (min_mcost < sub_threshold)
00182 end_pos = 1;
00183 else
00184 end_pos = 5;
00185
00186 if ( !p_Img->start_me_refinement_qp )
00187 min_mcost = INT_MAX;
00188
00189
00190
00191
00192
00193
00194 lambda_factor = lambda[Q_PEL];
00195 second_pos = 0;
00196 second_mcost = INT_MAX;
00197
00198 for (best_pos = 0, pos = p_Img->start_me_refinement_qp; pos < end_pos; ++pos)
00199 {
00200 cand = add_MVs(search_point_qp[pos], &padded_mv);
00201
00202
00203 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred_mv);
00204 mcost += mv_block->computePredQPel(ref_picture, mv_block, INT_MAX, &cand);
00205
00206 if (mcost < min_mcost)
00207 {
00208 second_mcost = min_mcost;
00209 second_pos = best_pos;
00210 min_mcost = mcost;
00211 best_pos = pos;
00212 }
00213 else if (mcost < second_mcost)
00214 {
00215 second_mcost = mcost;
00216 second_pos = pos;
00217 }
00218 }
00219
00220
00221 if (min_mcost < sub_threshold)
00222 {
00223 return min_mcost;
00224 }
00225
00226 if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
00227 {
00228 start_pos = 5;
00229 end_pos = mv_block->search_pos4;
00230
00231 if (best_pos != 0 && second_pos != 0)
00232 {
00233 switch (best_pos ^ second_pos)
00234 {
00235 case 1:
00236 start_pos = 6;
00237 end_pos = 7;
00238 break;
00239 case 3:
00240 start_pos = 5;
00241 end_pos = 6;
00242 break;
00243 case 5:
00244 start_pos = 8;
00245 end_pos = 9;
00246 break;
00247 case 7:
00248 start_pos = 7;
00249 end_pos = 8;
00250 break;
00251 default:
00252 break;
00253 }
00254 }
00255 else
00256 {
00257 switch (best_pos + second_pos)
00258 {
00259
00260
00261
00262
00263 case 1:
00264 start_pos = 8;
00265 end_pos = 10;
00266 break;
00267 case 2:
00268 start_pos = 5;
00269 end_pos = 7;
00270 break;
00271 case 5:
00272 start_pos = 6;
00273 end_pos = 8;
00274 break;
00275 case 7:
00276 start_pos = 7;
00277 end_pos = 9;
00278 break;
00279 default:
00280 break;
00281 }
00282 }
00283
00284 for (pos = start_pos; pos < end_pos; ++pos)
00285 {
00286 cand = add_MVs(search_point_qp[pos], &padded_mv);
00287
00288
00289 mcost = mv_cost (p_Img, lambda_factor, &cand, &pred_mv);
00290
00291 if (mcost >= min_mcost)
00292 continue;
00293
00294 mcost += mv_block->computePredQPel(ref_picture, mv_block, min_mcost - mcost, &cand);
00295
00296 if (mcost < min_mcost)
00297 {
00298 min_mcost = mcost;
00299 best_pos = pos;
00300 }
00301 }
00302 }
00303 if (best_pos)
00304 {
00305 add_mvs(mv, &search_point_qp[best_pos]);
00306 }
00307
00308
00309 return min_mcost;
00310 }
00311
00312
00313
00314
00315
00316
00317
00318 int
00319 EPZSSubPelBlockSearchBiPred (Macroblock *currMB,
00320 MEBlock *mv_block,
00321 int list,
00322 MotionVector *pred_mv1,
00323 MotionVector *pred_mv2,
00324 MotionVector *mv1,
00325 MotionVector *mv2,
00326 int min_mcost,
00327 int* lambda
00328 )
00329 {
00330 ImageParameters *p_Img = currMB->p_Img;
00331
00332 int list_offset = p_Img->mb_data[p_Img->current_mb_nr].list_offset;
00333
00334 int pos, best_pos = 0, second_pos = 0, mcost;
00335 int second_mcost = INT_MAX;
00336
00337 MotionVector cand, sand;
00338
00339 int start_hp = (min_mcost == INT_MAX) ? 0 : p_Img->start_me_refinement_hp;
00340 int max_pos2 = ( (!p_Img->start_me_refinement_hp || !p_Img->start_me_refinement_qp) ? imax(1, mv_block->search_pos2) : mv_block->search_pos2);
00341
00342 short ref = mv_block->ref_idx;
00343 StorablePicture *ref_picture1 = p_Img->listX[list + list_offset][ref];
00344 StorablePicture *ref_picture2 = p_Img->listX[(list ^ 1) + list_offset][0];
00345
00346 int start_pos = 5, end_pos = max_pos2;
00347 int lambda_factor = lambda[H_PEL];
00348
00349 sand = pad_MVs(*mv2, mv_block);
00350
00351
00352
00353
00354
00355
00356
00357 for (best_pos = 0, pos = start_hp; pos < 5; ++pos)
00358 {
00359 cand = add_MVs(search_point_hp[pos], mv1);
00360
00361
00362 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv1);
00363 mcost += mv_cost (p_Img, lambda_factor, mv2, pred_mv2);
00364
00365 cand = pad_MVs(cand, mv_block);
00366 mcost += mv_block->computeBiPredHPel(ref_picture1, ref_picture2, mv_block, INT_MAX, &cand, &sand);
00367
00368 if (mcost < min_mcost)
00369 {
00370 second_mcost = min_mcost;
00371 second_pos = best_pos;
00372 min_mcost = mcost;
00373 best_pos = pos;
00374 }
00375 else if (mcost < second_mcost)
00376 {
00377 second_mcost = mcost;
00378 second_pos = pos;
00379 }
00380 }
00381
00382
00383
00384
00385 if (best_pos !=0 || (iabs(pred_mv1->mv_x - mv1->mv_x) + iabs(pred_mv1->mv_y - mv1->mv_y)))
00386 {
00387 if (best_pos != 0 && second_pos != 0)
00388 {
00389 switch (best_pos ^ second_pos)
00390 {
00391 case 1:
00392 start_pos = 6;
00393 end_pos = 7;
00394 break;
00395 case 3:
00396 start_pos = 5;
00397 end_pos = 6;
00398 break;
00399 case 5:
00400 start_pos = 8;
00401 end_pos = 9;
00402 break;
00403 case 7:
00404 start_pos = 7;
00405 end_pos = 8;
00406 break;
00407 default:
00408 break;
00409 }
00410 }
00411 else
00412 {
00413 switch (best_pos + second_pos)
00414 {
00415 case 0:
00416 start_pos = 5;
00417 end_pos = 5;
00418 break;
00419 case 1:
00420 start_pos = 8;
00421 end_pos = 10;
00422 break;
00423 case 2:
00424 start_pos = 5;
00425 end_pos = 7;
00426 break;
00427 case 5:
00428 start_pos = 6;
00429 end_pos = 8;
00430 break;
00431 case 7:
00432 start_pos = 7;
00433 end_pos = 9;
00434 break;
00435 default:
00436 break;
00437 }
00438 }
00439
00440 for (pos = start_pos; pos < end_pos; ++pos)
00441 {
00442 cand = add_MVs(search_point_hp[pos], mv1);
00443
00444
00445 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv1);
00446 mcost += mv_cost (p_Img, lambda_factor, mv2, pred_mv2);
00447 if (mcost >= min_mcost) continue;
00448 cand = pad_MVs(cand, mv_block);
00449
00450 mcost += mv_block->computeBiPredHPel(ref_picture1, ref_picture2, mv_block, min_mcost - mcost, &cand, &sand);
00451
00452 if (mcost < min_mcost)
00453 {
00454 min_mcost = mcost;
00455 best_pos = pos;
00456 }
00457 }
00458 }
00459
00460 if (best_pos)
00461 {
00462
00463 add_mvs (mv1, &search_point_hp[best_pos]);
00464
00465 }
00466
00467 if ( !p_Img->start_me_refinement_qp )
00468 min_mcost = INT_MAX;
00469
00470
00471
00472
00473
00474
00475 lambda_factor = lambda[Q_PEL];
00476 second_pos = 0;
00477 second_mcost = INT_MAX;
00478
00479 for (best_pos = 0, pos = p_Img->start_me_refinement_qp; pos < 5; ++pos)
00480 {
00481 cand = add_MVs(search_point_qp[pos], mv1);
00482
00483
00484 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv1);
00485 mcost += mv_cost (p_Img, lambda_factor, mv2, pred_mv2);
00486 cand = pad_MVs(cand, mv_block);
00487
00488 mcost += mv_block->computeBiPredQPel(ref_picture1, ref_picture2, mv_block, INT_MAX, &cand, &sand);
00489
00490 if (mcost < min_mcost)
00491 {
00492 second_mcost = min_mcost;
00493 second_pos = best_pos;
00494 min_mcost = mcost;
00495 best_pos = pos;
00496 }
00497 else if (mcost < second_mcost)
00498 {
00499 second_mcost = mcost;
00500 second_pos = pos;
00501 }
00502 }
00503
00504 if (best_pos !=0 || (iabs(pred_mv1->mv_x - mv1->mv_x) + iabs(pred_mv1->mv_y - mv1->mv_y)))
00505 {
00506 start_pos = 5;
00507 end_pos = mv_block->search_pos4;
00508
00509 if (best_pos != 0 && second_pos != 0)
00510 {
00511 switch (best_pos ^ second_pos)
00512 {
00513 case 1:
00514 start_pos = 6;
00515 end_pos = 7;
00516 break;
00517 case 3:
00518 start_pos = 5;
00519 end_pos = 6;
00520 break;
00521 case 5:
00522 start_pos = 8;
00523 end_pos = 9;
00524 break;
00525 case 7:
00526 start_pos = 7;
00527 end_pos = 8;
00528 break;
00529 default:
00530 break;
00531 }
00532 }
00533 else
00534 {
00535 switch (best_pos + second_pos)
00536 {
00537
00538
00539
00540
00541 case 1:
00542 start_pos = 8;
00543 end_pos = 10;
00544 break;
00545 case 2:
00546 start_pos = 5;
00547 end_pos = 7;
00548 break;
00549 case 5:
00550 start_pos = 6;
00551 end_pos = 8;
00552 break;
00553 case 7:
00554 start_pos = 7;
00555 end_pos = 9;
00556 break;
00557 default:
00558 break;
00559 }
00560 }
00561
00562 for (pos = start_pos; pos < end_pos; ++pos)
00563 {
00564 cand = add_MVs(search_point_qp[pos], mv1);
00565
00566
00567 mcost = mv_cost (p_Img, lambda_factor, &cand, pred_mv1);
00568 mcost += mv_cost (p_Img, lambda_factor, mv2, pred_mv2);
00569 if (mcost >= min_mcost) continue;
00570
00571 cand = pad_MVs(cand, mv_block);
00572 mcost += mv_block->computeBiPredQPel(ref_picture1, ref_picture2, mv_block, min_mcost - mcost, &cand, &sand);
00573
00574 if (mcost < min_mcost)
00575 {
00576 min_mcost = mcost;
00577 best_pos = pos;
00578 }
00579 }
00580 }
00581 if (best_pos)
00582 {
00583 add_mvs(mv1, &search_point_qp[best_pos]);
00584 }
00585
00586
00587 return min_mcost;
00588 }
00589