00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "contributors.h"
00018
00019 #include <limits.h>
00020
00021 #include "global.h"
00022 #include "image.h"
00023 #include "memalloc.h"
00024 #include "mb_access.h"
00025 #include "refbuf.h"
00026
00027 #include "me_distortion.h"
00028 #include "me_epzs.h"
00029 #include "mv-search.h"
00030
00031 #define EPZSREF 1
00032
00033
00034 static const short blk_parent[8] = {1, 1, 1, 1, 2, 4, 4, 5};
00035
00036 static const int minthres_base[8] = {0, 64, 32, 32, 16, 8, 8, 4};
00037 static const int medthres_base[8] = {0, 256, 128, 128, 64, 32, 32, 16};
00038 static const int maxthres_base[8] = {0, 768, 384, 384, 192, 96, 96, 48};
00039 static const short search_point_hp[10][2] = {{0,0},{-2,0}, {0,2}, {2,0}, {0,-2}, {-2,2}, {2,2}, {2,-2}, {-2,-2}, {-2,2}};
00040 static const short search_point_qp[10][2] = {{0,0},{-1,0}, {0,1}, {1,0}, {0,-1}, {-1,1}, {1,1}, {1,-1}, {-1,-1}, {-1,1}};
00041
00042
00043 static int (*computePred)(imgpel* , int , int , int , int , int );
00044
00045 static unsigned short EPZSBlkCount;
00046 static int searcharray;
00047 static int mv_rescale;
00048
00049
00050 static int pattern_data[5][12][4] =
00051 {
00052 {
00053 { 0, 4, 3, 3 }, { 4, 0, 0, 3 }, { 0, -4, 1, 3 }, { -4, 0, 2, 3 }
00054 },
00055 {
00056 { 0, 4, 7, 3 }, { 4, 4, 7, 5 }, { 4, 0, 1, 3 }, { 4, -4, 1, 5 },
00057 { 0, -4, 3, 3 }, { -4, -4, 3, 5 }, { -4, 0, 5, 3 }, { -4, 4, 5, 5 }
00058 },
00059 {
00060 { -4, 4, 10, 5 }, { 0, 8, 10, 8 }, { 0, 4, 10, 7 }, { 4, 4, 1, 5 },
00061 { 8, 0, 1, 8 }, { 4, 0, 1, 7 }, { 4, -4, 4, 5 }, { 0, -8, 4, 8 },
00062 { 0, -4, 4, 7 }, { -4, -4, 7, 5 }, { -8, 0, 7, 8 }, { -4, 0, 7, 7 }
00063
00064 },
00065 {
00066 { 0, 8, 6, 5 }, { 4, 4, 0, 3 }, { 8, 0, 0, 5 }, { 4, -4, 2, 3 },
00067 { 0, -8, 2, 5 }, { -4, -4, 4, 3 }, { -8, 0, 4, 5 }, { -4, 4, 6, 3 }
00068 },
00069 {
00070 { 0, 8, 6, 12 }, { 4, 4, 0, 12 }, { 8, 0, 0, 12 }, { 4, -4, 2, 12 },
00071 { 0, -8, 2, 12 }, { -4, -4, 4, 12 }, { -8, 0, 4, 12 }, { -4, 4, 6, 12 },
00072 { 0, 2, 6, 12 }, { 2, 0, 0, 12 }, { 0, -2, 2, 12 }, { -2, 0, 4, 12 }
00073 }
00074 };
00075
00076
00077 static const char c_EPZSPattern[6][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
00078 static const char c_EPZSDualPattern[7][20] = { "Disabled","Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST"};
00079 static const char c_EPZSFixed[3][20] = { "Disabled","All P", "All P + B"};
00080 static const char c_EPZSOther[2][20] = { "Disabled","Enabled"};
00081
00082 static int medthres[8];
00083 static int maxthres[8];
00084 static int minthres[8];
00085 static int subthres[8];
00086 static int mv_scale[6][MAX_REFERENCE_PICTURES][MAX_REFERENCE_PICTURES];
00087
00088 static unsigned short **EPZSMap;
00089 int ***EPZSDistortion;
00090 int ***EPZSBiDistortion;
00091 #if EPZSREF
00092 MotionVector *****EPZS_Motion;
00093 #else
00094 MotionVector ****EPZS_Motion;
00095 #endif
00096
00097
00098 EPZSStructure *searchPattern,*searchPatternD, *predictor;
00099 EPZSStructure *window_predictor, *window_predictor_extended;
00100 EPZSStructure *sdiamond,*square,*ediamond,*ldiamond, *sbdiamond, *pmvfast;
00101 EPZSColocParams *EPZSCo_located;
00102
00103
00104
00105
00106
00107
00108
00109
00110 static int EPZSDetermineStopCriterion(int* prevSad, PixelPos *block_a, PixelPos *block_b, PixelPos *block_c, int pic_pix_x2, int blocktype, int blockshape_x)
00111 {
00112 int sadA, sadB, sadC, stopCriterion;
00113
00114 sadA = block_a->available ? prevSad[pic_pix_x2 - blockshape_x] : INT_MAX;
00115 sadB = block_b->available ? prevSad[pic_pix_x2] : INT_MAX;
00116 sadC = block_c->available ? prevSad[pic_pix_x2 + blockshape_x] : INT_MAX;
00117
00118 stopCriterion = imin(sadA,imin(sadB,sadC));
00119 stopCriterion = imax(stopCriterion,minthres[blocktype]);
00120 stopCriterion = imin(stopCriterion,maxthres[blocktype]);
00121
00122 stopCriterion = (9 * imax (medthres[blocktype], stopCriterion) + 2 * medthres[blocktype]) >> 3;
00123 return stopCriterion;
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 static EPZSColocParams* allocEPZScolocated(int size_x, int size_y, int mb_adaptive_frame_field_flag)
00143 {
00144 EPZSColocParams *s;
00145
00146 s = calloc(1, sizeof(EPZSColocParams));
00147 if (NULL == s)
00148 no_mem_exit("alloc_EPZScolocated: s");
00149
00150 s->size_x = size_x;
00151 s->size_y = size_y;
00152 get_mem3Dmv(&(s->frame), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
00153
00154 if (mb_adaptive_frame_field_flag)
00155 {
00156 get_mem3Dmv(&(s->top), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
00157 get_mem3Dmv(&(s->bot), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
00158 }
00159
00160 s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag;
00161
00162 return s;
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 static void freeEPZScolocated(EPZSColocParams* p)
00176 {
00177 if (p)
00178 {
00179 free_mem3Dmv (p->frame);
00180
00181 if (p->mb_adaptive_frame_field_flag)
00182 {
00183 free_mem3Dmv (p->top);
00184 free_mem3Dmv (p->bot);
00185 }
00186
00187 free(p);
00188
00189 p=NULL;
00190 }
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 static EPZSStructure* allocEPZSpattern(int searchpoints)
00206 {
00207 EPZSStructure *s;
00208
00209 s = calloc(1, sizeof(EPZSStructure));
00210 if (NULL == s)
00211 no_mem_exit("alloc_EPZSpattern: s");
00212
00213 s->searchPoints = searchpoints;
00214 s->point = (SPoint*) calloc(searchpoints, sizeof(SPoint));
00215
00216 return s;
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229 static void freeEPZSpattern(EPZSStructure* p)
00230 {
00231 if (p)
00232 {
00233 free ( (SPoint*) p->point);
00234 free(p);
00235 p=NULL;
00236 }
00237 }
00238
00239 static void assignEPZSpattern(EPZSStructure *pattern,int type, int stopSearch, int nextLast, EPZSStructure *nextpattern)
00240 {
00241 int i;
00242
00243 for (i = 0; i < pattern->searchPoints; i++)
00244 {
00245 pattern->point[i].motion.mv_x = pattern_data[type][i][0] >> mv_rescale;
00246 pattern->point[i].motion.mv_y = pattern_data[type][i][1] >> mv_rescale;
00247 pattern->point[i].start_nmbr = pattern_data[type][i][2];
00248 pattern->point[i].next_points = pattern_data[type][i][3];
00249 }
00250 pattern->stopSearch = stopSearch;
00251 pattern->nextLast = nextLast;
00252 pattern->nextpattern = nextpattern;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 static int RoundLog2 (int iValue)
00262 {
00263 int iRet = 0;
00264 int iValue_square = iValue * iValue;
00265
00266 while ((1 << (iRet + 1)) <= iValue_square)
00267 iRet++;
00268
00269 iRet = (iRet + 1) >> 1;
00270
00271 return iRet;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 static inline int add_predictor(MotionVector *cur_mv, MotionVector prd_mv, int mvScale, int shift_mv)
00282 {
00283 *cur_mv = prd_mv;
00284 cur_mv->mv_x = rshift_rnd_sf((mvScale * cur_mv->mv_x), shift_mv);
00285 cur_mv->mv_y = rshift_rnd_sf((mvScale * cur_mv->mv_y), shift_mv);
00286 return (*((int*) cur_mv) != 0);
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 static void EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
00296 {
00297 int pos;
00298 int searchpos, fieldsearchpos;
00299 int prednum = 0;
00300 int i;
00301 int search_range_qpel = params->EPZSSubPelGrid ? 2 : 0;
00302 SPoint *point = predictor->point;
00303
00304 if (mode == 0)
00305 {
00306 for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
00307 {
00308 searchpos = ((search_range << search_range_qpel)>> pos);
00309
00310 for (i=1; i>=-1; i-=2)
00311 {
00312 point[prednum ].motion.mv_x = i * searchpos;
00313 point[prednum++].motion.mv_y = 0;
00314 point[prednum ].motion.mv_x = i * searchpos;
00315 point[prednum++].motion.mv_y = i * searchpos;
00316 point[prednum ].motion.mv_x = 0;
00317 point[prednum++].motion.mv_y = i * searchpos;
00318 point[prednum ].motion.mv_x = -i * searchpos;
00319 point[prednum++].motion.mv_y = i * searchpos;
00320 }
00321 }
00322 }
00323 else
00324 {
00325 for (pos = RoundLog2 (search_range) - 2; pos > -1; pos--)
00326 {
00327 searchpos = ((search_range << search_range_qpel) >> pos);
00328 fieldsearchpos = ((3 * searchpos + 1) << search_range_qpel) >> 1;
00329
00330 for (i=1; i>=-1; i-=2)
00331 {
00332 point[prednum ].motion.mv_x = i * searchpos;
00333 point[prednum++].motion.mv_y = 0;
00334 point[prednum ].motion.mv_x = i * searchpos;
00335 point[prednum++].motion.mv_y = i * searchpos;
00336 point[prednum ].motion.mv_x = 0;
00337 point[prednum++].motion.mv_y = i * searchpos;
00338 point[prednum ].motion.mv_x = -i * searchpos;
00339 point[prednum++].motion.mv_y = i * searchpos;
00340 }
00341
00342 for (i=1; i>=-1; i-=2)
00343 {
00344 point[prednum ].motion.mv_x = i * fieldsearchpos;
00345 point[prednum++].motion.mv_y = -i * searchpos;
00346 point[prednum ].motion.mv_x = i * fieldsearchpos;
00347 point[prednum++].motion.mv_y = 0;
00348 point[prednum ].motion.mv_x = i * fieldsearchpos;
00349 point[prednum++].motion.mv_y = i * searchpos;
00350 point[prednum ].motion.mv_x = i * searchpos;
00351 point[prednum++].motion.mv_y = i * fieldsearchpos;
00352 point[prednum ].motion.mv_x = 0;
00353 point[prednum++].motion.mv_y = i * fieldsearchpos;
00354 point[prednum ].motion.mv_x = -i * searchpos;
00355 point[prednum++].motion.mv_y = i * fieldsearchpos;
00356 }
00357 }
00358 }
00359 predictor->searchPoints = prednum;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368 int EPZSInit (InputParameters *params, ImageParameters *img)
00369 {
00370 int pel_error_me = 1 << (img->bitdepth_luma - 8);
00371 int pel_error_me_cr = 1 << (img->bitdepth_chroma - 8);
00372 int i, memory_size = 0;
00373 double chroma_weight = params->ChromaMEEnable ? pel_error_me_cr * params->ChromaMEWeight * (double) (img->width_cr * img->height_cr) / (double) (img->width * img->height) : 0;
00374 int searchlevels = RoundLog2 (params->search_range) - 1;
00375
00376 searcharray = params->BiPredMotionEstimation? (2 * imax (params->search_range, params->BiPredMESearchRange) + 1) << (params->EPZSGrid) : (2 * params->search_range + 1)<< (params->EPZSGrid);
00377
00378 mv_rescale = params->EPZSSubPelGrid ? 0 : 2;
00379
00380
00381
00382
00383
00384 for (i=0;i<8;i++)
00385 {
00386 medthres[i] = params->EPZSMedThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
00387 maxthres[i] = params->EPZSMaxThresScale * (maxthres_base[i] * pel_error_me + (int) (maxthres_base[i] * chroma_weight + 0.5));
00388 minthres[i] = params->EPZSMinThresScale * (minthres_base[i] * pel_error_me + (int) (minthres_base[i] * chroma_weight + 0.5));
00389 subthres[i] = params->EPZSSubPelThresScale * (medthres_base[i] * pel_error_me + (int) (medthres_base[i] * chroma_weight + 0.5));
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 sdiamond = allocEPZSpattern(4);
00403 assignEPZSpattern(sdiamond, SDIAMOND, TRUE, TRUE, sdiamond);
00404 square = allocEPZSpattern(8);
00405 assignEPZSpattern(square, SQUARE, TRUE, TRUE, square);
00406 ediamond = allocEPZSpattern(12);
00407 assignEPZSpattern(ediamond, EDIAMOND, TRUE, TRUE, ediamond);
00408 ldiamond = allocEPZSpattern(8);
00409 assignEPZSpattern(ldiamond, LDIAMOND, TRUE, TRUE, ldiamond);
00410 sbdiamond = allocEPZSpattern(12);
00411 assignEPZSpattern(sbdiamond, SBDIAMOND, FALSE, TRUE, sdiamond);
00412 pmvfast = allocEPZSpattern(8);
00413 assignEPZSpattern(pmvfast, LDIAMOND, FALSE, TRUE, sdiamond);
00414
00415
00416
00417
00418
00419 window_predictor = allocEPZSpattern(searchlevels * 8);
00420 window_predictor_extended = allocEPZSpattern(searchlevels * 20);
00421 EPZSWindowPredictorInit ((short) params->search_range, window_predictor, 0);
00422 EPZSWindowPredictorInit ((short) params->search_range, window_predictor_extended, 1);
00423
00424
00425 predictor = allocEPZSpattern(searchlevels * 20 + 5 + 5 + 9 * (params->EPZSTemporal) + 3 * (params->EPZSSpatialMem));
00426
00427
00428
00429
00430
00431 memory_size += get_mem3Dint (&EPZSDistortion, 6, 7, img->width/BLOCK_SIZE);
00432 if (params->BiPredMotionEstimation)
00433 memory_size += get_mem3Dint (&EPZSBiDistortion, 6, 7, img->width/BLOCK_SIZE);
00434 memory_size += get_mem2Dshort ((short ***) &EPZSMap, searcharray, searcharray );
00435
00436 if (params->EPZSSpatialMem)
00437 {
00438 #if EPZSREF
00439 memory_size += get_mem5Dmv (&EPZS_Motion, 6, img->max_num_references, 7, 4, img->width/BLOCK_SIZE);
00440 #else
00441 memory_size += get_mem4Dmv (&EPZS_Motion, 6, 7, 4, img->width/BLOCK_SIZE);
00442 #endif
00443 }
00444
00445 if (params->EPZSTemporal)
00446 EPZSCo_located = allocEPZScolocated (img->width, img->height, active_sps->mb_adaptive_frame_field_flag);
00447
00448 switch (params->EPZSPattern)
00449 {
00450 case 5:
00451 searchPattern = pmvfast;
00452 break;
00453 case 4:
00454 searchPattern = sbdiamond;
00455 break;
00456 case 3:
00457 searchPattern = ldiamond;
00458 break;
00459 case 2:
00460 searchPattern = ediamond;
00461 break;
00462 case 1:
00463 searchPattern = square;
00464 break;
00465 case 0:
00466 default:
00467 searchPattern = sdiamond;
00468 break;
00469 }
00470
00471 switch (params->EPZSDual)
00472 {
00473 case 6:
00474 searchPatternD = pmvfast;
00475 break;
00476 case 5:
00477 searchPatternD = sbdiamond;
00478 break;
00479 case 4:
00480 searchPatternD = ldiamond;
00481 break;
00482 case 3:
00483 searchPatternD = ediamond;
00484 break;
00485 case 2:
00486 searchPatternD = square;
00487 break;
00488 case 1:
00489 default:
00490 searchPatternD = sdiamond;
00491 break;
00492 }
00493
00494 return memory_size;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503 void EPZSDelete (InputParameters *params)
00504 {
00505 if (params->EPZSTemporal)
00506 freeEPZScolocated (EPZSCo_located);
00507
00508
00509 free_mem2Dshort((short **) EPZSMap);
00510 free_mem3Dint (EPZSDistortion);
00511 if (params->BiPredMotionEstimation)
00512 free_mem3Dint (EPZSBiDistortion);
00513 freeEPZSpattern(window_predictor_extended);
00514 freeEPZSpattern(window_predictor);
00515 freeEPZSpattern(predictor);
00516
00517 freeEPZSpattern(pmvfast);
00518 freeEPZSpattern(sbdiamond);
00519 freeEPZSpattern(ldiamond);
00520 freeEPZSpattern(ediamond);
00521 freeEPZSpattern(sdiamond);
00522 freeEPZSpattern(square);
00523 if (params->EPZSSpatialMem)
00524 {
00525 #if EPZSREF
00526 free_mem5Dmv (EPZS_Motion);
00527 #else
00528 free_mem4Dmv (EPZS_Motion);
00529 #endif
00530 }
00531
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541 void EPZSSliceInit (InputParameters *params, ImageParameters *img, EPZSColocParams * p, StorablePicture ** listX[6])
00542 {
00543 StorablePicture *fs, *fs_top, *fs_bottom;
00544 StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
00545 int i, j, k, jj, jdiv, loffset;
00546 int prescale, iTRb, iTRp;
00547 int list = img->type == B_SLICE ? LIST_1 : LIST_0;
00548 int tempmv_scale[2];
00549 int epzs_scale[2][6][MAX_LIST_SIZE];
00550 int iref;
00551 int invmv_precision = 8;
00552
00553
00554
00555 for (j = LIST_0; j < 2 + (img->MbaffFrameFlag * 4); j ++)
00556 {
00557 for (k = 0; k < listXsize[j]; k++)
00558 {
00559 for (i = 0; i < listXsize[j]; i++)
00560 {
00561 if ((j >> 1) == 0)
00562 {
00563 iTRb = iClip3 (-128, 127, enc_picture->poc - listX[j][i]->poc);
00564 iTRp = iClip3 (-128, 127, enc_picture->poc - listX[j][k]->poc);
00565 }
00566 else if ((j >> 1) == 1)
00567 {
00568 iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[j][i]->poc);
00569 iTRp = iClip3 (-128, 127, enc_picture->top_poc - listX[j][k]->poc);
00570 }
00571 else
00572 {
00573 iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][i]->poc);
00574 iTRp = iClip3 (-128, 127, enc_picture->bottom_poc - listX[j][k]->poc);
00575 }
00576
00577 if (iTRp != 0)
00578 {
00579 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00580 mv_scale[j][i][k] = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
00581 }
00582 else
00583 mv_scale[j][i][k] = 256;
00584 }
00585 }
00586 }
00587
00588 if (params->EPZSTemporal)
00589 {
00590 fs_top = fs_bottom = fs = listX[list][0];
00591 if (listXsize[list]> 1)
00592 fs_top1 = fs_bottom1 = fs1 = listX[list][1];
00593 else
00594 fs_top1 = fs_bottom1 = fs1 = listX[list][0];
00595
00596 for (j = 0; j < 6; j++)
00597 {
00598 for (i = 0; i < 6; i++)
00599 {
00600 epzs_scale[0][j][i] = 256;
00601 epzs_scale[1][j][i] = 256;
00602 }
00603 }
00604
00605 for (j = 0; j < 2 + (img->MbaffFrameFlag * 4); j += 2)
00606 {
00607 for (i = 0; i < listXsize[j]; i++)
00608 {
00609 if (j == 0)
00610 iTRb = iClip3 (-128, 127, enc_picture->poc - listX[LIST_0 + j][i]->poc);
00611 else if (j == 2)
00612 iTRb = iClip3 (-128, 127, enc_picture->top_poc - listX[LIST_0 + j][i]->poc);
00613 else
00614 iTRb = iClip3 (-128, 127, enc_picture->bottom_poc - listX[LIST_0 + j][i]->poc);
00615 iTRp = iClip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
00616 if (iTRp != 0)
00617 {
00618 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00619 prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
00620
00621 }
00622 else
00623 prescale = 256;
00624 epzs_scale[0][j][i] = rshift_rnd_sf((mv_scale[j][0][i] * prescale), 8);
00625 epzs_scale[0][j + 1][i] = prescale - 256;
00626
00627 if (listXsize[list + j]>1)
00628 {
00629 iTRp = iClip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
00630 if (iTRp != 0)
00631 {
00632 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00633 prescale = iClip3 (-2048, 2047, rshift_rnd_sf((iTRb * prescale), 6));
00634
00635 }
00636 else
00637 prescale = 256;
00638 epzs_scale[1][j][i] = rshift_rnd_sf((mv_scale[j][1][i] * prescale), 8);
00639 epzs_scale[1][j + 1][i] = prescale - 256;
00640 }
00641 else
00642 {
00643 epzs_scale[1][j][i] = epzs_scale[0][j][i];
00644 epzs_scale[1][j + 1][i] = epzs_scale[0][j + 1][i];
00645 }
00646 }
00647 }
00648 if (img->MbaffFrameFlag)
00649 {
00650 fs_top = listX[list + 2][0];
00651 fs_bottom = listX[list + 4][0];
00652 if (listXsize[0]> 1)
00653 {
00654 fs_top1 = listX[list + 2][1];
00655 fs_bottom = listX[list + 4][1];
00656 }
00657 }
00658 else
00659 {
00660 if (img->structure != FRAME)
00661 {
00662 if ((img->structure != fs->structure) && (fs->coded_frame))
00663 {
00664 if (img->structure == TOP_FIELD)
00665 {
00666 fs_top = fs_bottom = fs = listX[list][0]->top_field;
00667 fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
00668 }
00669 else
00670 {
00671 fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
00672 fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
00673 }
00674 }
00675 }
00676 }
00677
00678 if (!active_sps->frame_mbs_only_flag)
00679 {
00680 if (img->MbaffFrameFlag)
00681 {
00682 for (j = 0; j < fs->size_y >> 2; j++)
00683 {
00684 jj = j >> 1;
00685 jdiv = jj + 4 * (j >> 3);
00686
00687 for (i = 0; i < fs->size_x >> 2; i++)
00688 {
00689 if (fs->motion.field_frame[j][i])
00690 {
00691
00692
00693
00694 if (iabs (enc_picture->poc - fs_bottom->poc) > iabs (enc_picture->poc - fs_top->poc))
00695 {
00696 tempmv_scale[LIST_0] = 256;
00697 tempmv_scale[LIST_1] = 0;
00698
00699 if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
00700 {
00701 fsx = fs_top1;
00702 loffset = 1;
00703 }
00704 else
00705 {
00706 fsx = fs_top;
00707 loffset = 0;
00708 }
00709
00710 if (fs->motion.ref_id [LIST_0][jdiv][i] != -1)
00711 {
00712 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
00713 {
00714 if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv][i])
00715 {
00716 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00717 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00718 break;
00719 }
00720 }
00721 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
00722 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
00723 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
00724 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
00725 }
00726 else
00727 {
00728 p->frame[LIST_0][j][i].mv_x = 0;
00729 p->frame[LIST_0][j][i].mv_y = 0;
00730 p->frame[LIST_1][j][i].mv_x = 0;
00731 p->frame[LIST_1][j][i].mv_y = 0;
00732 }
00733 }
00734 else
00735 {
00736 tempmv_scale[LIST_0] = 256;
00737 tempmv_scale[LIST_1] = 0;
00738
00739 if (fs->motion.ref_id [LIST_0][jdiv + 4][i] < 0 && listXsize[LIST_0] > 1)
00740 {
00741 fsx = fs_bottom1;
00742 loffset = 1;
00743 }
00744 else
00745 {
00746 fsx = fs_bottom;
00747 loffset = 0;
00748 }
00749
00750 if (fs->motion.ref_id [LIST_0][jdiv + 4][i] != -1)
00751 {
00752 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
00753 {
00754 if (enc_picture->ref_pic_num[LIST_0][iref]==fs->motion.ref_id [LIST_0][jdiv + 4][i])
00755 {
00756 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00757 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00758 break;
00759 }
00760 }
00761 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
00762 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
00763 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][0]), invmv_precision));
00764 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][jj][i][1]), invmv_precision));
00765 }
00766 else
00767 {
00768 p->frame[LIST_0][j][i].mv_x = 0;
00769 p->frame[LIST_0][j][i].mv_y = 0;
00770 p->frame[LIST_1][j][i].mv_x = 0;
00771 p->frame[LIST_1][j][i].mv_y = 0;
00772 }
00773 }
00774 }
00775 else
00776 {
00777 tempmv_scale[LIST_0] = 256;
00778 tempmv_scale[LIST_1] = 0;
00779 if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
00780 {
00781 fsx = fs1;
00782 loffset = 1;
00783 }
00784 else
00785 {
00786 fsx = fs;
00787 loffset = 0;
00788 }
00789
00790 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
00791 {
00792 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
00793 {
00794 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
00795 {
00796 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00797 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00798 break;
00799 }
00800 }
00801 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00802 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00803 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00804 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00805 }
00806 else
00807 {
00808 p->frame[LIST_0][j][i].mv_x = 0;
00809 p->frame[LIST_0][j][i].mv_y = 0;
00810 p->frame[LIST_1][j][i].mv_x = 0;
00811 p->frame[LIST_1][j][i].mv_y = 0;
00812 }
00813 }
00814 }
00815 }
00816 }
00817 else
00818 {
00819 for (j = 0; j < fs->size_y >> 2; j++)
00820 {
00821 jj = j >> 1;
00822 jdiv = jj + 4 * (j >> 3);
00823
00824 for (i = 0; i < fs->size_x >> 2; i++)
00825 {
00826 tempmv_scale[LIST_0] = 256;
00827 tempmv_scale[LIST_1] = 0;
00828 if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
00829 {
00830 fsx = fs1;
00831 loffset = 1;
00832 }
00833 else
00834 {
00835 fsx = fs;
00836 loffset = 0;
00837 }
00838
00839 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
00840 {
00841 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
00842 {
00843 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
00844 {
00845 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00846 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00847 break;
00848 }
00849 }
00850 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00851 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00852 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00853 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00854 }
00855 else
00856 {
00857 p->frame[LIST_0][j][i].mv_x = 0;
00858 p->frame[LIST_0][j][i].mv_y = 0;
00859 p->frame[LIST_1][j][i].mv_x = 0;
00860 p->frame[LIST_1][j][i].mv_y = 0;
00861 }
00862 }
00863 }
00864 }
00865
00866
00867 if (img->structure || img->MbaffFrameFlag)
00868 {
00869 for (j = 0; j < fs->size_y / 8; j++)
00870 {
00871 for (i = 0; i < fs->size_x / 4; i++)
00872 {
00873 if (!img->MbaffFrameFlag)
00874 {
00875 tempmv_scale[LIST_0] = 256;
00876 tempmv_scale[LIST_1] = 0;
00877
00878 if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
00879 {
00880 fsx = fs1;
00881 loffset = 1;
00882 }
00883 else
00884 {
00885 fsx = fs;
00886 loffset = 0;
00887 }
00888
00889 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
00890 {
00891 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
00892 {
00893 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
00894 {
00895 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00896 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00897 break;
00898 }
00899 }
00900 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00901 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00902 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00903 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00904 }
00905 else
00906 {
00907 p->frame[LIST_0][j][i].mv_x = 0;
00908 p->frame[LIST_0][j][i].mv_y = 0;
00909 p->frame[LIST_1][j][i].mv_x = 0;
00910 p->frame[LIST_1][j][i].mv_y = 0;
00911 }
00912 }
00913 else
00914 {
00915 tempmv_scale[LIST_0] = 256;
00916 tempmv_scale[LIST_1] = 0;
00917
00918 if (fs_bottom->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
00919 {
00920 fsx = fs_bottom1;
00921 loffset = 1;
00922 }
00923 else
00924 {
00925 fsx = fs_bottom;
00926 loffset = 0;
00927 }
00928
00929 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
00930 {
00931 for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 4]); iref++)
00932 {
00933 if (enc_picture->ref_pic_num[LIST_0 + 4][iref]==fsx->motion.ref_id [LIST_0][j][i])
00934 {
00935 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref];
00936 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref];
00937 break;
00938 }
00939 }
00940 p->bot[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00941 p->bot[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00942 p->bot[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00943 p->bot[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00944 }
00945 else
00946 {
00947 p->bot[LIST_0][j][i].mv_x = 0;
00948 p->bot[LIST_0][j][i].mv_y = 0;
00949 p->bot[LIST_1][j][i].mv_x = 0;
00950 p->bot[LIST_1][j][i].mv_y = 0;
00951 }
00952
00953 if (!fs->motion.field_frame[2 * j][i])
00954 {
00955 p->bot[LIST_0][j][i].mv_y = (p->bot[LIST_0][j][i].mv_y + 1) >> 1;
00956 p->bot[LIST_1][j][i].mv_y = (p->bot[LIST_1][j][i].mv_y + 1) >> 1;
00957 }
00958
00959 tempmv_scale[LIST_0] = 256;
00960 tempmv_scale[LIST_1] = 0;
00961
00962 if (fs_top->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
00963 {
00964 fsx = fs_top1;
00965 loffset = 1;
00966 }
00967 else
00968 {
00969 fsx = fs_top;
00970 loffset = 0;
00971 }
00972
00973 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
00974 {
00975 for (iref = 0; iref < imin(2*img->num_ref_idx_l0_active,listXsize[LIST_0 + 2]); iref++)
00976 {
00977 if (enc_picture->ref_pic_num[LIST_0 + 2][iref]==fsx->motion.ref_id [LIST_0][j][i])
00978 {
00979 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref];
00980 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref];
00981 break;
00982 }
00983 }
00984 p->top[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00985 p->top[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00986 p->top[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
00987 p->top[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
00988 }
00989 else
00990 {
00991 p->top[LIST_0][j][i].mv_x = 0;
00992 p->top[LIST_0][j][i].mv_y = 0;
00993 p->top[LIST_1][j][i].mv_x = 0;
00994 p->top[LIST_1][j][i].mv_y = 0;
00995 }
00996
00997 if (!fs->motion.field_frame[2 * j][i])
00998 {
00999 p->top[LIST_0][j][i].mv_y = (p->top[LIST_0][j][i].mv_y + 1) >> 1;
01000 p->top[LIST_1][j][i].mv_y = (p->top[LIST_1][j][i].mv_y + 1) >> 1;
01001 }
01002 }
01003 }
01004 }
01005 }
01006 }
01007
01008
01009 if (!active_sps->frame_mbs_only_flag )
01010 {
01011
01012
01013 if (!img->structure)
01014 {
01015 for (j = 0; j < fs->size_y >> 2; j++)
01016 {
01017 jj = j>>1;
01018 jdiv = (j>>1) + ((j>>3) << 2);
01019 for (i = 0; i < fs->size_x >> 2; i++)
01020 {
01021 if (fs->motion.field_frame[j][i])
01022 {
01023 tempmv_scale[LIST_0] = 256;
01024 tempmv_scale[LIST_1] = 0;
01025
01026 if (fs->motion.ref_id [LIST_0][jdiv][i] < 0 && listXsize[LIST_0] > 1)
01027 {
01028 fsx = fs1;
01029 loffset = 1;
01030 }
01031 else
01032 {
01033 fsx = fs;
01034 loffset = 0;
01035 }
01036 if (fsx->motion.ref_id [LIST_0][jdiv][i] != -1)
01037 {
01038 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
01039 {
01040 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][jdiv][i])
01041 {
01042 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
01043 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
01044 break;
01045 }
01046 }
01047
01048 if (iabs (enc_picture->poc - fsx->bottom_field->poc) > iabs (enc_picture->poc - fsx->top_field->poc))
01049 {
01050 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
01051 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
01052 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
01053 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->top_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
01054 }
01055 else
01056 {
01057 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
01058 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
01059 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][0]), invmv_precision));
01060 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->bottom_field->motion.mv[LIST_0][jj][i][1]), invmv_precision));
01061 }
01062 }
01063 else
01064 {
01065 p->frame[LIST_0][j][i].mv_x = 0;
01066 p->frame[LIST_0][j][i].mv_y = 0;
01067 p->frame[LIST_1][j][i].mv_x = 0;
01068 p->frame[LIST_1][j][i].mv_y = 0;
01069 }
01070 }
01071 }
01072 }
01073 }
01074 }
01075
01076 if (active_sps->frame_mbs_only_flag)
01077 {
01078 for (j = 0; j < fs->size_y >> 2; j++)
01079 {
01080 for (i = 0; i < fs->size_x >> 2; i++)
01081 {
01082 tempmv_scale[LIST_0] = 256;
01083 tempmv_scale[LIST_1] = 0;
01084 if (fs->motion.ref_id [LIST_0][j][i] < 0 && listXsize[LIST_0] > 1)
01085 {
01086 fsx = fs1;
01087 loffset = 1;
01088 }
01089 else
01090 {
01091 fsx = fs;
01092 loffset = 0;
01093 }
01094
01095 if (fsx->motion.ref_id [LIST_0][j][i] != -1)
01096 {
01097 for (iref = 0; iref < imin(img->num_ref_idx_l0_active,listXsize[LIST_0]); iref++)
01098 {
01099 if (enc_picture->ref_pic_num[LIST_0][iref]==fsx->motion.ref_id [LIST_0][j][i])
01100 {
01101 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
01102 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
01103 break;
01104 }
01105 }
01106
01107 p->frame[LIST_0][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
01108 p->frame[LIST_0][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_0] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
01109 p->frame[LIST_1][j][i].mv_x = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][0]), invmv_precision));
01110 p->frame[LIST_1][j][i].mv_y = iClip3 (-32768, 32767, rshift_rnd_sf((tempmv_scale[LIST_1] * fsx->motion.mv[LIST_0][j][i][1]), invmv_precision));
01111 }
01112 else
01113 {
01114 p->frame[LIST_0][j][i].mv_x = 0;
01115 p->frame[LIST_0][j][i].mv_y = 0;
01116 p->frame[LIST_1][j][i].mv_x = 0;
01117 p->frame[LIST_1][j][i].mv_y = 0;
01118 }
01119 }
01120 }
01121 }
01122
01123 if (!active_sps->frame_mbs_only_flag)
01124 {
01125 for (j = 0; j < fs->size_y >> 2; j++)
01126 {
01127 for (i = 0; i < fs->size_x >> 2; i++)
01128 {
01129 if ((!img->MbaffFrameFlag && !img->structure && fs->motion.field_frame[j][i]) || (img->MbaffFrameFlag && fs->motion.field_frame[j][i]))
01130 {
01131 p->frame[LIST_0][j][i].mv_y *= 2;
01132 p->frame[LIST_1][j][i].mv_y *= 2;
01133 }
01134 else if (img->structure && !fs->motion.field_frame[j][i])
01135 {
01136 p->frame[LIST_0][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_0][j][i].mv_y, 1);
01137 p->frame[LIST_1][j][i].mv_y = rshift_rnd_sf(p->frame[LIST_1][j][i].mv_y, 1);
01138 }
01139 }
01140 }
01141 }
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150
01151
01152 static short EPZSSpatialPredictors (PixelPos *block_a,
01153 PixelPos *block_b,
01154 PixelPos *block_c,
01155 PixelPos *block_d,
01156 int list,
01157 int list_offset,
01158 short ref,
01159 char **refPic,
01160 short ***tmp_mv,
01161 SPoint *point)
01162 {
01163 int refA, refB, refC, refD;
01164 int *mot_scale = mv_scale[list + list_offset][ref];
01165 short sp_shift_mv = 8 + mv_rescale;
01166 int fixed_mv = (12 >> mv_rescale);
01167
01168
01169 point[0].motion.mv_x = 0;
01170 point[0].motion.mv_y = 0;
01171
01172
01173 if (!img->MbaffFrameFlag)
01174 {
01175 refA = block_a->available ? (int) refPic[block_a->pos_y][block_a->pos_x] : -1;
01176 refB = block_b->available ? (int) refPic[block_b->pos_y][block_b->pos_x] : -1;
01177 refC = block_c->available ? (int) refPic[block_c->pos_y][block_c->pos_x] : -1;
01178 refD = block_d->available ? (int) refPic[block_d->pos_y][block_d->pos_x] : -1;
01179
01180
01181 if (block_a->available)
01182 {
01183 point[1].motion.mv_x = rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][0]), sp_shift_mv);
01184 point[1].motion.mv_y = rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][1]), sp_shift_mv);
01185 }
01186 else
01187 {
01188 point[1].motion.mv_x = fixed_mv;
01189 point[1].motion.mv_y = 0;
01190 }
01191
01192 if (block_b->available)
01193 {
01194 point[2].motion.mv_x = rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][0]), sp_shift_mv);
01195 point[2].motion.mv_y = rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][1]), sp_shift_mv);
01196 }
01197 else
01198 {
01199 point[2].motion.mv_x = 0;
01200 point[2].motion.mv_y = fixed_mv;
01201 }
01202
01203
01204 if (block_c->available)
01205 {
01206 point[3].motion.mv_x = rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][0]), sp_shift_mv);
01207 point[3].motion.mv_y = rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][1]), sp_shift_mv);
01208 }
01209 else
01210 {
01211 point[3].motion.mv_x = -fixed_mv;
01212 point[3].motion.mv_y = 0;
01213 }
01214
01215
01216 if (block_d->available)
01217 {
01218 point[4].motion.mv_x = rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][0]), sp_shift_mv);
01219 point[4].motion.mv_y = rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][1]), sp_shift_mv);
01220 }
01221 else
01222 {
01223 point[4].motion.mv_x = 0;
01224 point[4].motion.mv_y = -fixed_mv;
01225 }
01226 }
01227 else
01228 {
01229
01230 if (list_offset)
01231 {
01232 refA = block_a->available
01233 ? img->mb_data[block_a->mb_addr].mb_field
01234 ? (int) refPic[block_a->pos_y][block_a->pos_x]
01235 : (int) refPic[block_a->pos_y][block_a->pos_x] * 2 : -1;
01236 refB =block_b->available
01237 ? img->mb_data[block_b->mb_addr].mb_field
01238 ? (int) refPic[block_b->pos_y][block_b->pos_x]
01239 : (int) refPic[block_b->pos_y][block_b->pos_x] * 2 : -1;
01240 refC = block_c->available
01241 ? img->mb_data[block_c->mb_addr].mb_field
01242 ? (int) refPic[block_c->pos_y][block_c->pos_x]
01243 : (int) refPic[block_c->pos_y][block_c->pos_x] * 2 : -1;
01244 refD = block_d->available
01245 ? img->mb_data[block_d->mb_addr].mb_field
01246 ? (int) refPic[block_d->pos_y][block_d->pos_x]
01247 : (int) refPic[block_d->pos_y][block_d->pos_x] * 2 : -1;
01248
01249
01250 point[1].motion.mv_x = (block_a->available)
01251 ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][0]), sp_shift_mv) : fixed_mv;
01252 point[1].motion.mv_y = (block_a->available)
01253 ? img->mb_data[block_a->mb_addr].mb_field
01254 ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][1]), sp_shift_mv)
01255 : rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][1]), sp_shift_mv + 1) : 0;
01256
01257
01258 point[2].motion.mv_x = (block_b->available)
01259 ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][0]), sp_shift_mv) : 0;
01260 point[2].motion.mv_y = (block_b->available)
01261 ? img->mb_data[block_b->mb_addr].mb_field
01262 ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][1]), sp_shift_mv)
01263 : rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][1]), sp_shift_mv + 1) : fixed_mv;
01264
01265
01266 point[3].motion.mv_x = (block_c->available)
01267 ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][0]), sp_shift_mv) : -fixed_mv;
01268 point[3].motion.mv_y = (block_c->available)
01269 ? img->mb_data[block_c->mb_addr].mb_field
01270 ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][1]), sp_shift_mv)
01271 : rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][1]), sp_shift_mv + 1) : 0;
01272
01273
01274 point[4].motion.mv_x = (block_d->available)
01275 ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][0]), sp_shift_mv) : 0;
01276 point[4].motion.mv_y = (block_d->available)
01277 ? img->mb_data[block_d->mb_addr].mb_field
01278 ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][1]), sp_shift_mv)
01279 : rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][1]), sp_shift_mv + 1) : -fixed_mv;
01280 }
01281 else
01282 {
01283 refA = block_a->available
01284 ? img->mb_data[block_a->mb_addr].mb_field
01285 ? (int) refPic[block_a->pos_y][block_a->pos_x] >> 1
01286 : (int) refPic[block_a->pos_y][block_a->pos_x] : -1;
01287 refB = block_b->available
01288 ? img->mb_data[block_b->mb_addr].mb_field
01289 ? (int) refPic[block_b->pos_y][block_b->pos_x] >> 1
01290 : (int) refPic[block_b->pos_y][block_b->pos_x] : -1;
01291 refC = block_c->available
01292 ? img->mb_data[block_c->mb_addr].mb_field
01293 ? (int) refPic[block_c->pos_y][block_c->pos_x] >> 1
01294 : (int) refPic[block_c->pos_y][block_c->pos_x] : -1;
01295 refD = block_d->available
01296 ? img->mb_data[block_d->mb_addr].mb_field
01297 ? (int) refPic[block_d->pos_y][block_d->pos_x] >> 1
01298 : (int) refPic[block_d->pos_y][block_d->pos_x] : -1;
01299
01300
01301 point[1].motion.mv_x = (block_a->available)
01302 ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][0]), sp_shift_mv) : fixed_mv;
01303 point[1].motion.mv_y = (block_a->available)
01304 ? img->mb_data[block_a->mb_addr].mb_field
01305 ? rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][1]), sp_shift_mv - 1)
01306 : rshift_rnd_sf((mot_scale[refA] * tmp_mv[block_a->pos_y][block_a->pos_x][1]), sp_shift_mv) : 0;
01307
01308
01309 point[2].motion.mv_x = (block_b->available)
01310 ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][0]), sp_shift_mv) : 0;
01311 point[2].motion.mv_y = (block_b->available)
01312 ? img->mb_data[block_b->mb_addr].mb_field
01313 ? rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][1]), sp_shift_mv - 1)
01314 : rshift_rnd_sf((mot_scale[refB] * tmp_mv[block_b->pos_y][block_b->pos_x][1]), sp_shift_mv) : fixed_mv;
01315
01316
01317 point[3].motion.mv_x = (block_c->available)
01318 ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][0]), sp_shift_mv) : -fixed_mv;
01319 point[3].motion.mv_y = (block_c->available)
01320 ? img->mb_data[block_c->mb_addr].mb_field
01321 ? rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][1]), sp_shift_mv - 1)
01322 : rshift_rnd_sf((mot_scale[refC] * tmp_mv[block_c->pos_y][block_c->pos_x][1]), sp_shift_mv) : 0;
01323
01324
01325 point[4].motion.mv_x = (block_d->available)
01326 ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][0]), sp_shift_mv) : 0;
01327 point[4].motion.mv_y = (block_d->available)
01328 ? img->mb_data[block_d->mb_addr].mb_field
01329 ? rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][1]), sp_shift_mv - 1)
01330 : rshift_rnd_sf((mot_scale[refD] * tmp_mv[block_d->pos_y][block_d->pos_x][1]), sp_shift_mv) : -fixed_mv;
01331 }
01332 }
01333
01334 return ((refA == -1) + (refB == -1) + (refC == -1 && refD == -1));
01335 }
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 static void EPZSSpatialMemPredictors (int list,
01346 short ref,
01347 int blocktype,
01348 int pic_x,
01349 int bs_x,
01350 int bs_y,
01351 int by,
01352 int *prednum,
01353 int img_width,
01354 SPoint *point)
01355 {
01356 #if EPZSREF
01357 MotionVector **prd_mv = EPZS_Motion[list][ref][blocktype];
01358 MotionVector *cur_mv = &point[*prednum].motion;
01359
01360
01361 if (pic_x > 0)
01362 {
01363 *cur_mv = prd_mv[by][pic_x - bs_x];
01364 *prednum += (*((int*) cur_mv) != 0);
01365 cur_mv = &point[*prednum].motion;
01366 }
01367
01368 by = (by > 0) ? by - bs_y: 4 - bs_y;
01369
01370 *cur_mv = prd_mv[by][pic_x];
01371 *prednum += (*((int*) cur_mv) != 0);
01372
01373
01374 if (pic_x + bs_x < img_width)
01375 {
01376 cur_mv = &point[*prednum].motion;
01377 *cur_mv = prd_mv[by][pic_x + bs_x];
01378 *prednum += (*((int*) cur_mv) != 0);
01379 }
01380
01381 #else
01382 int mot_scale = mv_scale[list][ref][0];
01383 MotionVector **prd_mv = EPZS_Motion[list][blocktype];
01384
01385
01386 point[*prednum].motion.mv_x = (pic_x > 0)
01387 ? rshift_rnd_sf((mot_scale * prd_mv[by][pic_x - bs_x].mv_x), 8)
01388 : 0;
01389 point[*prednum].motion.mv_y = (pic_x > 0)
01390 ? rshift_rnd_sf((mot_scale * prd_mv[by][pic_x - bs_x].mv_y), 8)
01391 : 0;
01392 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01393
01394
01395 point[*prednum].motion.mv_x = (by > 0)
01396 ? rshift_rnd_sf((mot_scale * prd_mv[by - bs_y][pic_x].mv_x), 8)
01397 : rshift_rnd_sf((mot_scale * prd_mv[4 - bs_y][pic_x].mv_x), 8);
01398 point[*prednum].motion.mv_y = (by > 0)
01399 ? rshift_rnd_sf((mot_scale * prd_mv[by - bs_y][pic_x].mv_y), 8)
01400 : rshift_rnd_sf((mot_scale * prd_mv[4 - bs_y][pic_x].mv_y), 8);
01401 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01402
01403
01404 point[*prednum].motion.mv_x = (pic_x + bs_x < img_width)
01405 ? (by > 0)
01406 ? rshift_rnd_sf((mot_scale * prd_mv[by - bs_y][pic_x + bs_x].mv_x), 8)
01407 : rshift_rnd_sf((mot_scale * prd_mv[4 - bs_y][pic_x + bs_x].mv_x), 8)
01408 : 0;
01409 point[*prednum].motion.mv_y = (pic_x + bs_x < img_width)
01410 ? (by > 0)
01411 ? rshift_rnd_sf((mot_scale * prd_mv[by - bs_y][pic_x + bs_x].mv_y), 8)
01412 : rshift_rnd_sf((mot_scale * prd_mv[4 - bs_y][pic_x + bs_x].mv_y), 8)
01413 : 0;
01414 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01415 #endif
01416 }
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426 static void
01427 EPZSTemporalPredictors (int list,
01428 int list_offset,
01429 short ref,
01430 int o_block_x,
01431 int o_block_y,
01432 SPoint *point,
01433 int *prednum,
01434 int block_available_left,
01435 int block_available_up,
01436 int block_available_right,
01437 int block_available_below,
01438 int blockshape_x,
01439 int blockshape_y,
01440 int stopCriterion,
01441 int min_mcost)
01442 {
01443 int mvScale = mv_scale[list + list_offset][ref][0];
01444 MotionVector **col_mv = (list_offset == 0) ? EPZSCo_located->frame[list]
01445 : (list_offset == 2) ? EPZSCo_located->top[list] : EPZSCo_located->bot[list];
01446 short temp_shift_mv = 8 + mv_rescale;
01447 MotionVector *cur_mv = &point[*prednum].motion;
01448
01449 *prednum += add_predictor(cur_mv, col_mv[o_block_y][o_block_x], mvScale, temp_shift_mv);
01450
01451 if (min_mcost > stopCriterion && ref < 2)
01452 {
01453 if (block_available_left)
01454 {
01455 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, temp_shift_mv);
01456
01457
01458 if (block_available_up)
01459 {
01460 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, temp_shift_mv);
01461 }
01462
01463 if (block_available_below)
01464 {
01465 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, temp_shift_mv);
01466 }
01467 }
01468
01469 if (block_available_up)
01470 {
01471 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, temp_shift_mv);
01472 }
01473
01474
01475 if (block_available_right)
01476 {
01477 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
01478
01479 if (block_available_up)
01480 {
01481 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, temp_shift_mv);
01482 }
01483 if (block_available_below)
01484 {
01485 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, temp_shift_mv);
01486 }
01487 }
01488
01489 if (block_available_below)
01490 {
01491 *prednum += add_predictor( &point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, temp_shift_mv);
01492 }
01493 }
01494 }
01495
01496
01497
01498
01499
01500
01501
01502 static void EPZSBlockTypePredictors (int block_x, int block_y, int blocktype, int ref, int list,
01503 SPoint *point, int *prednum)
01504 {
01505 short *****all_mv = img->all_mv[list];
01506 short block_shift_mv = 8 + mv_rescale;
01507 MotionVector *cur_mv = &point[*prednum].motion;
01508
01509 cur_mv->mv_x = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][0]), mv_rescale);
01510 cur_mv->mv_y = rshift_rnd((all_mv[ref][blk_parent[blocktype]][block_y][block_x][1]), mv_rescale);
01511
01512 *prednum += (*((int*) cur_mv) != 0);
01513
01514 if ((ref > 0) && (blocktype < 5 || img->structure != FRAME))
01515 {
01516 cur_mv = &point[*prednum].motion;
01517 cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][0]), block_shift_mv );
01518 cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][ref-1] * all_mv[ref-1][blocktype][block_y][block_x][1]), block_shift_mv );
01519
01520 *prednum += (*((int*) cur_mv) != 0);
01521
01522 cur_mv = &point[*prednum].motion;
01523 cur_mv->mv_x = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][0]), block_shift_mv );
01524 cur_mv->mv_y = rshift_rnd_sf((mv_scale[list][ref][0] * all_mv[0][blocktype][block_y][block_x][1]), block_shift_mv );
01525
01526 *prednum += (*((int*) cur_mv) != 0);
01527 }
01528
01529 if (blocktype != 1)
01530 {
01531 cur_mv = &point[*prednum].motion;
01532 cur_mv->mv_x = rshift_rnd((all_mv[ref][1][block_y][block_x][0]), mv_rescale);
01533 cur_mv->mv_y = rshift_rnd((all_mv[ref][1][block_y][block_x][1]), mv_rescale);
01534
01535 *prednum += (*((int*) cur_mv) != 0);
01536 }
01537
01538 if (blocktype != 4)
01539 {
01540 cur_mv = &point[*prednum].motion;
01541 cur_mv->mv_x = rshift_rnd((all_mv[ref][4][block_y][block_x][0]), mv_rescale);
01542 cur_mv->mv_y = rshift_rnd((all_mv[ref][4][block_y][block_x][1]), mv_rescale);
01543
01544 *prednum += (*((int*) cur_mv) != 0);
01545 }
01546 }
01547
01548
01549
01550
01551
01552
01553
01554 static void EPZSWindowPredictors (MotionVector *mv, EPZSStructure *predictor, int *prednum, int extended)
01555 {
01556 int pos;
01557 EPZSStructure *windowPred = (extended) ? window_predictor_extended : window_predictor;
01558 SPoint *wPoint = &windowPred->point[0];
01559 SPoint *pPoint = &predictor->point[(*prednum)];
01560
01561 for (pos = 0; pos < windowPred->searchPoints; pos++)
01562 {
01563 (pPoint )->motion.mv_x = mv->mv_x + (wPoint )->motion.mv_x;
01564 (pPoint++)->motion.mv_y = mv->mv_y + (wPoint++)->motion.mv_y;
01565 }
01566 *prednum += windowPred->searchPoints;
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576 int
01577 EPZSPelBlockMotionSearch (Macroblock *currMB,
01578 imgpel * cur_pic,
01579 short ref,
01580 int list,
01581 char ***refPic,
01582 short ****tmp_mv,
01583 int pic_pix_x,
01584 int pic_pix_y,
01585 int blocktype,
01586 MotionVector *pred_mv,
01587 MotionVector *mv,
01588 int search_range,
01589 int min_mcost,
01590 int lambda_factor,
01591 int apply_weights)
01592 {
01593 int cur_list = list + currMB->list_offset;
01594 StorablePicture *ref_picture = listX[cur_list][ref];
01595
01596 short blocksize_y = params->blc_size[blocktype][1];
01597 short blocksize_x = params->blc_size[blocktype][0];
01598 short blockshape_x = (blocksize_x >> 2);
01599 short blockshape_y = (blocksize_y >> 2);
01600
01601 short mb_x = pic_pix_x - img->opix_x;
01602 short mb_y = pic_pix_y - img->opix_y;
01603 short pic_pix_x2 = pic_pix_x >> 2;
01604 short pic_pix_y2 = pic_pix_y >> 2;
01605 short block_x = (mb_x >> 2);
01606 short block_y = (mb_y >> 2);
01607
01608 int stopCriterion = medthres[blocktype];
01609 int mapCenter_x = search_range - mv->mv_x;
01610 int mapCenter_y = search_range - mv->mv_y;
01611 int second_mcost = INT_MAX;
01612 int *prevSad = EPZSDistortion[cur_list][blocktype - 1];
01613 MotionVector *p_motion = NULL;
01614 int mv_range = (2<<(2-mv_rescale));
01615
01616 short invalid_refs = 0;
01617 byte checkMedian = FALSE;
01618 EPZSStructure *searchPatternF = searchPattern;
01619
01620 MotionVector center, tmp = *mv, tmp2 = {0, 0}, cand, pred;
01621 pred.mv_x = (pic_pix_x << 2) + pred_mv->mv_x;
01622 pred.mv_y = (pic_pix_y << 2) + pred_mv->mv_y;
01623 center.mv_x = (pic_pix_x << (params->EPZSGrid))+ mv->mv_x;
01624 center.mv_y = (pic_pix_y << (params->EPZSGrid))+ mv->mv_y;
01625 cand.mv_x = center.mv_x << mv_rescale;
01626 cand.mv_y = center.mv_y << mv_rescale;
01627
01628 computePred = computeUniPred[F_PEL + 3 * apply_weights];
01629
01630 EPZSBlkCount ++;
01631 if (EPZSBlkCount == 0)
01632 EPZSBlkCount ++;
01633
01634 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
01635
01636 img_width = ref_picture->size_x;
01637 img_height = ref_picture->size_y;
01638 width_pad = ref_picture->size_x_pad;
01639 height_pad = ref_picture->size_y_pad;
01640
01641 if (ChromaMEEnable)
01642 {
01643 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
01644 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
01645 width_pad_cr = ref_picture->size_x_cr_pad;
01646 height_pad_cr = ref_picture->size_y_cr_pad;
01647 }
01648
01649 pic_pix_x = (pic_pix_x << (params->EPZSGrid));
01650 pic_pix_y = (pic_pix_y << (params->EPZSGrid));
01651
01652 if (params->EPZSSpatialMem)
01653 {
01654 #if EPZSREF
01655 p_motion = &EPZS_Motion[cur_list][ref][blocktype - 1][block_y][pic_pix_x2];
01656 #else
01657 p_motion = &EPZS_Motion[cur_list][blocktype - 1][block_y][pic_pix_x2];
01658 #endif
01659 }
01660
01661
01662
01663
01664
01665 EPZSMap[search_range][search_range] = EPZSBlkCount;
01666
01667
01668 min_mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
01669
01670
01671 min_mcost += computePred(cur_pic, blocksize_y, blocksize_x,
01672 INT_MAX, cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4);
01673
01674
01675 if ((ref>0 && img->structure == FRAME)
01676 && (prevSad[pic_pix_x2] < imin(medthres[blocktype],min_mcost)))
01677 {
01678 #if EPZSREF
01679 if (params->EPZSSpatialMem)
01680 #else
01681 if (params->EPZSSpatialMem && ref == 0)
01682 #endif
01683 {
01684 *p_motion = tmp;
01685 }
01686 return min_mcost;
01687 }
01688
01689
01690
01691 if (min_mcost > stopCriterion)
01692 {
01693 int mb_available_right = (img->mb_x < (img_width >> 4) - 1);
01694 int mb_available_below = (img->mb_y < (img_height >> 4) - 1);
01695
01696 int block_available_right;
01697 int block_available_below;
01698 int prednum = 5;
01699 int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
01700 int totalCheckPts = 0, motionDirection = 0;
01701 int conditionEPZS;
01702 MotionVector tmv;
01703 int pos, mcost;
01704 PixelPos block_a, block_b, block_c, block_d;
01705
01706 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, mb_x, mb_y, blocksize_x);
01707
01708 if (mb_y > 0)
01709 {
01710 if (mb_x < 8)
01711 {
01712 if (mb_y == 8)
01713 {
01714 block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
01715 }
01716 else
01717 {
01718 block_available_right = (mb_x + blocksize_x != 8) || mb_available_right;
01719 }
01720 }
01721 else
01722 {
01723 block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
01724 }
01725 }
01726 else
01727 {
01728 block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
01729 }
01730
01731 block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below);
01732
01733 stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blockshape_x);
01734
01735
01736
01737
01738 invalid_refs = EPZSSpatialPredictors (&block_a, &block_b, &block_c, &block_d,
01739 list, currMB->list_offset, ref, refPic[list], tmp_mv[list], predictor->point);
01740 if (params->EPZSSpatialMem)
01741 EPZSSpatialMemPredictors (cur_list, ref, blocktype - 1, pic_pix_x2,
01742 blockshape_x, blockshape_y, block_y, &prednum, img_width>>2, predictor->point);
01743
01744
01745
01746 if (params->EPZSTemporal)
01747 EPZSTemporalPredictors (list, currMB->list_offset, ref, pic_pix_x2, pic_pix_y2, predictor->point, &prednum,
01748 block_a.available, block_b.available, block_available_right,
01749 block_available_below, blockshape_x, blockshape_y, stopCriterion, min_mcost);
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764 conditionEPZS = ((min_mcost > stopCriterion) && ((ref < 2 && blocktype < 5)
01765 || ((img->structure!=FRAME || currMB->list_offset) && ref < 3))
01766 && (params->EPZSFixed > 1 || (params->EPZSFixed && img->type == P_SLICE)));
01767
01768 if (conditionEPZS)
01769 EPZSWindowPredictors (mv, predictor, &prednum,
01770 (blocktype < 5) && (invalid_refs > 2) && (ref < 1 + (img->structure != FRAME || currMB->list_offset)));
01771
01772
01773
01774
01775
01776
01777
01778 conditionEPZS = (ref == 0 || (ref > 0 && min_mcost > stopCriterion));
01779
01780 if (conditionEPZS && currMB->mb_nr != 0 && params->EPZSBlockType)
01781 EPZSBlockTypePredictors (block_x, block_y, blocktype, ref, list, predictor->point, &prednum);
01782
01783
01784 for (pos = 0; pos < prednum; pos++)
01785 {
01786 tmv = predictor->point[pos].motion;
01787
01788 if (iabs (tmv.mv_x - mv->mv_x) > search_range || iabs (tmv.mv_y - mv->mv_y) > search_range)
01789 continue;
01790
01791
01792 {
01793 if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] == EPZSBlkCount)
01794 continue;
01795 else
01796 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
01797 }
01798
01799 cand.mv_x = (pic_pix_x + tmv.mv_x) << mv_rescale;
01800 cand.mv_y = (pic_pix_y + tmv.mv_y) << mv_rescale;
01801
01802
01803 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
01804
01805 if (mcost >= second_mcost) continue;
01806
01807 mcost += computePred(cur_pic, blocksize_y, blocksize_x, second_mcost - mcost,
01808 cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4);
01809
01810
01811 if (mcost < min_mcost)
01812 {
01813 tmp2 = tmp;
01814 tmp = tmv;
01815 second_mcost = min_mcost;
01816 min_mcost = mcost;
01817 checkMedian = TRUE;
01818 }
01819
01820 else if (mcost < second_mcost)
01821 {
01822 tmp2 = tmv;
01823 second_mcost = mcost;
01824 checkMedian = TRUE;
01825 }
01826 }
01827
01828
01829
01830
01831
01832 if (min_mcost > stopCriterion)
01833 {
01834
01835 if (params->EPZSPattern != 0)
01836 {
01837 if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
01838 {
01839 if ((tmp.mv_x == 0 && tmp.mv_y == 0)
01840 || (iabs (tmp.mv_x - mv->mv_x) < (mv_range) && iabs (tmp.mv_y - mv->mv_y) < (mv_range)))
01841 searchPatternF = sdiamond;
01842 else
01843 searchPatternF = square;
01844 }
01845 else if (blocktype > 4 || (ref > 0 && blocktype != 1))
01846 searchPatternF = square;
01847 else
01848 searchPatternF = searchPattern;
01849 }
01850
01851 totalCheckPts = searchPatternF->searchPoints;
01852
01853
01854 center = tmp;
01855 while (1)
01856 {
01857 do
01858 {
01859 checkPts = totalCheckPts;
01860 do
01861 {
01862 tmv = center;
01863 tmv.mv_x += searchPatternF->point[pointNumber].motion.mv_x;
01864 tmv.mv_y += searchPatternF->point[pointNumber].motion.mv_y;
01865
01866 if ((iabs (tmv.mv_x - mv->mv_x) <= search_range) && (iabs (tmv.mv_y - mv->mv_y) <= search_range))
01867 {
01868 if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] != EPZSBlkCount)
01869 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
01870 else
01871 {
01872 pointNumber ++;
01873 if (pointNumber >= searchPatternF->searchPoints)
01874 pointNumber -= searchPatternF->searchPoints;
01875 checkPts --;
01876 continue;
01877 }
01878 cand.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
01879 cand.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
01880
01881 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred.mv_x, pred.mv_y);
01882
01883 if (mcost < min_mcost)
01884 {
01885
01886 mcost += computePred(cur_pic, blocksize_y, blocksize_x, min_mcost - mcost,
01887 cand.mv_x + IMG_PAD_SIZE_TIMES4, cand.mv_y + IMG_PAD_SIZE_TIMES4);
01888
01889 if (mcost < min_mcost)
01890 {
01891 tmp = tmv;
01892 min_mcost = mcost;
01893 motionDirection = pointNumber;
01894 }
01895 }
01896 }
01897 pointNumber ++;
01898 if (pointNumber >= searchPatternF->searchPoints)
01899 pointNumber -= searchPatternF->searchPoints;
01900 checkPts --;
01901 }
01902 while (checkPts > 0);
01903
01904 if (nextLast || ((tmp.mv_x == center.mv_x) && (tmp.mv_y == center.mv_y)))
01905 {
01906 patternStop = searchPatternF->stopSearch;
01907 searchPatternF = searchPatternF->nextpattern;
01908 totalCheckPts = searchPatternF->searchPoints;
01909 nextLast = searchPatternF->nextLast;
01910 motionDirection = 0;
01911 pointNumber = 0;
01912 }
01913 else
01914 {
01915 totalCheckPts = searchPatternF->point[motionDirection].next_points;
01916 pointNumber = searchPatternF->point[motionDirection].start_nmbr;
01917 center = tmp;
01918 }
01919 }
01920 while (patternStop != 1);
01921
01922 if ((ref>0) && (img->structure == FRAME) && (( 4 * prevSad[pic_pix_x2] < min_mcost) ||
01923 ((3 * prevSad[pic_pix_x2] < min_mcost) && (prevSad[pic_pix_x2] <= stopCriterion))))
01924 {
01925 *mv = tmp;
01926 #if EPZSREF
01927 if (params->EPZSSpatialMem)
01928 #else
01929 if (params->EPZSSpatialMem && ref == 0)
01930 #endif
01931 {
01932 *p_motion = tmp;
01933 }
01934
01935 return min_mcost;
01936 }
01937
01938
01939 conditionEPZS = (checkMedian == TRUE)
01940 && ((img->type == P_SLICE) || (blocktype < 5))
01941 && (min_mcost > stopCriterion) && (params->EPZSDual > 0);
01942
01943 if (!conditionEPZS) break;
01944
01945 pointNumber = 0;
01946 patternStop = 0;
01947 motionDirection = 0;
01948 nextLast = 0;
01949
01950 if ((tmp.mv_x == 0 && tmp.mv_y == 0) || (tmp.mv_x == mv->mv_x && tmp.mv_y == mv->mv_y))
01951 {
01952 if (iabs (tmp.mv_x - mv->mv_x) < (mv_range) && iabs (tmp.mv_y - mv->mv_y) < (mv_range))
01953 searchPatternF = sdiamond;
01954 else
01955 searchPatternF = square;
01956 }
01957 else
01958 searchPatternF = searchPatternD;
01959 totalCheckPts = searchPatternF->searchPoints;
01960
01961
01962 center = tmp2;
01963 checkMedian = FALSE;
01964 }
01965 }
01966 }
01967
01968 if ((ref==0) || (prevSad[pic_pix_x2] > min_mcost))
01969 prevSad[pic_pix_x2] = min_mcost;
01970 #if EPZSREF
01971 if (params->EPZSSpatialMem)
01972 #else
01973 if (params->EPZSSpatialMem && ref == 0)
01974 #endif
01975 {
01976 *p_motion = tmp;
01977
01978
01979 }
01980
01981 *mv = tmp;
01982
01983 return min_mcost;
01984 }
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994 int
01995 EPZSBiPredBlockMotionSearch (Macroblock *currMB,
01996 imgpel * cur_pic,
01997 short ref,
01998 int list,
01999 char ***refPic,
02000 short ****tmp_mv,
02001 int pic_pix_x,
02002 int pic_pix_y,
02003 int blocktype,
02004 MotionVector *pred_mv1,
02005 MotionVector *pred_mv2,
02006 MotionVector *mv1,
02007 MotionVector *mv2,
02008 int search_range,
02009 int min_mcost,
02010 int iteration_no,
02011 int lambda_factor,
02012 int apply_weights
02013 )
02014 {
02015 StorablePicture *ref_picture1 = listX[list + currMB->list_offset][ref];
02016 StorablePicture *ref_picture2 = listX[(list ^ 1) + currMB->list_offset][0];
02017 short blocksize_y = params->blc_size[blocktype][1];
02018 short blocksize_x = params->blc_size[blocktype][0];
02019 short blockshape_x = (blocksize_x >> 2);
02020
02021
02022 short mb_x = pic_pix_x - img->opix_x;
02023 short mb_y = pic_pix_y - img->opix_y;
02024 short pic_pix_x2 = pic_pix_x >> 2;
02025
02026
02027 int stopCriterion = medthres[blocktype];
02028 int mapCenter_x = search_range - mv1->mv_x;
02029 int mapCenter_y = search_range - mv1->mv_y;
02030 int second_mcost = INT_MAX;
02031 int *prevSad = EPZSBiDistortion[list + currMB->list_offset][blocktype - 1];
02032 int mv_range = (2<<(2-mv_rescale));
02033 short invalid_refs = 0;
02034 byte checkMedian = FALSE;
02035 EPZSStructure *searchPatternF = searchPattern;
02036
02037 static MotionVector center1, center2, tmp, tmp2, cand1, cand2, pred1, pred2;
02038 pred1.mv_x = (pic_pix_x << 2) + pred_mv1->mv_x;
02039 pred1.mv_y = (pic_pix_y << 2) + pred_mv1->mv_y;
02040 pred2.mv_x = (pic_pix_x << 2) + pred_mv2->mv_x;
02041 pred2.mv_y = (pic_pix_y << 2) + pred_mv2->mv_y;
02042 center1.mv_x = (pic_pix_x << (params->EPZSGrid))+ mv1->mv_x;
02043 center1.mv_y = (pic_pix_y << (params->EPZSGrid))+ mv1->mv_y;
02044 center2.mv_x = (pic_pix_x << (params->EPZSGrid))+ mv2->mv_x;
02045 center2.mv_y = (pic_pix_y << (params->EPZSGrid))+ mv2->mv_y;
02046 cand1.mv_x = center1.mv_x << mv_rescale;
02047 cand1.mv_y = center1.mv_y << mv_rescale;
02048 cand2.mv_x = center2.mv_x << mv_rescale;
02049 cand2.mv_y = center2.mv_y << mv_rescale;
02050
02051 tmp = *mv1;
02052 tmp2.mv_x = 0;
02053 tmp2.mv_y = 0;
02054 EPZSBlkCount ++;
02055 if (EPZSBlkCount == 0)
02056 EPZSBlkCount ++;
02057
02058 ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
02059 ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
02060
02061 img_width = ref_picture1->size_x;
02062 img_height = ref_picture1->size_y;
02063 width_pad = ref_picture1->size_x_pad;
02064 height_pad = ref_picture1->size_y_pad;
02065
02066 if (apply_weights)
02067 {
02068 computeBiPred = computeBiPred2[F_PEL];
02069 }
02070 else
02071 {
02072 computeBiPred = computeBiPred1[F_PEL];
02073 }
02074
02075 if ( ChromaMEEnable )
02076 {
02077 ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
02078 ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
02079 ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
02080 ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
02081 width_pad_cr = ref_picture1->size_x_cr_pad;
02082 height_pad_cr = ref_picture1->size_y_cr_pad;
02083 }
02084
02085 pic_pix_x = (pic_pix_x << (params->EPZSGrid));
02086 pic_pix_y = (pic_pix_y << (params->EPZSGrid));
02087
02088
02089
02090
02091
02092 EPZSMap[search_range][search_range] = EPZSBlkCount;
02093
02094
02095 min_mcost = MV_COST_SMP (lambda_factor, cand1.mv_x, cand1.mv_y, pred1.mv_x, pred1.mv_y);
02096 min_mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);
02097
02098
02099 min_mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, INT_MAX,
02100 cand1.mv_x + IMG_PAD_SIZE_TIMES4,
02101 cand1.mv_y + IMG_PAD_SIZE_TIMES4,
02102 cand2.mv_x + IMG_PAD_SIZE_TIMES4,
02103 cand2.mv_y + IMG_PAD_SIZE_TIMES4);
02104
02105
02106 if (min_mcost > stopCriterion)
02107 {
02108 int mb_available_right = (img->mb_x < (img_width >> 4) - 1);
02109 int mb_available_below = (img->mb_y < (img_height >> 4) - 1);
02110
02111 int block_available_right;
02112 int block_available_below;
02113 int prednum = 5;
02114 int patternStop = 0, pointNumber = 0, checkPts, nextLast = 0;
02115 int totalCheckPts = 0, motionDirection = 0;
02116 int conditionEPZS;
02117 MotionVector tmv;
02118 int pos, mcost;
02119 PixelPos block_a, block_b, block_c, block_d;
02120
02121 get_neighbors(currMB, &block_a, &block_b, &block_c, &block_d, mb_x, mb_y, blocksize_x);
02122
02123 if (mb_y > 0)
02124 {
02125 if (mb_x < 8)
02126 {
02127 if (mb_y == 8)
02128 {
02129 block_available_right = (blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
02130 }
02131 else
02132 {
02133 block_available_right = (mb_x + blocksize_x != 8) || mb_available_right;
02134 }
02135 }
02136 else
02137 {
02138 block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
02139 }
02140 }
02141 else
02142 {
02143 block_available_right = (mb_x + blocksize_x != MB_BLOCK_SIZE) || mb_available_right;
02144 }
02145
02146 block_available_below = (mb_y + blocksize_y != MB_BLOCK_SIZE) || (mb_available_below);
02147
02148 stopCriterion = EPZSDetermineStopCriterion(prevSad, &block_a, &block_b, &block_c, pic_pix_x2, blocktype, blockshape_x);
02149
02150
02151
02152
02153
02154
02155 invalid_refs = EPZSSpatialPredictors (&block_a, &block_b, &block_c, &block_d,
02156 list, currMB->list_offset, ref, refPic[list], tmp_mv[list], predictor->point);
02157
02158
02159 for (pos = 0; pos < prednum; pos++)
02160 {
02161 tmv = predictor->point[pos].motion;
02162
02163 if (iabs (tmv.mv_x - mv1->mv_x) > search_range || iabs (tmv.mv_y - mv1->mv_y) > search_range)
02164 continue;
02165
02166
02167 {
02168 if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] == EPZSBlkCount)
02169 continue;
02170 else
02171 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
02172 }
02173
02174 cand1.mv_x = (pic_pix_x + tmv.mv_x) << mv_rescale;
02175 cand1.mv_y = (pic_pix_y + tmv.mv_y) << mv_rescale;
02176
02177
02178 mcost = MV_COST_SMP (lambda_factor, cand1.mv_x, cand1.mv_y, pred1.mv_x, pred1.mv_y);
02179 mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);
02180
02181 if (mcost >= second_mcost) continue;
02182
02183 mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, second_mcost - mcost,
02184 cand1.mv_x + IMG_PAD_SIZE_TIMES4 , cand1.mv_y + IMG_PAD_SIZE_TIMES4,
02185 cand2.mv_x + IMG_PAD_SIZE_TIMES4, cand2.mv_y + IMG_PAD_SIZE_TIMES4);
02186
02187
02188 if (mcost < min_mcost)
02189 {
02190 tmp2 = tmp;
02191 tmp = tmv;
02192 second_mcost = min_mcost;
02193 min_mcost = mcost;
02194 checkMedian = TRUE;
02195 }
02196
02197 else if (mcost < second_mcost)
02198 {
02199 tmp2 = tmv;
02200 second_mcost = mcost;
02201 checkMedian = TRUE;
02202 }
02203 }
02204
02205
02206
02207
02208
02209 if (min_mcost > stopCriterion)
02210 {
02211
02212 if (params->EPZSPattern != 0)
02213 {
02214 if ((min_mcost < stopCriterion + ((3 * medthres[blocktype]) >> 1)))
02215 {
02216 if ((tmp.mv_x == 0 && tmp.mv_y == 0)
02217 || (iabs (tmp.mv_x - mv1->mv_x) < (mv_range) && iabs (tmp.mv_y - mv1->mv_y) < (mv_range)))
02218 searchPatternF = sdiamond;
02219 else
02220 searchPatternF = square;
02221 }
02222 else if (blocktype > 5 || (ref > 0 && blocktype != 1))
02223 searchPatternF = square;
02224 else
02225 searchPatternF = searchPattern;
02226 }
02227
02228 totalCheckPts = searchPatternF->searchPoints;
02229
02230
02231 center1 = tmp;
02232 while (1)
02233 {
02234 do
02235 {
02236 checkPts = totalCheckPts;
02237 do
02238 {
02239 tmv = center1;
02240 tmv.mv_x += searchPatternF->point[pointNumber].motion.mv_x;
02241 tmv.mv_y += searchPatternF->point[pointNumber].motion.mv_y;
02242
02243 if ((iabs (tmv.mv_x - mv1->mv_x) <= search_range) && (iabs (tmv.mv_y - mv1->mv_y) <= search_range))
02244 {
02245 if (EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] != EPZSBlkCount)
02246 EPZSMap[mapCenter_y + tmv.mv_y][mapCenter_x + tmv.mv_x] = EPZSBlkCount;
02247 else
02248 {
02249 pointNumber ++;
02250 if (pointNumber >= searchPatternF->searchPoints)
02251 pointNumber -= searchPatternF->searchPoints;
02252 checkPts --;
02253 continue;
02254 }
02255
02256 cand1.mv_x = (pic_pix_x + tmv.mv_x)<<mv_rescale;
02257 cand1.mv_y = (pic_pix_y + tmv.mv_y)<<mv_rescale;
02258
02259 mcost = MV_COST_SMP (lambda_factor, cand1.mv_x, cand1.mv_y, pred1.mv_x, pred1.mv_y);
02260 mcost += MV_COST_SMP (lambda_factor, cand2.mv_x, cand2.mv_y, pred2.mv_x, pred2.mv_y);
02261
02262 if (mcost < min_mcost)
02263 {
02264 mcost += computeBiPred(cur_pic, blocksize_y, blocksize_x, min_mcost - mcost,
02265 cand1.mv_x + IMG_PAD_SIZE_TIMES4, cand1.mv_y + IMG_PAD_SIZE_TIMES4,
02266 cand2.mv_x + IMG_PAD_SIZE_TIMES4, cand2.mv_y + IMG_PAD_SIZE_TIMES4);
02267
02268 if (mcost < min_mcost)
02269 {
02270 tmp = tmv;
02271 min_mcost = mcost;
02272 motionDirection = pointNumber;
02273 }
02274 }
02275 }
02276 pointNumber ++;
02277 if (pointNumber >= searchPatternF->searchPoints)
02278 pointNumber -= searchPatternF->searchPoints;
02279 checkPts --;
02280 }
02281 while (checkPts > 0);
02282
02283 if (nextLast || ((tmp.mv_x == center1.mv_x) && (tmp.mv_y == center1.mv_y)))
02284 {
02285 patternStop = searchPatternF->stopSearch;
02286 searchPatternF = searchPatternF->nextpattern;
02287 totalCheckPts = searchPatternF->searchPoints;
02288 nextLast = searchPatternF->nextLast;
02289 motionDirection = 0;
02290 pointNumber = 0;
02291 }
02292 else
02293 {
02294 totalCheckPts = searchPatternF->point[motionDirection].next_points;
02295 pointNumber = searchPatternF->point[motionDirection].start_nmbr;
02296 center1 = tmp;
02297 }
02298 }
02299 while (patternStop != 1);
02300
02301
02302 conditionEPZS = (checkMedian == TRUE)
02303 && (blocktype < 5)
02304 && (min_mcost > stopCriterion) && (params->EPZSDual > 0);
02305
02306 if (!conditionEPZS) break;
02307
02308 pointNumber = 0;
02309 patternStop = 0;
02310 motionDirection = 0;
02311 nextLast = 0;
02312
02313 if ((tmp.mv_x == 0 && tmp.mv_y == 0) || (tmp.mv_x == mv1->mv_x && tmp.mv_y == mv1->mv_y))
02314 {
02315 if (iabs (tmp.mv_x - mv1->mv_x) < (mv_range) && iabs (tmp.mv_y - mv1->mv_y) < (mv_range))
02316 searchPatternF = sdiamond;
02317 else
02318 searchPatternF = square;
02319 }
02320 else
02321 searchPatternF = searchPatternD;
02322 totalCheckPts = searchPatternF->searchPoints;
02323
02324
02325 center1 = tmp2;
02326 checkMedian = FALSE;
02327 }
02328 }
02329 }
02330
02331 if (iteration_no == 0)
02332 {
02333 prevSad[pic_pix_x2] = min_mcost;
02334 }
02335
02336 *mv1 = tmp;
02337
02338 return min_mcost;
02339 }
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 void EPZSOutputStats (InputParameters *params, FILE * stat, short stats_file)
02351 {
02352 if (stats_file == 1)
02353 {
02354 fprintf (stat, " EPZS Pattern : %s\n",c_EPZSPattern[params->EPZSPattern]);
02355 fprintf (stat, " EPZS Dual Pattern : %s\n",c_EPZSDualPattern[params->EPZSDual]);
02356 fprintf (stat, " EPZS Fixed Predictors : %s\n",c_EPZSFixed[params->EPZSFixed]);
02357 fprintf (stat, " EPZS Temporal Predictors : %s\n",c_EPZSOther[params->EPZSTemporal]);
02358 fprintf (stat, " EPZS Spatial Predictors : %s\n",c_EPZSOther[params->EPZSSpatialMem]);
02359 fprintf (stat, " EPZS Thresholds (16x16) : (%d %d %d)\n",medthres[1], minthres[1], maxthres[1]);
02360 fprintf (stat, " EPZS Subpel ME : %s\n",c_EPZSOther[params->EPZSSubPelME]);
02361 fprintf (stat, " EPZS Subpel ME BiPred : %s\n",c_EPZSOther[params->EPZSSubPelMEBiPred]);
02362 }
02363 else
02364 {
02365 fprintf (stat, " EPZS Pattern : %s\n",c_EPZSPattern[params->EPZSPattern]);
02366 fprintf (stat, " EPZS Dual Pattern : %s\n",c_EPZSDualPattern[params->EPZSDual]);
02367 fprintf (stat, " EPZS Fixed Predictors : %s\n",c_EPZSFixed[params->EPZSFixed]);
02368 fprintf (stat, " EPZS Temporal Predictors : %s\n",c_EPZSOther[params->EPZSTemporal]);
02369 fprintf (stat, " EPZS Spatial Predictors : %s\n",c_EPZSOther[params->EPZSSpatialMem]);
02370 fprintf (stat, " EPZS Thresholds (16x16) : (%d %d %d)\n",medthres[1], minthres[1], maxthres[1]);
02371 fprintf (stat, " EPZS Subpel ME : %s\n",c_EPZSOther[params->EPZSSubPelME]);
02372 fprintf (stat, " EPZS Subpel ME BiPred : %s\n",c_EPZSOther[params->EPZSSubPelMEBiPred]);
02373 }
02374 }
02375
02376
02377
02378
02379
02380
02381
02382
02383 int
02384 EPZSSubPelBlockMotionSearch (imgpel* orig_pic,
02385 short ref,
02386 int list,
02387 int list_offset,
02388 int pic_pix_x,
02389 int pic_pix_y,
02390 int blocktype,
02391 MotionVector *pred,
02392 MotionVector *mv,
02393 int search_pos2,
02394 int search_pos4,
02395 int min_mcost,
02396 int* lambda,
02397 int apply_weights
02398 )
02399 {
02400
02401 int pos, best_pos = 0, second_pos = 0, mcost;
02402 int second_mcost = INT_MAX;
02403
02404 MotionVector cand;
02405
02406 int blocksize_x = params->blc_size[blocktype][0];
02407 int blocksize_y = params->blc_size[blocktype][1];
02408 int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
02409 int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
02410
02411 int max_pos2 = ( (!start_me_refinement_hp || !start_me_refinement_qp) ? imax(1,search_pos2) : search_pos2);
02412
02413 StorablePicture *ref_picture = listX[list+list_offset][ref];
02414
02415 int start_pos = 5, end_pos = max_pos2;
02416 int lambda_factor = lambda[H_PEL];
02417 computePred = computeUniPred[H_PEL + 3 * apply_weights];
02418
02419 ref_pic_sub.luma = ref_picture->p_curr_img_sub;
02420 width_pad = ref_picture->size_x_pad;
02421 height_pad = ref_picture->size_y_pad;
02422
02423 if ( ChromaMEEnable )
02424 {
02425 ref_pic_sub.crcb[0] = ref_picture->imgUV_sub[0];
02426 ref_pic_sub.crcb[1] = ref_picture->imgUV_sub[1];
02427 width_pad_cr = ref_picture->size_x_cr_pad;
02428 height_pad_cr = ref_picture->size_y_cr_pad;
02429 }
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439 for (best_pos = 0, pos = start_me_refinement_hp; pos < 5; pos++)
02440 {
02441 cand.mv_x = mv->mv_x + search_point_hp[pos][0];
02442 cand.mv_y = mv->mv_y + search_point_hp[pos][1];
02443
02444
02445 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred->mv_x, pred->mv_y);
02446 mcost += computePred( orig_pic, blocksize_y, blocksize_x,
02447 INT_MAX, cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y);
02448
02449 if (mcost < min_mcost)
02450 {
02451 second_mcost = min_mcost;
02452 second_pos = best_pos;
02453 min_mcost = mcost;
02454 best_pos = pos;
02455 }
02456 else if (mcost < second_mcost)
02457 {
02458 second_mcost = mcost;
02459 second_pos = pos;
02460 }
02461 }
02462
02463 if (best_pos ==0 && (pred->mv_x == mv->mv_x) && (pred->mv_y == mv->mv_y) && min_mcost < subthres[blocktype])
02464 return min_mcost;
02465
02466 if (best_pos != 0 && second_pos != 0)
02467 {
02468 switch (best_pos ^ second_pos)
02469 {
02470 case 1:
02471 start_pos = 6;
02472 end_pos = 7;
02473 break;
02474 case 3:
02475 start_pos = 5;
02476 end_pos = 6;
02477 break;
02478 case 5:
02479 start_pos = 8;
02480 end_pos = 9;
02481 break;
02482 case 7:
02483 start_pos = 7;
02484 end_pos = 8;
02485 break;
02486 default:
02487 break;
02488 }
02489 }
02490 else
02491 {
02492 switch (best_pos + second_pos)
02493 {
02494 case 0:
02495 start_pos = 5;
02496 end_pos = 5;
02497 break;
02498 case 1:
02499 start_pos = 8;
02500 end_pos = 10;
02501 break;
02502 case 2:
02503 start_pos = 5;
02504 end_pos = 7;
02505 break;
02506 case 5:
02507 start_pos = 6;
02508 end_pos = 8;
02509 break;
02510 case 7:
02511 start_pos = 7;
02512 end_pos = 9;
02513 break;
02514 default:
02515 break;
02516 }
02517 }
02518
02519 if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
02520 {
02521 for (pos = start_pos; pos < end_pos; pos++)
02522 {
02523 cand.mv_x = mv->mv_x + search_point_hp[pos][0];
02524 cand.mv_y = mv->mv_y + search_point_hp[pos][1];
02525
02526
02527 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred->mv_x, pred->mv_y);
02528
02529 if (mcost >= min_mcost) continue;
02530
02531 mcost += computePred( orig_pic, blocksize_y, blocksize_x,
02532 min_mcost - mcost, cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y);
02533
02534 if (mcost < min_mcost)
02535 {
02536 min_mcost = mcost;
02537 best_pos = pos;
02538 }
02539 }
02540 }
02541
02542 if (best_pos)
02543 {
02544 mv->mv_x += search_point_hp[best_pos][0];
02545 mv->mv_y += search_point_hp[best_pos][1];
02546 }
02547
02548 if ( !start_me_refinement_qp )
02549 min_mcost = INT_MAX;
02550
02551
02552
02553
02554
02555
02556
02557 computePred = computeUniPred[Q_PEL + 3 * apply_weights];
02558 lambda_factor = lambda[Q_PEL];
02559 second_pos = 0;
02560 second_mcost = INT_MAX;
02561
02562 for (best_pos = 0, pos = start_me_refinement_qp; pos < 5; pos++)
02563 {
02564 cand.mv_x = mv->mv_x + search_point_qp[pos][0];
02565 cand.mv_y = mv->mv_y + search_point_qp[pos][1];
02566
02567
02568 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred->mv_x, pred->mv_y);
02569 mcost += computePred( orig_pic, blocksize_y, blocksize_x,
02570 INT_MAX, cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y);
02571
02572 if (mcost < min_mcost)
02573 {
02574 second_mcost = min_mcost;
02575 second_pos = best_pos;
02576 min_mcost = mcost;
02577 best_pos = pos;
02578 }
02579 else if (mcost < second_mcost)
02580 {
02581 second_mcost = mcost;
02582 second_pos = pos;
02583 }
02584 }
02585
02586 if (best_pos ==0 && (pred->mv_x == mv->mv_x) && (pred->mv_y == mv->mv_y) && min_mcost < subthres[blocktype])
02587 {
02588 return min_mcost;
02589 }
02590
02591 start_pos = 5;
02592 end_pos = search_pos4;
02593
02594 if (best_pos != 0 && second_pos != 0)
02595 {
02596 switch (best_pos ^ second_pos)
02597 {
02598 case 1:
02599 start_pos = 6;
02600 end_pos = 7;
02601 break;
02602 case 3:
02603 start_pos = 5;
02604 end_pos = 6;
02605 break;
02606 case 5:
02607 start_pos = 8;
02608 end_pos = 9;
02609 break;
02610 case 7:
02611 start_pos = 7;
02612 end_pos = 8;
02613 break;
02614 default:
02615 break;
02616 }
02617 }
02618 else
02619 {
02620 switch (best_pos + second_pos)
02621 {
02622
02623
02624
02625
02626 case 1:
02627 start_pos = 8;
02628 end_pos = 10;
02629 break;
02630 case 2:
02631 start_pos = 5;
02632 end_pos = 7;
02633 break;
02634 case 5:
02635 start_pos = 6;
02636 end_pos = 8;
02637 break;
02638 case 7:
02639 start_pos = 7;
02640 end_pos = 9;
02641 break;
02642 default:
02643 break;
02644 }
02645 }
02646
02647 if (best_pos !=0 || (iabs(pred->mv_x - mv->mv_x) + iabs(pred->mv_y - mv->mv_y)))
02648 {
02649 for (pos = start_pos; pos < end_pos; pos++)
02650 {
02651 cand.mv_x = mv->mv_x + search_point_qp[pos][0];
02652 cand.mv_y = mv->mv_y + search_point_qp[pos][1];
02653
02654
02655 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred->mv_x, pred->mv_y);
02656
02657 if (mcost >= min_mcost) continue;
02658 mcost += computePred( orig_pic, blocksize_y, blocksize_x,
02659 min_mcost - mcost, cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y);
02660
02661 if (mcost < min_mcost)
02662 {
02663 min_mcost = mcost;
02664 best_pos = pos;
02665 }
02666 }
02667 }
02668 if (best_pos)
02669 {
02670 mv->mv_x += search_point_qp [best_pos][0];
02671 mv->mv_y += search_point_qp [best_pos][1];
02672 }
02673
02674
02675 return min_mcost;
02676 }
02677
02678
02679
02680
02681
02682
02683
02684 int
02685 EPZSSubPelBlockSearchBiPred (imgpel* orig_pic,
02686 short ref,
02687 int list,
02688 int pic_pix_x,
02689 int pic_pix_y,
02690 int blocktype,
02691 MotionVector *pred_mv1,
02692 MotionVector *pred_mv2,
02693 MotionVector *mv1,
02694 MotionVector *mv2,
02695 int search_pos2,
02696 int search_pos4,
02697 int min_mcost,
02698 int* lambda,
02699 int apply_weights
02700 )
02701 {
02702 int list_offset = img->mb_data[img->current_mb_nr].list_offset;
02703
02704 int pos, best_pos = 0, second_pos = 0, mcost;
02705 int second_mcost = INT_MAX;
02706
02707 MotionVector cand, sand;
02708
02709 int blocksize_x = params->blc_size[blocktype][0];
02710 int blocksize_y = params->blc_size[blocktype][1];
02711 int pic4_pix_x = ((pic_pix_x + IMG_PAD_SIZE)<< 2);
02712 int pic4_pix_y = ((pic_pix_y + IMG_PAD_SIZE)<< 2);
02713
02714 int start_hp = (min_mcost == INT_MAX) ? 0 : start_me_refinement_hp;
02715 int max_pos2 = ( (!start_me_refinement_hp || !start_me_refinement_qp) ? imax(1,search_pos2) : search_pos2);
02716
02717 StorablePicture *ref_picture1 = listX[list + list_offset][ref];
02718 StorablePicture *ref_picture2 = listX[(list ^ 1) + list_offset][0];
02719
02720 int start_pos = 5, end_pos = max_pos2;
02721 int lambda_factor = lambda[H_PEL];
02722
02723 sand.mv_x = mv2->mv_x + pic4_pix_x;
02724 sand.mv_y = mv2->mv_y + pic4_pix_y;
02725
02726 ref_pic1_sub.luma = ref_picture1->p_curr_img_sub;
02727 ref_pic2_sub.luma = ref_picture2->p_curr_img_sub;
02728 width_pad = ref_picture1->size_x_pad;
02729 height_pad = ref_picture1->size_y_pad;
02730
02731 if (apply_weights)
02732 {
02733 computeBiPred = computeBiPred2[H_PEL];
02734 }
02735 else
02736 {
02737 computeBiPred = computeBiPred1[H_PEL];
02738 }
02739
02740
02741 if ( ChromaMEEnable )
02742 {
02743 ref_pic1_sub.crcb[0] = ref_picture1->imgUV_sub[0];
02744 ref_pic1_sub.crcb[1] = ref_picture1->imgUV_sub[1];
02745 ref_pic2_sub.crcb[0] = ref_picture2->imgUV_sub[0];
02746 ref_pic2_sub.crcb[1] = ref_picture2->imgUV_sub[1];
02747 width_pad_cr = ref_picture1->size_x_cr_pad;
02748 height_pad_cr = ref_picture1->size_y_cr_pad;
02749 }
02750
02751
02752
02753
02754
02755
02756
02757
02758 for (best_pos = 0, pos = start_hp; pos < 5; pos++)
02759 {
02760 cand.mv_x = mv1->mv_x + search_point_hp[pos][0];
02761 cand.mv_y = mv1->mv_y + search_point_hp[pos][1];
02762
02763
02764 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred_mv1->mv_x, pred_mv1->mv_y);
02765 mcost += MV_COST_SMP (lambda_factor, mv2->mv_x, mv2->mv_y, pred_mv2->mv_x, pred_mv2->mv_y);
02766 mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, INT_MAX,
02767 cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y, sand.mv_x, sand.mv_y);
02768
02769 if (mcost < min_mcost)
02770 {
02771 second_mcost = min_mcost;
02772 second_pos = best_pos;
02773 min_mcost = mcost;
02774 best_pos = pos;
02775 }
02776 else if (mcost < second_mcost)
02777 {
02778 second_mcost = mcost;
02779 second_pos = pos;
02780 }
02781 }
02782
02783
02784
02785
02786 if (best_pos != 0 && second_pos != 0)
02787 {
02788 switch (best_pos ^ second_pos)
02789 {
02790 case 1:
02791 start_pos = 6;
02792 end_pos = 7;
02793 break;
02794 case 3:
02795 start_pos = 5;
02796 end_pos = 6;
02797 break;
02798 case 5:
02799 start_pos = 8;
02800 end_pos = 9;
02801 break;
02802 case 7:
02803 start_pos = 7;
02804 end_pos = 8;
02805 break;
02806 default:
02807 break;
02808 }
02809 }
02810 else
02811 {
02812 switch (best_pos + second_pos)
02813 {
02814 case 0:
02815 start_pos = 5;
02816 end_pos = 5;
02817 break;
02818 case 1:
02819 start_pos = 8;
02820 end_pos = 10;
02821 break;
02822 case 2:
02823 start_pos = 5;
02824 end_pos = 7;
02825 break;
02826 case 5:
02827 start_pos = 6;
02828 end_pos = 8;
02829 break;
02830 case 7:
02831 start_pos = 7;
02832 end_pos = 9;
02833 break;
02834 default:
02835 break;
02836 }
02837 }
02838
02839 if (best_pos !=0 || (iabs(pred_mv1->mv_x - mv1->mv_x) + iabs(pred_mv1->mv_y - mv1->mv_y)))
02840 {
02841 for (pos = start_pos; pos < end_pos; pos++)
02842 {
02843 cand.mv_x = mv1->mv_x + search_point_hp[pos][0];
02844 cand.mv_y = mv1->mv_y + search_point_hp[pos][1];
02845
02846
02847 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred_mv1->mv_x, pred_mv1->mv_y);
02848 mcost += MV_COST_SMP (lambda_factor, mv2->mv_x, mv2->mv_y, pred_mv2->mv_x, pred_mv2->mv_y);
02849 if (mcost >= min_mcost) continue;
02850
02851 mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, min_mcost - mcost,
02852 cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y, sand.mv_x, sand.mv_y);
02853
02854 if (mcost < min_mcost)
02855 {
02856 min_mcost = mcost;
02857 best_pos = pos;
02858 }
02859 }
02860 }
02861
02862 if (best_pos)
02863 {
02864 mv1->mv_x += search_point_hp [best_pos][0];
02865 mv1->mv_y += search_point_hp [best_pos][1];
02866 }
02867
02868 if ( !start_me_refinement_qp )
02869 min_mcost = INT_MAX;
02870
02871
02872
02873
02874
02875
02876 computeBiPred = apply_weights? computeBiPred2[Q_PEL] : computeBiPred1[Q_PEL];
02877
02878 lambda_factor = lambda[Q_PEL];
02879 second_pos = 0;
02880 second_mcost = INT_MAX;
02881
02882 for (best_pos = 0, pos = start_me_refinement_qp; pos < 5; pos++)
02883 {
02884 cand.mv_x = mv1->mv_x + search_point_qp[pos][0];
02885 cand.mv_y = mv1->mv_y + search_point_qp[pos][1];
02886
02887
02888 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred_mv1->mv_x, pred_mv1->mv_y);
02889 mcost += MV_COST_SMP (lambda_factor, mv2->mv_x, mv2->mv_y, pred_mv2->mv_x, pred_mv2->mv_y);
02890
02891 mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, INT_MAX,
02892 cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y, sand.mv_x, sand.mv_y);
02893
02894 if (mcost < min_mcost)
02895 {
02896 second_mcost = min_mcost;
02897 second_pos = best_pos;
02898 min_mcost = mcost;
02899 best_pos = pos;
02900 }
02901 else if (mcost < second_mcost)
02902 {
02903 second_mcost = mcost;
02904 second_pos = pos;
02905 }
02906 }
02907
02908 start_pos = 5;
02909 end_pos = search_pos4;
02910
02911 if (best_pos != 0 && second_pos != 0)
02912 {
02913 switch (best_pos ^ second_pos)
02914 {
02915 case 1:
02916 start_pos = 6;
02917 end_pos = 7;
02918 break;
02919 case 3:
02920 start_pos = 5;
02921 end_pos = 6;
02922 break;
02923 case 5:
02924 start_pos = 8;
02925 end_pos = 9;
02926 break;
02927 case 7:
02928 start_pos = 7;
02929 end_pos = 8;
02930 break;
02931 default:
02932 break;
02933 }
02934 }
02935 else
02936 {
02937 switch (best_pos + second_pos)
02938 {
02939
02940
02941
02942
02943 case 1:
02944 start_pos = 8;
02945 end_pos = 10;
02946 break;
02947 case 2:
02948 start_pos = 5;
02949 end_pos = 7;
02950 break;
02951 case 5:
02952 start_pos = 6;
02953 end_pos = 8;
02954 break;
02955 case 7:
02956 start_pos = 7;
02957 end_pos = 9;
02958 break;
02959 default:
02960 break;
02961 }
02962 }
02963
02964 if (best_pos !=0 || (iabs(pred_mv1->mv_x - mv1->mv_x) + iabs(pred_mv1->mv_y - mv1->mv_y)))
02965 {
02966 for (pos = start_pos; pos < end_pos; pos++)
02967 {
02968 cand.mv_x = mv1->mv_x + search_point_qp[pos][0];
02969 cand.mv_y = mv1->mv_y + search_point_qp[pos][1];
02970
02971
02972 mcost = MV_COST_SMP (lambda_factor, cand.mv_x, cand.mv_y, pred_mv1->mv_x, pred_mv1->mv_y);
02973 mcost += MV_COST_SMP (lambda_factor, mv2->mv_x, mv2->mv_y, pred_mv2->mv_x, pred_mv2->mv_y);
02974 if (mcost >= min_mcost) continue;
02975
02976 mcost += computeBiPred(orig_pic, blocksize_y, blocksize_x, min_mcost - mcost,
02977 cand.mv_x + pic4_pix_x, cand.mv_y + pic4_pix_y, sand.mv_x, sand.mv_y);
02978
02979 if (mcost < min_mcost)
02980 {
02981 min_mcost = mcost;
02982 best_pos = pos;
02983 }
02984 }
02985 }
02986 if (best_pos)
02987 {
02988 mv1->mv_x += search_point_qp [best_pos][0];
02989 mv1->mv_y += search_point_qp [best_pos][1];
02990 }
02991
02992
02993 return min_mcost;
02994 }
02995