00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "contributors.h"
00025
00026 #include <math.h>
00027 #include <limits.h>
00028 #include <time.h>
00029 #include <sys/timeb.h>
00030
00031 #include "global.h"
00032
00033 #include "image.h"
00034 #include "mv-search.h"
00035 #include "refbuf.h"
00036 #include "memalloc.h"
00037 #include "mb_access.h"
00038 #include "macroblock.h"
00039 #include "mc_prediction.h"
00040 #include "conformance.h"
00041
00042
00043 #include "me_distortion.h"
00044
00045
00046 #include "me_epzs.h"
00047 #include "me_fullfast.h"
00048 #include "me_fullsearch.h"
00049 #include "me_umhex.h"
00050 #include "me_umhexsmp.h"
00051 #include "rdoq.h"
00052
00053
00054
00055 int max_mvd;
00056 short* spiral_search_x;
00057 short* spiral_search_y;
00058 short* spiral_hpel_search_x;
00059 short* spiral_hpel_search_y;
00060 SearchWindow searchrange;
00061
00062 int* mvbits;
00063 int* refbits;
00064 int* byte_abs;
00065 int**** motion_cost;
00066 int byte_abs_range;
00067
00068 static int diff [16];
00069 static int diff64[64];
00070 static imgpel orig_pic [768];
00071
00072 int (*IntPelME) (Macroblock *, imgpel *, short, int, char ***, short ****,
00073 int, int, int, MotionVector *, MotionVector *, int, int, int, int);
00074
00075 int (*BiPredME) (Macroblock *, imgpel *, short, int, char ***, short ****,
00076 int, int, int, MotionVector *, MotionVector *, MotionVector *, MotionVector *, int, int, int, int, int);
00077
00078 int (*SubPelBiPredME) (imgpel* orig_pic, short ref, int list, int pic_pix_x, int pic_pix_y,
00079 int blocktype, MotionVector *pred_mv1, MotionVector *pred_mv2, MotionVector *mv1, MotionVector *mv2,
00080 int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights);
00081 int (*SubPelME) (imgpel* orig_pic, short ref, int list, int list_offset, int pic_pix_x, int pic_pix_y,
00082 int blocktype, MotionVector *pred_mv, MotionVector *mv,
00083 int search_pos2, int search_pos4, int min_mcost, int* lambda_factor, int apply_weights);
00084
00085
00086 int BlockMotionSearch (Macroblock *currMB, short,int,int,int,int,int, int*);
00087 int BiPredBlockMotionSearch(Macroblock *currMB, MotionVector*, MotionVector*, short, int, int, int, int , int, int, int*);
00088
00089 int GetSkipCostMB (Macroblock *currMB);
00090
00091 extern ColocatedParams *Co_located;
00092 extern const short block_type_shift_factor[8];
00093
00094
00095
00096
00097
00098
00099
00100 void set_access_method(int *access_method, MotionVector *blk, int min_x, int min_y, int max_x, int max_y)
00101 {
00102 if ( (blk->mv_x > min_x) && (blk->mv_x < max_x) && (blk->mv_y > min_y) && (blk->mv_y < max_y))
00103 {
00104 *access_method = FAST_ACCESS;
00105 }
00106 else
00107 {
00108 *access_method = UMV_ACCESS;
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 void init_ME_engine(int SearchMode)
00119 {
00120 switch (SearchMode)
00121 {
00122 case EPZS:
00123 IntPelME = EPZSPelBlockMotionSearch;
00124 BiPredME = EPZSBiPredBlockMotionSearch;
00125 SubPelBiPredME = (params->EPZSSubPelMEBiPred) ? EPZSSubPelBlockSearchBiPred : SubPelBlockSearchBiPred;
00126 SubPelME = (params->EPZSSubPelME) ? EPZSSubPelBlockMotionSearch : SubPelBlockMotionSearch;
00127 break;
00128 case UM_HEX:
00129 IntPelME = UMHEXIntegerPelBlockMotionSearch;
00130 BiPredME = UMHEXBipredIntegerPelBlockMotionSearch;
00131 SubPelBiPredME = SubPelBlockSearchBiPred;
00132 SubPelME = UMHEXSubPelBlockME;
00133 break;
00134 case UM_HEX_SIMPLE:
00135 IntPelME = smpUMHEXIntegerPelBlockMotionSearch;
00136 BiPredME = smpUMHEXBipredIntegerPelBlockMotionSearch;
00137 SubPelBiPredME = SubPelBlockSearchBiPred;
00138 SubPelME = smpUMHEXSubPelBlockME;
00139 break;
00140 case FULL_SEARCH:
00141 IntPelME = FullPelBlockMotionSearch;
00142 BiPredME = FullPelBlockMotionBiPred;
00143 SubPelBiPredME = SubPelBlockSearchBiPred;
00144 SubPelME = SubPelBlockMotionSearch;
00145 break;
00146 case FAST_FULL_SEARCH:
00147 default:
00148 IntPelME = FastFullPelBlockMotionSearch;
00149 BiPredME = FullPelBlockMotionBiPred;
00150 SubPelBiPredME = SubPelBlockSearchBiPred;
00151 SubPelME = SubPelBlockMotionSearch;
00152 break;
00153 }
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 void PrepareMEParams(int apply_weights, int ChromaMEEnable, int list, int ref)
00163 {
00164 if (apply_weights)
00165 {
00166 weight_luma = wp_weight[list][ref][0];
00167 offset_luma = wp_offset[list][ref][0];
00168
00169 if ( ChromaMEEnable)
00170 {
00171 weight_cr[0] = wp_weight[list][ref][1];
00172 weight_cr[1] = wp_weight[list][ref][2];
00173 offset_cr[0] = wp_offset[list][ref][1];
00174 offset_cr[1] = wp_offset[list][ref][2];
00175 }
00176 }
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 void PrepareBiPredMEParams(int apply_weights, int ChromaMEEnable, int list, int list_offset, int ref)
00186 {
00187 if (apply_weights)
00188 {
00189 if (list == LIST_0)
00190 {
00191 weight1 = wbp_weight[list_offset ][ref][0][0];
00192 weight2 = wbp_weight[list_offset + LIST_1][ref][0][0];
00193 offsetBi = (wp_offset[list_offset ][ref][0] + wp_offset[list_offset + LIST_1][ref][0] + 1)>>1;
00194
00195 if ( ChromaMEEnable)
00196 {
00197 weight1_cr[0] = wbp_weight[list_offset ][ref][0][1];
00198 weight1_cr[1] = wbp_weight[list_offset ][ref][0][2];
00199 weight2_cr[0] = wbp_weight[list_offset + LIST_1][ref][0][1];
00200 weight2_cr[1] = wbp_weight[list_offset + LIST_1][ref][0][2];
00201
00202 offsetBi_cr[0] = (wp_offset[list_offset ][ref][1] + wp_offset[list_offset + LIST_1][ref][1] + 1) >> 1;
00203 offsetBi_cr[1] = (wp_offset[list_offset ][ref][2] + wp_offset[list_offset + LIST_1][ref][2] + 1) >> 1;
00204 }
00205 }
00206 else
00207 {
00208 weight1 = wbp_weight[list_offset + LIST_1][0 ][ref][0];
00209 weight2 = wbp_weight[list_offset ][0 ][ref][0];
00210 offsetBi = (wp_offset[list_offset + LIST_1][0][0] + wp_offset[list_offset][0][0] + 1)>>1;
00211
00212 if ( ChromaMEEnable)
00213 {
00214 weight1_cr[0] = wbp_weight[list_offset + LIST_1][0 ][ref][1];
00215 weight1_cr[1] = wbp_weight[list_offset + LIST_1][0 ][ref][2];
00216 weight2_cr[0] = wbp_weight[list_offset ][0 ][ref][1];
00217 weight2_cr[1] = wbp_weight[list_offset ][0 ][ref][2];
00218
00219 offsetBi_cr[0] = (wp_offset[list_offset + LIST_1][0 ][1] + wp_offset[list_offset ][0 ][1] + 1) >> 1;
00220 offsetBi_cr[1] = (wp_offset[list_offset + LIST_1][0 ][2] + wp_offset[list_offset ][0 ][2] + 1) >> 1;
00221 }
00222 }
00223 }
00224 else
00225 {
00226 weight1 = 1<<luma_log_weight_denom;
00227 weight2 = 1<<luma_log_weight_denom;
00228 offsetBi = 0;
00229 if ( ChromaMEEnable)
00230 {
00231 weight1_cr[0] = 1<<chroma_log_weight_denom;
00232 weight1_cr[1] = 1<<chroma_log_weight_denom;
00233 weight2_cr[0] = 1<<chroma_log_weight_denom;
00234 weight2_cr[1] = 1<<chroma_log_weight_denom;
00235 offsetBi_cr[0] = 0;
00236 offsetBi_cr[1] = 0;
00237 }
00238 }
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 void get_neighbors(Macroblock *currMB,
00248 PixelPos *block_a,
00249 PixelPos *block_b,
00250 PixelPos *block_c,
00251 PixelPos *block_d,
00252 int mb_x,
00253 int mb_y,
00254 int blockshape_x
00255 )
00256 {
00257 int *mb_size = img->mb_size[IS_LUMA];
00258
00259 get4x4Neighbour(currMB, mb_x - 1, mb_y , mb_size, block_a);
00260 get4x4Neighbour(currMB, mb_x, mb_y - 1, mb_size, block_b);
00261 get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, block_c);
00262 get4x4Neighbour(currMB, mb_x - 1, mb_y - 1, mb_size, block_d);
00263
00264 if (mb_y > 0)
00265 {
00266 if (mb_x < 8)
00267 {
00268 if (mb_y == 8 )
00269 {
00270 if (blockshape_x == MB_BLOCK_SIZE)
00271 block_c->available = 0;
00272 }
00273 else if (mb_x + blockshape_x == 8)
00274 {
00275 block_c->available = 0;
00276 }
00277 }
00278 else if (mb_x + blockshape_x == MB_BLOCK_SIZE)
00279 {
00280 block_c->available = 0;
00281 }
00282 }
00283
00284 if (!block_c->available)
00285 {
00286 *block_c = *block_d;
00287 }
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 void GetMotionVectorPredictor (Macroblock *currMB,
00297 PixelPos *block_a,
00298 PixelPos *block_b,
00299 PixelPos *block_c,
00300 short pmv[2],
00301 char **refPic,
00302 short ***tmp_mv,
00303 short ref_frame,
00304 int mb_x,
00305 int mb_y,
00306 int blockshape_x,
00307 int blockshape_y)
00308 {
00309 int mv_a, mv_b, mv_c, pred_vec=0;
00310 int mvPredType, rFrameL, rFrameU, rFrameUR;
00311 int hv;
00312
00313 mvPredType = MVPRED_MEDIAN;
00314
00315 if (!img->MbaffFrameFlag)
00316 {
00317 rFrameL = block_a->available ? refPic[block_a->pos_y][block_a->pos_x] : -1;
00318 rFrameU = block_b->available ? refPic[block_b->pos_y][block_b->pos_x] : -1;
00319 rFrameUR = block_c->available ? refPic[block_c->pos_y][block_c->pos_x] : -1;
00320 }
00321 else
00322 {
00323 if (currMB->mb_field)
00324 {
00325 rFrameL = block_a->available
00326 ? (img->mb_data[block_a->mb_addr].mb_field
00327 ? refPic[block_a->pos_y][block_a->pos_x]
00328 : refPic[block_a->pos_y][block_a->pos_x] * 2) : -1;
00329 rFrameU = block_b->available
00330 ? (img->mb_data[block_b->mb_addr].mb_field
00331 ? refPic[block_b->pos_y][block_b->pos_x]
00332 : refPic[block_b->pos_y][block_b->pos_x] * 2) : -1;
00333 rFrameUR = block_c->available
00334 ? (img->mb_data[block_c->mb_addr].mb_field
00335 ? refPic[block_c->pos_y][block_c->pos_x]
00336 : refPic[block_c->pos_y][block_c->pos_x] * 2) : -1;
00337 }
00338 else
00339 {
00340 rFrameL = block_a->available
00341 ? (img->mb_data[block_a->mb_addr].mb_field
00342 ? refPic[block_a->pos_y][block_a->pos_x] >>1
00343 : refPic[block_a->pos_y][block_a->pos_x]) : -1;
00344 rFrameU = block_b->available
00345 ? (img->mb_data[block_b->mb_addr].mb_field
00346 ? refPic[block_b->pos_y][block_b->pos_x] >>1
00347 : refPic[block_b->pos_y][block_b->pos_x]) : -1;
00348 rFrameUR = block_c->available
00349 ? (img->mb_data[block_c->mb_addr].mb_field
00350 ? refPic[block_c->pos_y][block_c->pos_x] >>1
00351 : refPic[block_c->pos_y][block_c->pos_x]) : -1;
00352 }
00353 }
00354
00355
00356
00357
00358 if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
00359 mvPredType = MVPRED_L;
00360 else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
00361 mvPredType = MVPRED_U;
00362 else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
00363 mvPredType = MVPRED_UR;
00364
00365 if(blockshape_x == 8 && blockshape_y == 16)
00366 {
00367 if(mb_x == 0)
00368 {
00369 if(rFrameL == ref_frame)
00370 mvPredType = MVPRED_L;
00371 }
00372 else
00373 {
00374 if( rFrameUR == ref_frame)
00375 mvPredType = MVPRED_UR;
00376 }
00377 }
00378 else if(blockshape_x == 16 && blockshape_y == 8)
00379 {
00380 if(mb_y == 0)
00381 {
00382 if(rFrameU == ref_frame)
00383 mvPredType = MVPRED_U;
00384 }
00385 else
00386 {
00387 if(rFrameL == ref_frame)
00388 mvPredType = MVPRED_L;
00389 }
00390 }
00391
00392 for (hv=0; hv < 2; hv++)
00393 {
00394 if (!img->MbaffFrameFlag || hv == 0)
00395 {
00396 mv_a = block_a->available ? tmp_mv[block_a->pos_y][block_a->pos_x][hv] : 0;
00397 mv_b = block_b->available ? tmp_mv[block_b->pos_y][block_b->pos_x][hv] : 0;
00398 mv_c = block_c->available ? tmp_mv[block_c->pos_y][block_c->pos_x][hv] : 0;
00399 }
00400 else
00401 {
00402 if (currMB->mb_field)
00403 {
00404 mv_a = block_a->available ? img->mb_data[block_a->mb_addr].mb_field
00405 ? tmp_mv[block_a->pos_y][block_a->pos_x][hv]
00406 : tmp_mv[block_a->pos_y][block_a->pos_x][hv] / 2
00407 : 0;
00408 mv_b = block_b->available ? img->mb_data[block_b->mb_addr].mb_field
00409 ? tmp_mv[block_b->pos_y][block_b->pos_x][hv]
00410 : tmp_mv[block_b->pos_y][block_b->pos_x][hv] / 2
00411 : 0;
00412 mv_c = block_c->available ? img->mb_data[block_c->mb_addr].mb_field
00413 ? tmp_mv[block_c->pos_y][block_c->pos_x][hv]
00414 : tmp_mv[block_c->pos_y][block_c->pos_x][hv] / 2
00415 : 0;
00416 }
00417 else
00418 {
00419 mv_a = block_a->available ? img->mb_data[block_a->mb_addr].mb_field
00420 ? tmp_mv[block_a->pos_y][block_a->pos_x][hv] * 2
00421 : tmp_mv[block_a->pos_y][block_a->pos_x][hv]
00422 : 0;
00423 mv_b = block_b->available ? img->mb_data[block_b->mb_addr].mb_field
00424 ? tmp_mv[block_b->pos_y][block_b->pos_x][hv] * 2
00425 : tmp_mv[block_b->pos_y][block_b->pos_x][hv]
00426 : 0;
00427 mv_c = block_c->available ? img->mb_data[block_c->mb_addr].mb_field
00428 ? tmp_mv[block_c->pos_y][block_c->pos_x][hv] * 2
00429 : tmp_mv[block_c->pos_y][block_c->pos_x][hv]
00430 : 0;
00431 }
00432 }
00433
00434 switch (mvPredType)
00435 {
00436 case MVPRED_MEDIAN:
00437 if(!(block_b->available || block_c->available))
00438 {
00439 pred_vec = mv_a;
00440 }
00441 else
00442 {
00443 pred_vec = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c));
00444 }
00445 break;
00446 case MVPRED_L:
00447 pred_vec = mv_a;
00448 break;
00449 case MVPRED_U:
00450 pred_vec = mv_b;
00451 break;
00452 case MVPRED_UR:
00453 pred_vec = mv_c;
00454 break;
00455 default:
00456 break;
00457 }
00458
00459 pmv[hv] = (short) pred_vec;
00460 }
00461 }
00462
00463
00464
00465
00466
00467
00468
00469 void Init_Motion_Search_Module (void)
00470 {
00471 int bits, i_min, i_max, k;
00472 int i, l;
00473
00474 int search_range = params->search_range;
00475 int max_search_points = imax(9, (2 * search_range + 1) * (2 * search_range + 1));
00476 int max_ref_bits = 1 + 2 * (int)floor(log(imax(16, img->max_num_references + 1)) / log(2) + 1e-10);
00477 int max_ref = (1<<((max_ref_bits>>1)+1))-1;
00478 int number_of_subpel_positions = 4 * (2*search_range+3);
00479 int max_mv_bits = 3 + 2 * (int)ceil (log(number_of_subpel_positions + 1) / log(2) + 1e-10);
00480 max_mvd = (1<<( max_mv_bits >>1) ) - 1;
00481 byte_abs_range = (imax(img->max_imgpel_value_comp[0],img->max_imgpel_value_comp[1]) + 1) * 64;
00482
00483
00484
00485 if ((spiral_search_x = (short*)calloc(max_search_points, sizeof(short))) == NULL)
00486 no_mem_exit("Init_Motion_Search_Module: spiral_search_x");
00487 if ((spiral_search_y = (short*)calloc(max_search_points, sizeof(short))) == NULL)
00488 no_mem_exit("Init_Motion_Search_Module: spiral_search_y");
00489 if ((spiral_hpel_search_x = (short*)calloc(max_search_points, sizeof(short))) == NULL)
00490 no_mem_exit("Init_Motion_Search_Module: spiral_hpel_search_x");
00491 if ((spiral_hpel_search_y = (short*)calloc(max_search_points, sizeof(short))) == NULL)
00492 no_mem_exit("Init_Motion_Search_Module: spiral_hpel_search_y");
00493
00494 if ((mvbits = (int*)calloc(2 * max_mvd + 1, sizeof(int))) == NULL)
00495 no_mem_exit("Init_Motion_Search_Module: mvbits");
00496
00497 if ((refbits = (int*)calloc(max_ref, sizeof(int))) == NULL)
00498 no_mem_exit("Init_Motion_Search_Module: refbits");
00499 if ((byte_abs = (int*)calloc(byte_abs_range, sizeof(int))) == NULL)
00500 no_mem_exit("Init_Motion_Search_Module: byte_abs");
00501
00502 if (img->max_num_references)
00503 get_mem4Dint (&motion_cost, 8, 2, img->max_num_references, 4);
00504
00505
00506 mvbits += max_mvd;
00507 byte_abs += byte_abs_range/2;
00508
00509
00510
00511
00512 mvbits[0] = 1;
00513 for (bits=3; bits<=max_mv_bits; bits+=2)
00514 {
00515 i_max = 1 << (bits >> 1);
00516 i_min = i_max >> 1;
00517
00518 for (i = i_min; i < i_max; i++)
00519 mvbits[-i] = mvbits[i] = bits;
00520 }
00521
00522
00523 refbits[0] = 1;
00524 for (bits=3; bits<=max_ref_bits; bits+=2)
00525 {
00526 i_max = (1 << ((bits >> 1) + 1)) - 1;
00527 i_min = i_max >> 1;
00528
00529 for (i = i_min; i < i_max; i++)
00530 refbits[i] = bits;
00531 }
00532
00533
00534 byte_abs[0] = 0;
00535
00536
00537
00538
00539 for (i=1; i<byte_abs_range/2; i++)
00540 {
00541 byte_abs[i] = byte_abs[-i] = i;
00542 }
00543
00544
00545 spiral_search_x[0] = spiral_search_y[0] = 0;
00546 spiral_hpel_search_x[0] = spiral_hpel_search_y[0] = 0;
00547
00548 for (k=1, l=1; l <= imax(1,search_range); l++)
00549 {
00550 for (i=-l+1; i< l; i++)
00551 {
00552 spiral_search_x[k] = i;
00553 spiral_search_y[k] = -l;
00554 spiral_hpel_search_x[k] = i<<1;
00555 spiral_hpel_search_y[k++] = -l<<1;
00556 spiral_search_x[k] = i;
00557 spiral_search_y[k] = l;
00558 spiral_hpel_search_x[k] = i<<1;
00559 spiral_hpel_search_y[k++] = l<<1;
00560 }
00561 for (i=-l; i<=l; i++)
00562 {
00563 spiral_search_x[k] = -l;
00564 spiral_search_y[k] = i;
00565 spiral_hpel_search_x[k] = -l<<1;
00566 spiral_hpel_search_y[k++] = i<<1;
00567 spiral_search_x[k] = l;
00568 spiral_search_y[k] = i;
00569 spiral_hpel_search_x[k] = l<<1;
00570 spiral_hpel_search_y[k++] = i<<1;
00571 }
00572 }
00573
00574
00575 start_me_refinement_hp = (params->ChromaMEEnable == 1 || params->MEErrorMetric[F_PEL] != params->MEErrorMetric[H_PEL] ) ? 0 : 1;
00576 start_me_refinement_qp = (params->ChromaMEEnable == 1 || params->MEErrorMetric[H_PEL] != params->MEErrorMetric[Q_PEL] ) ? 0 : 1;
00577
00578
00579 for (i=0; i<3; i++)
00580 {
00581 switch(params->MEErrorMetric[i])
00582 {
00583 case ERROR_SAD:
00584 computeUniPred[i] = computeSAD;
00585 computeUniPred[i + 3] = computeSADWP;
00586 computeBiPred1[i] = computeBiPredSAD1;
00587 computeBiPred2[i] = computeBiPredSAD2;
00588 break;
00589 case ERROR_SSE:
00590 computeUniPred[i] = computeSSE;
00591 computeUniPred[i + 3] = computeSSEWP;
00592 computeBiPred1[i] = computeBiPredSSE1;
00593 computeBiPred2[i] = computeBiPredSSE2;
00594 break;
00595 case ERROR_SATD :
00596 default:
00597 computeUniPred[i] = computeSATD;
00598 computeUniPred[i + 3] = computeSATDWP;
00599 computeBiPred1[i] = computeBiPredSATD1;
00600 computeBiPred2[i] = computeBiPredSATD2;
00601 break;
00602 }
00603 }
00604 if (!params->IntraProfile)
00605 {
00606 if(params->SearchMode == FAST_FULL_SEARCH)
00607 InitializeFastFullIntegerSearch ();
00608
00609 init_ME_engine(params->SearchMode);
00610
00611 if (params->SearchMode == UM_HEX)
00612 UMHEX_DefineThreshold();
00613 }
00614 }
00615
00616
00617
00618
00619
00620
00621
00622 void
00623 Clear_Motion_Search_Module ()
00624 {
00625
00626 mvbits -= max_mvd;
00627 byte_abs -= byte_abs_range/2;
00628
00629
00630 free (spiral_search_x);
00631 free (spiral_search_y);
00632 free (spiral_hpel_search_x);
00633 free (spiral_hpel_search_y);
00634 free (mvbits);
00635 free (refbits);
00636 free (byte_abs);
00637
00638 if (motion_cost)
00639 free_mem4Dint (motion_cost);
00640
00641 if ((params->SearchMode == FAST_FULL_SEARCH) && (!params->IntraProfile) )
00642 ClearFastFullIntegerSearch ();
00643 }
00644
00645 static inline int mv_bits_cost(short ***all_mv, short ***p_mv, int by, int bx, int step_v0, int step_v, int step_h0, int step_h, int mvd_bits)
00646 {
00647 int v, h;
00648 for (v=by; v<by + step_v0; v+=step_v)
00649 {
00650 for (h=bx; h<bx + step_h0; h+=step_h)
00651 {
00652 mvd_bits += mvbits[ all_mv[v][h][0] - p_mv[v][h][0] ];
00653 mvd_bits += mvbits[ all_mv[v][h][1] - p_mv[v][h][1] ];
00654 }
00655 }
00656 return mvd_bits;
00657 }
00658
00659 static inline int mv_bit_cost(Macroblock *currMB, short ***all_mv, int cur_list, int cur_ref, int by, int bx, int step_v0, int step_v, int step_h0, int step_h, int mvd_bits)
00660 {
00661 int v, h;
00662 short predMV[2];
00663 static PixelPos block_a, block_b, block_c, block_d;
00664 PicMotionParams *motion = &enc_picture->motion;
00665
00666 for (v=by; v<by + step_v0; v+=step_v)
00667 {
00668 for (h=bx; h<bx + step_h0; h+=step_h)
00669 {
00670
00671 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, h, v, step_h);
00672
00673 GetMotionVectorPredictor (currMB, &block_a, &block_b, &block_c, predMV, motion->ref_idx[cur_list], motion->mv[cur_list], cur_ref, h, v, step_h, step_v);
00674
00675 mvd_bits += mvbits[ all_mv[v][h][0] - predMV[0] ];
00676 mvd_bits += mvbits[ all_mv[v][h][1] - predMV[1] ];
00677 }
00678 }
00679
00680 return mvd_bits;
00681 }
00682
00683
00684
00685
00686
00687
00688
00689 int BPredPartitionCost (Macroblock *currMB,
00690 int blocktype,
00691 int block8x8,
00692 short ref_l0,
00693 short ref_l1,
00694 int lambda_factor,
00695 int list)
00696 {
00697 static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
00698 static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
00699
00700 int curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
00701 int bsx = imin(params->blc_size[blocktype][0], 8);
00702 int bsy = imin(params->blc_size[blocktype][1], 8);
00703
00704 int pic_pix_x, pic_pix_y, block_x, block_y;
00705 int v, h, mcost, i, j, k;
00706 int mvd_bits = 0;
00707 int parttype = (blocktype < 4 ? blocktype : 4);
00708 int step_h0 = (params->part_size[ parttype][0]);
00709 int step_v0 = (params->part_size[ parttype][1]);
00710 int step_h = (params->part_size[blocktype][0]);
00711 int step_v = (params->part_size[blocktype][1]);
00712 int bxx, byy;
00713 int by0_part = by0[parttype][block8x8];
00714 int bx0_part = bx0[parttype][block8x8];
00715
00716 short ***all_mv_l0 = img->bipred_mv[list][LIST_0][ref_l0][blocktype];
00717 short ***all_mv_l1 = img->bipred_mv[list][LIST_1][ref_l1][blocktype];
00718 imgpel **mb_pred = img->mb_pred[0];
00719
00720
00721 mvd_bits = mv_bit_cost(currMB, all_mv_l0, LIST_0, ref_l0, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits);
00722
00723 mvd_bits = mv_bit_cost(currMB, all_mv_l1, LIST_1, ref_l1, by0_part, bx0_part, step_v0, step_v, step_h0, step_h, mvd_bits);
00724
00725 mcost = WEIGHTED_COST (lambda_factor, mvd_bits);
00726
00727
00728 for (byy=0, v=by0_part; v < by0_part + step_v0; byy += 4, v++)
00729 {
00730
00731 pic_pix_y = img->opix_y + (block_y = (v<<2));
00732 for (bxx=0, h = bx0_part; h < bx0_part + step_h0; bxx += 4, h++)
00733 {
00734 pic_pix_x = img->opix_x + (block_x = (h<<2));
00735 LumaPredictionBi (currMB, block_x, block_y, 4, 4, blocktype, blocktype, ref_l0, ref_l1, list);
00736
00737 for (k = j = 0; j < 4; j++)
00738 {
00739 for (i = 0; i < 4; i++)
00740 diff64[k++] = curr_blk[byy+j][bxx+i] =
00741 pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
00742 }
00743
00744 if ((!params->Transform8x8Mode) || (blocktype>4))
00745 {
00746 mcost += distortion4x4 (diff64);
00747 }
00748 }
00749 }
00750 if (params->Transform8x8Mode && (blocktype<=4))
00751 {
00752 for (byy=0; byy < params->blc_size[parttype][1]; byy += bsy)
00753 for (bxx=0; bxx < params->blc_size[parttype][0]; bxx += bsx)
00754 {
00755 for (k=0, j = byy; j < byy + 8; j++, k += 8)
00756 memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));
00757
00758 mcost += distortion8x8(diff64);
00759 }
00760 }
00761 return mcost;
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771 int
00772 BlockMotionSearch (Macroblock *currMB,
00773 short ref,
00774 int list,
00775 int mb_x,
00776 int mb_y,
00777 int blocktype,
00778 int search_range,
00779 int* lambda_factor)
00780 {
00781
00782
00783 static PixelPos block_a, block_b, block_c, block_d;
00784
00785 imgpel *orig_pic_tmp = orig_pic;
00786
00787 int apply_bi_weights = params->UseWeightedReferenceME && ((img->type == B_SLICE) && active_pps->weighted_bipred_idc != 0);
00788 int apply_weights = params->UseWeightedReferenceME &&
00789 ((active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) || apply_bi_weights);
00790
00791 short pred_mv[2];
00792 MotionVector mv, pred;
00793 int i, j;
00794
00795 int max_value = INT_MAX;
00796 int min_mcost = max_value;
00797
00798 int block_x = (mb_x>>2);
00799 int block_y = (mb_y>>2);
00800
00801 int bsx = params->blc_size[blocktype][0];
00802 int bsy = params->blc_size[blocktype][1];
00803
00804 int pic_pix_x = img->opix_x + mb_x;
00805 int pic_pix_y = img->opix_y + mb_y;
00806
00807 int pic_pix_x_c = pic_pix_x >> (shift_cr_x);
00808 int pic_pix_y_c = pic_pix_y >> (shift_cr_y);
00809 int bsx_c = bsx >> (shift_cr_x);
00810 int bsy_c = bsy >> (shift_cr_y);
00811
00812 short*** all_mv = &img->all_mv[list][ref][blocktype][block_y];
00813 PicMotionParams *motion = &enc_picture->motion;
00814 int *prevSad = (params->SearchMode == EPZS)? EPZSDistortion[list + currMB->list_offset][blocktype - 1]: NULL;
00815
00816
00817 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, mb_x, mb_y, bsx);
00818 PrepareMEParams(apply_weights, params->ChromaMEEnable, list + currMB->list_offset, ref);
00819
00820
00821
00822
00823 for (j = pic_pix_y; j < pic_pix_y + bsy; j++)
00824 {
00825 memcpy(orig_pic_tmp,&pCurImg[j][pic_pix_x], bsx * sizeof(imgpel));
00826 orig_pic_tmp += bsx;
00827 }
00828
00829 ChromaMEEnable = params->ChromaMEEnable;
00830 if ( ChromaMEEnable )
00831 {
00832
00833 for ( i = 1; i<=2; i++)
00834 {
00835 orig_pic_tmp = orig_pic + (256 << (i - 1));
00836 for (j = pic_pix_y_c; j < pic_pix_y_c + bsy_c; j++)
00837 {
00838 memcpy(orig_pic_tmp, &(pImgOrg[i][j][pic_pix_x_c]), bsx_c * sizeof(imgpel));
00839 orig_pic_tmp += bsx_c;
00840 }
00841 }
00842 }
00843
00844 if (params->SearchMode == UM_HEX)
00845 {
00846 UMHEX_blocktype = blocktype;
00847 bipred_flag = 0;
00848 }
00849 else if (params->SearchMode == UM_HEX_SIMPLE)
00850 {
00851 smpUMHEX_setup(ref, list, block_y, block_x, blocktype, img->all_mv );
00852 }
00853
00854
00855
00856
00857
00858 if (params->SearchMode == UM_HEX)
00859 UMHEXSetMotionVectorPredictor(currMB, pred_mv, motion->ref_idx[list], motion->mv[list], ref, list, mb_x, mb_y, bsx, bsy, &search_range);
00860 else
00861 GetMotionVectorPredictor (currMB, &block_a, &block_b, &block_c, pred_mv, motion->ref_idx[list], motion->mv[list], ref, mb_x, mb_y, bsx, bsy);
00862
00863 pred.mv_x = pred_mv[0];
00864 pred.mv_y = pred_mv[1];
00865
00866
00867
00868
00869 if (params->EPZSSubPelGrid)
00870 {
00871 mv = pred;
00872 }
00873 else
00874 {
00875 mv.mv_x = (pred.mv_x + 2)>> 2;
00876 mv.mv_y = (pred.mv_y + 2)>> 2;
00877 }
00878
00879 if (!params->rdopt)
00880 {
00881
00882 mv.mv_x = iClip3 (-search_range<<(params->EPZSGrid), search_range<<(params->EPZSGrid), mv.mv_x);
00883 mv.mv_y = iClip3 (-search_range<<(params->EPZSGrid), search_range<<(params->EPZSGrid), mv.mv_y);
00884 }
00885
00886
00887 clip_mv_range(img, search_range, &mv, params->EPZSGrid);
00888
00889
00890 min_mcost = IntPelME (currMB, orig_pic, ref, list,
00891 motion->ref_idx, motion->mv, pic_pix_x, pic_pix_y, blocktype,
00892 &pred, &mv, search_range<<(params->EPZSGrid), min_mcost, lambda_factor[F_PEL], apply_weights);
00893
00894
00895 if (params->EPZSSubPelGrid == 0 || params->SearchMode != EPZS)
00896 {
00897 mv.mv_x <<= 2;
00898 mv.mv_y <<= 2;
00899 }
00900
00901
00902
00903
00904 ChromaMEEnable = (params->ChromaMEEnable == ME_YUV_FP_SP ) ? 1 : 0;
00905
00906 if (!params->DisableSubpelME)
00907 {
00908 if (params->SearchMode != EPZS || (ref == 0 || img->structure != FRAME || (ref > 0 && min_mcost < 3.5 * prevSad[pic_pix_x >> 2])))
00909 {
00910 if ( !start_me_refinement_hp )
00911 {
00912 min_mcost = max_value;
00913 }
00914 min_mcost = SubPelME (orig_pic, ref, list, currMB->list_offset, pic_pix_x, pic_pix_y, blocktype,
00915 &pred, &mv, 9, 9, min_mcost, lambda_factor, apply_weights);
00916 }
00917 }
00918
00919
00920
00921 clip_mv_range(img, 0, &mv, Q_PEL);
00922
00923 if (!params->rdopt)
00924 {
00925
00926 if (blocktype == 1 && (img->type == P_SLICE||img->type == SP_SLICE))
00927 {
00928 int cost;
00929
00930 FindSkipModeMotionVector (currMB);
00931
00932 cost = GetSkipCostMB (currMB);
00933 cost -= ((lambda_factor[Q_PEL] + 4096) >> 13);
00934 if (cost < min_mcost)
00935 {
00936 min_mcost = cost;
00937 mv.mv_x = img->all_mv [0][0][0][0][0][0];
00938 mv.mv_y = img->all_mv [0][0][0][0][0][1];
00939 }
00940 }
00941 }
00942
00943
00944
00945
00946
00947
00948 for (i=block_x; i < block_x + (bsx>>2); i++)
00949 {
00950 all_mv[0][i][0] = mv.mv_x;
00951 all_mv[0][i][1] = mv.mv_y;
00952 }
00953
00954
00955 for (j=1; j < (bsy>>2); j++)
00956 {
00957 memcpy(all_mv[j][block_x], all_mv[0][block_x], (bsx>>2) * 2 * sizeof(short));
00958 }
00959
00960
00961
00962 if (img->type == B_SLICE && is_bipred_enabled(blocktype) && (ref == 0))
00963 {
00964 BiPredBlockMotionSearch(currMB, &mv, &pred, ref, list, mb_x, mb_y, blocktype, search_range, apply_bi_weights, lambda_factor);
00965 }
00966
00967 return min_mcost;
00968 }
00969
00970
00971
00972
00973
00974
00975
00976
00977 int BiPredBlockMotionSearch(Macroblock *currMB,
00978 MotionVector *mv,
00979 MotionVector *pred_mv,
00980 short ref,
00981 int list,
00982 int mb_x,
00983 int mb_y,
00984 int blocktype,
00985 int search_range,
00986 int apply_bi_weights,
00987 int* lambda_factor)
00988 {
00989 int iteration_no, i, j;
00990 short bipred_type = list ? 0 : 1;
00991 short****** bipred_mv = img->bipred_mv[bipred_type];
00992 int min_mcostbi = INT_MAX;
00993 MotionVector bimv, tempmv;
00994 MotionVector pred_mv1, pred_mv2, pred_bi;
00995 MotionVector bi_mv1, bi_mv2;
00996 short iterlist=list;
00997 short pred_mv_bi[2];
00998 int block_x = (mb_x>>2);
00999 int block_y = (mb_y>>2);
01000 int bsx = params->blc_size[blocktype][0];
01001 int bsy = params->blc_size[blocktype][1];
01002 int pic_pix_x = img->opix_x + mb_x;
01003 int pic_pix_y = img->opix_y + mb_y;
01004 static PixelPos block_a, block_b, block_c, block_d;
01005 PicMotionParams *motion = &enc_picture->motion;
01006
01007 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, mb_x, mb_y, bsx);
01008
01009 if (params->SearchMode == UM_HEX)
01010 {
01011 bipred_flag = 1;
01012 UMHEXSetMotionVectorPredictor(currMB, pred_mv_bi, motion->ref_idx[list ^ 1], motion->mv[list ^ 1], 0, list ^ 1, mb_x, mb_y, bsx, bsy, &search_range);
01013 }
01014 else
01015 GetMotionVectorPredictor (currMB, &block_a, &block_b, &block_c, pred_mv_bi, motion->ref_idx[list ^ 1], motion->mv[list ^ 1], 0, mb_x, mb_y, bsx, bsy);
01016
01017 pred_bi.mv_x = pred_mv_bi[0];
01018 pred_bi.mv_y = pred_mv_bi[1];
01019
01020 if ((params->SearchMode != EPZS) || (params->EPZSSubPelGrid == 0))
01021 {
01022 mv->mv_x = (mv->mv_x + 2) >> 2;
01023 mv->mv_y = (mv->mv_y + 2) >> 2;
01024 bimv.mv_x = (pred_bi.mv_x + 2)>>2;
01025 bimv.mv_y = (pred_bi.mv_y + 2)>>2;
01026 }
01027 else
01028 {
01029 bimv = pred_bi;
01030 }
01031
01032
01033 for (iteration_no = 0; iteration_no <= params->BiPredMERefinements; iteration_no++)
01034 {
01035 if (iteration_no & 0x01)
01036 {
01037 pred_mv1 = *pred_mv;
01038 pred_mv2 = pred_bi;
01039 bi_mv1 = *mv;
01040 bi_mv2 = bimv;
01041 iterlist = list;
01042 }
01043 else
01044 {
01045 pred_mv1 = pred_bi;
01046 pred_mv2 = *pred_mv;
01047 bi_mv1 = bimv;
01048 bi_mv2 = *mv;
01049 iterlist = list ^ 1;
01050 }
01051
01052 tempmv = bi_mv1;
01053
01054 PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, currMB->list_offset, ref);
01055
01056 min_mcostbi = BiPredME (currMB, orig_pic, ref, iterlist, motion->ref_idx, motion->mv,
01057 pic_pix_x, pic_pix_y, blocktype, &pred_mv1, &pred_mv2, &bi_mv1, &bi_mv2,
01058 (params->BiPredMESearchRange <<(params->EPZSGrid))>>iteration_no, min_mcostbi, iteration_no, lambda_factor[F_PEL], apply_bi_weights);
01059
01060 if (iteration_no > 0 && (tempmv.mv_x == bi_mv1.mv_x) && (tempmv.mv_y == bi_mv1.mv_y))
01061 {
01062 break;
01063 }
01064 }
01065
01066 if ((params->SearchMode != EPZS) || (params->EPZSSubPelGrid == 0))
01067 {
01068 bi_mv2.mv_x = (bi_mv2.mv_x << 2);
01069 bi_mv2.mv_y = (bi_mv2.mv_y << 2);
01070 bi_mv1.mv_x = (bi_mv1.mv_x << 2);
01071 bi_mv1.mv_y = (bi_mv1.mv_y << 2);
01072 }
01073
01074 if (!params->DisableSubpelME)
01075 {
01076 if (params->BiPredMESubPel)
01077 {
01078 min_mcostbi = INT_MAX;
01079 PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist, currMB->list_offset, ref);
01080
01081 min_mcostbi = SubPelBiPredME (orig_pic, ref, iterlist, pic_pix_x, pic_pix_y, blocktype,
01082 &pred_mv1, &pred_mv2, &bi_mv1, &bi_mv2, 9, 9, min_mcostbi, lambda_factor, apply_bi_weights);
01083 }
01084
01085 if (params->BiPredMESubPel==2)
01086 {
01087 min_mcostbi = INT_MAX;
01088 PrepareBiPredMEParams(apply_bi_weights, ChromaMEEnable, iterlist ^ 1, currMB->list_offset, ref);
01089
01090 min_mcostbi = SubPelBiPredME (orig_pic, ref, iterlist ^ 1, pic_pix_x, pic_pix_y, blocktype,
01091 &pred_mv2, &pred_mv1, &bi_mv2, &bi_mv1, 9, 9, min_mcostbi, lambda_factor, apply_bi_weights);
01092 }
01093 }
01094
01095 clip_mv_range(img, 0, &bi_mv1, Q_PEL);
01096 clip_mv_range(img, 0, &bi_mv2, Q_PEL);
01097
01098 for (j=block_y; j < block_y + (bsy>>2); j++)
01099 {
01100 for (i=block_x ; i < block_x + (bsx>>2); i++)
01101 {
01102 bipred_mv[iterlist ][ref][blocktype][j][i][0] = bi_mv1.mv_x;
01103 bipred_mv[iterlist ][ref][blocktype][j][i][1] = bi_mv1.mv_y;
01104 bipred_mv[iterlist ^ 1][ref][blocktype][j][i][0] = bi_mv2.mv_x;
01105 bipred_mv[iterlist ^ 1][ref][blocktype][j][i][1] = bi_mv2.mv_y;
01106 }
01107 }
01108 return min_mcostbi;
01109 }
01110
01111
01112
01113
01114
01115
01116
01117 int BIDPartitionCost (Macroblock *currMB,
01118 int blocktype,
01119 int block8x8,
01120 char cur_ref[2],
01121 int lambda_factor)
01122 {
01123 static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
01124 static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
01125
01126 int curr_blk[MB_BLOCK_SIZE][MB_BLOCK_SIZE];
01127 int bsx = imin(params->blc_size[blocktype][0],8);
01128 int bsy = imin(params->blc_size[blocktype][1],8);
01129
01130 int pic_pix_x, pic_pix_y, block_x, block_y;
01131 int v, h, mcost, i, j, k;
01132 int mvd_bits = 0;
01133 int parttype = (blocktype<4?blocktype:4);
01134 int step_h0 = (params->part_size[ parttype][0]);
01135 int step_v0 = (params->part_size[ parttype][1]);
01136 int step_h = (params->part_size[blocktype][0]);
01137 int step_v = (params->part_size[blocktype][1]);
01138 int bxx, byy;
01139 int bx = bx0[parttype][block8x8];
01140 int by = by0[parttype][block8x8];
01141 short *** all_mv_l0 = img->all_mv [LIST_0][(int) cur_ref[LIST_0]][blocktype];
01142 short *** all_mv_l1 = img->all_mv [LIST_1][(int) cur_ref[LIST_1]][blocktype];
01143 short bipred_me = 0;
01144 imgpel **mb_pred = img->mb_pred[0];
01145
01146
01147
01148
01149
01150 mvd_bits = mv_bit_cost(currMB, all_mv_l0, LIST_0, cur_ref[LIST_0], by, bx, step_v0, step_v, step_h0, step_h, mvd_bits);
01151
01152
01153 mvd_bits = mv_bit_cost(currMB, all_mv_l1, LIST_1, cur_ref[LIST_1], by, bx, step_v0, step_v, step_h0, step_h, mvd_bits);
01154
01155 mcost = WEIGHTED_COST (lambda_factor, mvd_bits);
01156
01157
01158 for (byy=0, v=by; v<by + step_v0; byy+=4, v++)
01159 {
01160 pic_pix_y = img->opix_y + (block_y = (v<<2));
01161 for (bxx=0, h=bx; h<bx + step_h0; bxx+=4, h++)
01162 {
01163 pic_pix_x = img->opix_x + (block_x = (h<<2));
01164 LumaPrediction (currMB, block_x, block_y, 4, 4, 2, blocktype, blocktype, (short) cur_ref[0], (short) cur_ref[1], bipred_me);
01165
01166 for (k=j=0; j<4; j++)
01167 {
01168 for ( i=0; i<4; i++)
01169 diff64[k++] = curr_blk[byy+j][bxx+i] =
01170 pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
01171 }
01172 if ((!params->Transform8x8Mode) || (blocktype>4))
01173 mcost += distortion4x4 (diff64);
01174 }
01175 }
01176
01177 if (params->Transform8x8Mode && (blocktype<=4))
01178 {
01179 for (byy=0; byy < params->blc_size[parttype][1]; byy+=bsy)
01180 {
01181 for (bxx=0; bxx<params->blc_size[parttype][0]; bxx+=bsx)
01182 {
01183 for (k=0, j=byy;j<byy + 8;j++, k += 8)
01184 memcpy(&diff64[k], &(curr_blk[j][bxx]), 8 * sizeof(int));
01185
01186 mcost += distortion8x8(diff64);
01187 }
01188 }
01189 }
01190 return mcost;
01191 }
01192
01193
01194
01195
01196
01197
01198
01199 int GetSkipCostMB (Macroblock *currMB)
01200 {
01201 int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
01202 int cost = 0;
01203
01204 int curr_diff[8][8];
01205 int mb_x, mb_y;
01206 int block;
01207 imgpel **mb_pred = img->mb_pred[0];
01208
01209 for(block = 0;block < 4;block++)
01210 {
01211 mb_y = (block >> 1)<<3;
01212 mb_x = (block & 0x01)<<3;
01213 for (block_y = mb_y; block_y < mb_y+8; block_y += 4)
01214 {
01215 pic_pix_y = img->opix_y + block_y;
01216 for (block_x = mb_x; block_x < mb_x + 8; block_x += 4)
01217 {
01218 pic_pix_x = img->opix_x + block_x;
01219
01220
01221 LumaPrediction (currMB, block_x, block_y, 4, 4, 0, 0, 0, 0, 0, 0);
01222
01223
01224 for (k = j = 0; j < 4; j++)
01225 {
01226 for (i = 0; i < 4; i++, k++)
01227 {
01228 diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] = pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
01229 }
01230 }
01231
01232 if(!((params->rdopt==0) && (params->Transform8x8Mode)))
01233 cost += distortion4x4 (diff);
01234 }
01235 }
01236
01237 if((params->rdopt == 0) && (params->Transform8x8Mode))
01238 {
01239 for(k=j=0; j<8; j++, k+=8)
01240 memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));
01241 cost += distortion8x8 (diff64);
01242 }
01243 }
01244
01245 return cost;
01246 }
01247
01248
01249
01250
01251
01252
01253
01254 void FindSkipModeMotionVector (Macroblock *currMB)
01255 {
01256 int bx, by;
01257 short ***all_mv = img->all_mv[0][0][0];
01258
01259 short pmv[2];
01260
01261 int zeroMotionAbove;
01262 int zeroMotionLeft;
01263 PixelPos mb_a, mb_b, mb_c, mb_d;
01264 int a_mv_y = 0;
01265 int a_ref_idx = 0;
01266 int b_mv_y = 0;
01267 int b_ref_idx = 0;
01268 short ***mv = enc_picture->motion.mv[LIST_0];
01269
01270 get_neighbors(currMB, &mb_a, &mb_b, &mb_c, &mb_d, 0, 0, 16);
01271
01272 if (mb_a.available)
01273 {
01274 a_mv_y = mv[mb_a.pos_y][mb_a.pos_x][1];
01275 a_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
01276
01277 if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
01278 {
01279 a_mv_y /=2;
01280 a_ref_idx *=2;
01281 }
01282 if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
01283 {
01284 a_mv_y *= 2;
01285 a_ref_idx >>=1;
01286 }
01287 }
01288
01289 if (mb_b.available)
01290 {
01291 b_mv_y = mv[mb_b.pos_y][mb_b.pos_x][1];
01292 b_ref_idx = enc_picture->motion.ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
01293
01294 if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
01295 {
01296 b_mv_y /=2;
01297 b_ref_idx *=2;
01298 }
01299 if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
01300 {
01301 b_mv_y *=2;
01302 b_ref_idx >>=1;
01303 }
01304 }
01305
01306 zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
01307 zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
01308
01309 if (zeroMotionAbove || zeroMotionLeft)
01310 {
01311 memset(all_mv [0][0], 0, 4 * 4 * 2* sizeof(short));
01312 }
01313 else
01314 {
01315 GetMotionVectorPredictor (currMB, &mb_a, &mb_b, &mb_c, pmv, enc_picture->motion.ref_idx[LIST_0], mv, 0, 0, 0, 16, 16);
01316
01317 for (bx = 0;bx < 4;bx++)
01318 {
01319 memcpy(all_mv [0][bx], pmv, 2* sizeof(short));
01320 }
01321
01322 for (by = 1;by < 4;by++)
01323 memcpy(all_mv [by][0], all_mv [0][0], 4 * 2* sizeof(short));
01324 }
01325 }
01326
01327
01328
01329
01330
01331
01332
01333 int GetDirectCost8x8 (Macroblock *currMB, int block, int *cost8x8)
01334 {
01335 int block_y, block_x, pic_pix_y, pic_pix_x, i, j, k;
01336 int curr_diff[8][8];
01337 int cost = 0;
01338 int mb_y = (block/2)<<3;
01339 int mb_x = (block%2)<<3;
01340 short bipred_me = 0;
01341 imgpel **mb_pred = img->mb_pred[0];
01342
01343 for (block_y=mb_y; block_y<mb_y+8; block_y+=4)
01344 {
01345 pic_pix_y = img->opix_y + block_y;
01346
01347 for (block_x=mb_x; block_x<mb_x+8; block_x+=4)
01348 {
01349 pic_pix_x = img->opix_x + block_x;
01350
01351 if (direct_pdir[pic_pix_y>>2][pic_pix_x>>2]<0)
01352 {
01353 *cost8x8=INT_MAX;
01354 return INT_MAX;
01355 }
01356
01357
01358
01359 LumaPrediction (currMB, block_x, block_y, 4, 4,
01360 direct_pdir[pic_pix_y>>2][pic_pix_x>>2], 0, 0,
01361 direct_ref_idx[LIST_0][pic_pix_y>>2][pic_pix_x>>2],
01362 direct_ref_idx[LIST_1][pic_pix_y>>2][pic_pix_x>>2], bipred_me);
01363
01364
01365 for (k=j=0; j<4; j++)
01366 for (i=0; i<4; i++, k++)
01367 {
01368 diff[k] = curr_diff[block_y-mb_y+j][block_x-mb_x+i] =
01369 pCurImg[pic_pix_y+j][pic_pix_x+i] - mb_pred[j+block_y][i+block_x];
01370 }
01371
01372 cost += distortion4x4 (diff);
01373 }
01374 }
01375
01376 if((params->rdopt == 0) && (params->Transform8x8Mode))
01377 {
01378 k=0;
01379 for(j=0; j<8; j++, k+=8)
01380 memcpy(&diff64[k], &(curr_diff[j]), 8 * sizeof(int));
01381
01382 *cost8x8 += distortion8x8 (diff64);
01383 }
01384
01385 return cost;
01386 }
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 int GetDirectCostMB (Macroblock *currMB, int bslice)
01397 {
01398 int i;
01399 int cost = 0;
01400 int cost8x8 = 0;
01401
01402 for (i=0; i<4; i++)
01403 {
01404 cost += GetDirectCost8x8 (currMB, i, &cost8x8);
01405 if (cost8x8 == INT_MAX) return INT_MAX;
01406 }
01407
01408 switch(params->Transform8x8Mode)
01409 {
01410 case 1:
01411 if((cost8x8 < cost)||
01412 !(params->InterSearch[bslice][5] &&
01413 params->InterSearch[bslice][6] &&
01414 params->InterSearch[bslice][7])
01415 )
01416 {
01417 cost = cost8x8;
01418 }
01419 break;
01420 case 2:
01421 cost = cost8x8;
01422 break;
01423 default:
01424 break;
01425 }
01426
01427 return cost;
01428 }
01429
01430
01431
01432
01433
01434
01435
01436
01437 void
01438 PartitionMotionSearch (Macroblock *currMB,
01439 int blocktype,
01440 int block8x8,
01441 int *lambda_factor)
01442 {
01443 static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
01444 static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
01445
01446 char **ref_array;
01447 short ***mv_array;
01448 short *all_mv;
01449 short ref;
01450 int v, h, mcost, search_range, i, j;
01451 int pic_block_x, pic_block_y;
01452 int bslice = (img->type==B_SLICE);
01453 int parttype = (blocktype < 4 ? blocktype : 4);
01454 int step_h0 = (params->part_size[ parttype][0]);
01455 int step_v0 = (params->part_size[ parttype][1]);
01456 int step_h = (params->part_size[blocktype][0]);
01457 int step_v = (params->part_size[blocktype][1]);
01458 int list;
01459 int numlists = bslice ? 2 : 1;
01460 int list_offset = currMB->list_offset;
01461 int *m_cost;
01462 int by = by0[parttype][block8x8];
01463 int bx = bx0[parttype][block8x8];
01464
01465 #if GET_METIME
01466 static TIME_T me_time_start;
01467 static TIME_T me_time_end;
01468 int64 me_tmp_time;
01469 gettime( &me_time_start );
01470 #endif
01471
01472 for (list=0; list<numlists;list++)
01473 {
01474
01475 ref_array = enc_picture->motion.ref_idx[list];
01476 mv_array = enc_picture->motion.mv[list];
01477
01478 for (ref=0; ref < listXsize[list+list_offset]; ref++)
01479 {
01480 m_cost = &motion_cost[blocktype][list][ref][block8x8];
01481
01482 if (params->full_search == 2)
01483 search_range = params->search_range;
01484 else if (params->full_search == 1)
01485 search_range = params->search_range / (imin(ref,1)+1);
01486 else
01487 search_range = params->search_range / ((imin(ref,1)+1) * imin(2,blocktype));
01488
01489
01490
01491 if (Motion_Selected != 1)
01492 *m_cost = 0;
01493
01494
01495 for (v=by; v<by + step_v0; v += step_v)
01496 {
01497 pic_block_y = img->block_y + v;
01498
01499 for (h=bx; h<bx+step_h0; h+=step_h)
01500 {
01501 all_mv = img->all_mv[list][ref][blocktype][v][h];
01502 pic_block_x = img->block_x + h;
01503
01504
01505 if (Motion_Selected != 1)
01506 {
01507 mcost = BlockMotionSearch (currMB, ref, list, h<<2, v<<2, blocktype, search_range, lambda_factor);
01508 *m_cost += mcost;
01509 if ( (params->Transform8x8Mode == 1) && params->RDOQ_CP_MV && (blocktype == 4) && currMB->luma_transform_size_8x8_flag)
01510 {
01511 tmp_mv8[list][ref][v][h][0] = all_mv[0];
01512 tmp_mv8[list][ref][v][h][1] = all_mv[1];
01513 motion_cost8[list][ref][block8x8] = mcost;
01514 }
01515 }
01516 else
01517 updateMV_mp(m_cost, ref, list, h, v, blocktype, lambda_factor, block8x8);
01518
01519
01520 for (j=pic_block_y; j<pic_block_y + step_v; j++)
01521 {
01522 memset(&ref_array [j][pic_block_x], ref, step_h * sizeof(char));
01523
01524 for (i=pic_block_x; i<pic_block_x + step_h; i++)
01525 {
01526 memcpy(mv_array [j][i], all_mv, 2* sizeof(short));
01527 }
01528 }
01529 }
01530 }
01531 }
01532 }
01533 #if GET_METIME
01534 gettime(&me_time_end);
01535 me_tmp_time = timediff (&me_time_start, &me_time_end);
01536 me_tot_time += me_tmp_time;
01537 me_time += me_tmp_time;
01538 #endif
01539 }
01540
01541
01542
01543
01544
01545
01546
01547 void Get_Direct_Motion_Vectors (Macroblock *currMB)
01548 {
01549
01550 int block_x, block_y, pic_block_x, pic_block_y, opic_block_x, opic_block_y;
01551 short ******all_mvs;
01552 int mv_scale;
01553 int refList;
01554 int ref_idx;
01555
01556 MotionParams *colocated;
01557 char ** ref_pic_l0 = enc_picture->motion.ref_idx[LIST_0];
01558 char ** ref_pic_l1 = enc_picture->motion.ref_idx[LIST_1];
01559
01560 if (currMB->list_offset)
01561 {
01562 if(img->current_mb_nr%2)
01563 {
01564 colocated = &Co_located->bottom;
01565 }
01566 else
01567 {
01568 colocated = &Co_located->top;
01569 }
01570 }
01571 else
01572 {
01573 colocated = &Co_located->frame;
01574 }
01575
01576 if (img->direct_spatial_mv_pred_flag)
01577 {
01578
01579 short l0_refA, l0_refB, l0_refC;
01580 short l1_refA, l1_refB, l1_refC;
01581 short l0_refX,l1_refX;
01582 short pmvfw[2]={0,0},pmvbw[2]={0,0};
01583
01584 PixelPos mb_a, mb_b, mb_d, mb_c;
01585
01586 get_neighbors(currMB, &mb_a, &mb_b, &mb_c, &mb_d, 0, 0, 16);
01587
01588 if (!img->MbaffFrameFlag)
01589 {
01590 l0_refA = mb_a.available ? ref_pic_l0[mb_a.pos_y][mb_a.pos_x] : -1;
01591 l0_refB = mb_b.available ? ref_pic_l0[mb_b.pos_y][mb_b.pos_x] : -1;
01592 l0_refC = mb_c.available ? ref_pic_l0[mb_c.pos_y][mb_c.pos_x] : -1;
01593
01594 l1_refA = mb_a.available ? ref_pic_l1[mb_a.pos_y][mb_a.pos_x] : -1;
01595 l1_refB = mb_b.available ? ref_pic_l1[mb_b.pos_y][mb_b.pos_x] : -1;
01596 l1_refC = mb_c.available ? ref_pic_l1[mb_c.pos_y][mb_c.pos_x] : -1;
01597 }
01598 else
01599 {
01600 if (currMB->mb_field)
01601 {
01602 l0_refA = mb_a.available
01603 ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l0[mb_a.pos_y][mb_a.pos_x] < 0
01604 ? ref_pic_l0[mb_a.pos_y][mb_a.pos_x]
01605 : ref_pic_l0[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
01606
01607 l0_refB = mb_b.available
01608 ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
01609 ? ref_pic_l0[mb_b.pos_y][mb_b.pos_x]
01610 : ref_pic_l0[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
01611
01612 l0_refC = mb_c.available
01613 ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
01614 ? ref_pic_l0[mb_c.pos_y][mb_c.pos_x]
01615 : ref_pic_l0[mb_c.pos_y][mb_c.pos_x] * 2) : -1;
01616
01617 l1_refA = mb_a.available
01618 ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
01619 ? ref_pic_l1[mb_a.pos_y][mb_a.pos_x]
01620 : ref_pic_l1[mb_a.pos_y][mb_a.pos_x] * 2) : -1;
01621
01622 l1_refB = mb_b.available
01623 ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
01624 ? ref_pic_l1[mb_b.pos_y][mb_b.pos_x]
01625 : ref_pic_l1[mb_b.pos_y][mb_b.pos_x] * 2) : -1;
01626
01627 l1_refC = mb_c.available
01628 ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
01629 ? ref_pic_l1[mb_c.pos_y][mb_c.pos_x]
01630 : ref_pic_l1[mb_c.pos_y][mb_c.pos_x] * 2) : -1;
01631 }
01632 else
01633 {
01634 l0_refA = mb_a.available
01635 ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l0[mb_a.pos_y][mb_a.pos_x] < 0
01636 ? ref_pic_l0[mb_a.pos_y][mb_a.pos_x] >> 1
01637 : ref_pic_l0[mb_a.pos_y][mb_a.pos_x]) : -1;
01638
01639 l0_refB = mb_b.available
01640 ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l0[mb_b.pos_y][mb_b.pos_x] < 0
01641 ? ref_pic_l0[mb_b.pos_y][mb_b.pos_x] >> 1
01642 : ref_pic_l0[mb_b.pos_y][mb_b.pos_x]) : -1;
01643
01644 l0_refC = mb_c.available
01645 ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l0[mb_c.pos_y][mb_c.pos_x] < 0
01646 ? ref_pic_l0[mb_c.pos_y][mb_c.pos_x] >> 1
01647 : ref_pic_l0[mb_c.pos_y][mb_c.pos_x]) : -1;
01648
01649 l1_refA = mb_a.available
01650 ? (img->mb_data[mb_a.mb_addr].mb_field || ref_pic_l1[mb_a.pos_y][mb_a.pos_x] < 0
01651 ? ref_pic_l1[mb_a.pos_y][mb_a.pos_x] >> 1
01652 : ref_pic_l1[mb_a.pos_y][mb_a.pos_x]) : -1;
01653
01654 l1_refB = mb_b.available
01655 ? (img->mb_data[mb_b.mb_addr].mb_field || ref_pic_l1[mb_b.pos_y][mb_b.pos_x] < 0
01656 ? ref_pic_l1[mb_b.pos_y][mb_b.pos_x] >> 1
01657 : ref_pic_l1[mb_b.pos_y][mb_b.pos_x]) : -1;
01658
01659 l1_refC = mb_c.available
01660 ? (img->mb_data[mb_c.mb_addr].mb_field || ref_pic_l1[mb_c.pos_y][mb_c.pos_x] < 0
01661 ? ref_pic_l1[mb_c.pos_y][mb_c.pos_x] >> 1
01662 : ref_pic_l1[mb_c.pos_y][mb_c.pos_x]) : -1;
01663 }
01664 }
01665
01666 l0_refX = (l0_refA >= 0 && l0_refB >= 0) ? imin(l0_refA,l0_refB): imax(l0_refA,l0_refB);
01667 l0_refX = (l0_refX >= 0 && l0_refC >= 0) ? imin(l0_refX,l0_refC): imax(l0_refX,l0_refC);
01668
01669 l1_refX = (l1_refA >= 0 && l1_refB >= 0) ? imin(l1_refA,l1_refB): imax(l1_refA,l1_refB);
01670 l1_refX = (l1_refX >= 0 && l1_refC >= 0) ? imin(l1_refX,l1_refC): imax(l1_refX,l1_refC);
01671
01672 if (l0_refX >=0)
01673 GetMotionVectorPredictor (currMB, &mb_a, &mb_b, &mb_c, pmvfw, enc_picture->motion.ref_idx[LIST_0], enc_picture->motion.mv[LIST_0], l0_refX, 0, 0, 16, 16);
01674
01675 if (l1_refX >=0)
01676 GetMotionVectorPredictor (currMB, &mb_a, &mb_b, &mb_c, pmvbw, enc_picture->motion.ref_idx[LIST_1], enc_picture->motion.mv[LIST_1], l1_refX, 0, 0, 16, 16);
01677
01678 for (block_y=0; block_y<4; block_y++)
01679 {
01680 pic_block_y = (img->pix_y >> 2) + block_y;
01681 opic_block_y = (img->opix_y >> 2) + block_y;
01682
01683 for (block_x=0; block_x<4; block_x++)
01684 {
01685 pic_block_x = (img->pix_x >> 2) + block_x;
01686 opic_block_x = (img->opix_x >> 2) + block_x;
01687
01688 all_mvs = img->all_mv;
01689
01690 if (l0_refX >=0)
01691 {
01692 if (!l0_refX && !colocated->moving_block[opic_block_y][opic_block_x])
01693 {
01694 memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2 * sizeof(short));
01695 direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=0;
01696 }
01697 else
01698 {
01699 memcpy(all_mvs[LIST_0][l0_refX][0][block_y][block_x], pmvfw, 2 * sizeof(short));
01700 direct_ref_idx[LIST_0][pic_block_y][pic_block_x]= (char)l0_refX;
01701 }
01702 }
01703 else
01704 {
01705 memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2 * sizeof(short));
01706 direct_ref_idx[LIST_0][pic_block_y][pic_block_x]=-1;
01707 }
01708
01709 if (l1_refX >=0)
01710 {
01711 if(l1_refX==0 && !colocated->moving_block[opic_block_y][opic_block_x])
01712 {
01713 memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2 * sizeof(short));
01714 direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
01715 }
01716 else
01717 {
01718 memcpy(all_mvs[LIST_1][l1_refX][0][block_y][block_x], pmvbw, 2 * sizeof(short));
01719 direct_ref_idx[LIST_1][pic_block_y][pic_block_x]= (char)l1_refX;
01720 }
01721 }
01722 else
01723 {
01724 memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2 * sizeof(short));
01725 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01726 }
01727
01728
01729 if (img->MbaffFrameFlag
01730 && (out_of_bounds_mvs(img, all_mvs[LIST_0][l0_refX < 0? 0 : l0_refX][0][block_y][block_x])
01731 || out_of_bounds_mvs(img, all_mvs[LIST_1][l1_refX < 0? 0 : l1_refX][0][block_y][block_x])))
01732 {
01733 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
01734 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01735 direct_pdir [pic_block_y][pic_block_x] = -1;
01736 }
01737 else
01738 {
01739 if (l0_refX < 0 && l1_refX < 0)
01740 {
01741 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] =
01742 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
01743 l0_refX = 0;
01744 l1_refX = 0;
01745 }
01746
01747 if (direct_ref_idx[LIST_1][pic_block_y][pic_block_x] == -1)
01748 direct_pdir[pic_block_y][pic_block_x] = 0;
01749 else if (direct_ref_idx[LIST_0][pic_block_y][pic_block_x] == -1)
01750 direct_pdir[pic_block_y][pic_block_x] = 1;
01751 else if (active_pps->weighted_bipred_idc == 1)
01752 {
01753 int weight_sum, i;
01754 Boolean invalid_wp = FALSE;
01755 for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
01756 {
01757 weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
01758 if (weight_sum < -128 || weight_sum > 127)
01759 {
01760 invalid_wp = TRUE;
01761 break;
01762 }
01763 }
01764 if (invalid_wp == FALSE)
01765 direct_pdir[pic_block_y][pic_block_x] = 2;
01766 else
01767 {
01768 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
01769 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01770 direct_pdir [pic_block_y][pic_block_x] = -1;
01771 }
01772 }
01773 else
01774 direct_pdir[pic_block_y][pic_block_x] = 2;
01775 }
01776 }
01777 }
01778 }
01779 else
01780 {
01781 int64 *refpic = enc_picture->ref_pic_num[LIST_0 +currMB->list_offset];
01782
01783
01784 for (block_y = 0; block_y < 4; block_y++)
01785 {
01786 pic_block_y = (img->pix_y >> 2) + block_y;
01787 opic_block_y = (img->opix_y >> 2) + block_y;
01788
01789 for (block_x = 0; block_x < 4; block_x++)
01790 {
01791 pic_block_x = (img->pix_x>>2) + block_x;
01792 opic_block_x = (img->opix_x>>2) + block_x;
01793 all_mvs = img->all_mv;
01794
01795 refList = (colocated->ref_idx[LIST_0][opic_block_y][opic_block_x]== -1 ? LIST_1 : LIST_0);
01796 ref_idx = colocated->ref_idx[refList][opic_block_y][opic_block_x];
01797
01798
01799 if (ref_idx==-1)
01800 {
01801 memset(all_mvs[LIST_0][0][0][block_y][block_x], 0, 2* sizeof(short));
01802 memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2* sizeof(short));
01803 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = 0;
01804 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
01805 direct_pdir[pic_block_y][pic_block_x] = 2;
01806 }
01807
01808 else
01809 {
01810 int mapped_idx=INVALIDINDEX;
01811 int iref;
01812
01813 for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0+currMB->list_offset]);iref++)
01814 {
01815 if (refpic[iref]==colocated->ref_pic_id[refList ][opic_block_y][opic_block_x])
01816 {
01817 mapped_idx=iref;
01818 break;
01819 }
01820 else
01821 {
01822 mapped_idx=INVALIDINDEX;
01823 }
01824 }
01825
01826 if (mapped_idx !=INVALIDINDEX)
01827 {
01828 mv_scale = img->mvscale[LIST_0+currMB->list_offset][mapped_idx];
01829
01830 if (mv_scale==9999)
01831 {
01832
01833 memcpy(all_mvs[LIST_0][0][0][block_y][block_x], colocated->mv[refList][opic_block_y][opic_block_x], 2* sizeof(short));
01834
01835 memset(all_mvs[LIST_1][0][0][block_y][block_x], 0, 2* sizeof(short));
01836 }
01837 else
01838 {
01839
01840 all_mvs[LIST_0][mapped_idx][0][block_y][block_x][0] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
01841 all_mvs[LIST_0][mapped_idx][0][block_y][block_x][1] = (mv_scale * colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
01842
01843 all_mvs[LIST_1][ 0][0][block_y][block_x][0] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][0] + 128) >> 8;
01844 all_mvs[LIST_1][ 0][0][block_y][block_x][1] = ((mv_scale - 256)* colocated->mv[refList][opic_block_y][opic_block_x][1] + 128) >> 8;
01845 }
01846
01847
01848 if ( out_of_bounds_mvs(img, all_mvs[LIST_0][mapped_idx][0][block_y][block_x])|| out_of_bounds_mvs(img, all_mvs[LIST_1][0][0][block_y][block_x]))
01849 {
01850 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
01851 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01852 direct_pdir[pic_block_y][pic_block_x] = -1;
01853 }
01854 else
01855 {
01856 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = mapped_idx;
01857 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = 0;
01858 direct_pdir[pic_block_y][pic_block_x] = 2;
01859 }
01860 }
01861 else
01862 {
01863 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
01864 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01865 direct_pdir[pic_block_y][pic_block_x] = -1;
01866 }
01867 }
01868 if (active_pps->weighted_bipred_idc == 1 && direct_pdir[pic_block_y][pic_block_x] == 2)
01869 {
01870 int weight_sum, i;
01871 short l0_refX = direct_ref_idx[LIST_0][pic_block_y][pic_block_x];
01872 short l1_refX = direct_ref_idx[LIST_1][pic_block_y][pic_block_x];
01873 for (i=0;i< (active_sps->chroma_format_idc == YUV400 ? 1 : 3); i++)
01874 {
01875 weight_sum = wbp_weight[0][l0_refX][l1_refX][i] + wbp_weight[1][l0_refX][l1_refX][i];
01876 if (weight_sum < -128 || weight_sum > 127)
01877 {
01878 direct_ref_idx[LIST_0][pic_block_y][pic_block_x] = -1;
01879 direct_ref_idx[LIST_1][pic_block_y][pic_block_x] = -1;
01880 direct_pdir [pic_block_y][pic_block_x] = -1;
01881 break;
01882 }
01883 }
01884 }
01885 }
01886 }
01887 }
01888 }