00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <limits.h>
00017
00018 #include "contributors.h"
00019 #include "global.h"
00020 #include "image.h"
00021 #include "memalloc.h"
00022 #include "mb_access.h"
00023 #include "refbuf.h"
00024 #include "macroblock.h"
00025 #include "me_distortion.h"
00026 #include "me_epzs.h"
00027 #include "me_epzs_common.h"
00028 #include "mv_search.h"
00029
00030 static const short BLOCK_PARENT[8] = { 1, 1, 1, 1, 2, 4, 4, 5 };
00031 static const int MIN_THRES_BASE[8] = { 0, 64, 32, 32, 16, 8, 8, 4 };
00032 static const int MED_THRES_BASE[8] = { 0, 256, 128, 128, 64, 32, 32, 16 };
00033 static const int MAX_THRES_BASE[8] = { 0, 768, 384, 384, 192, 96, 96, 48 };
00034
00035
00036 static const char EPZS_PATTERN[6][20] = { "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST" };
00037 static const char EPZS_DUAL_PATTERN[7][20] =
00038 { "Disabled", "Diamond", "Square", "Extended Diamond", "Large Diamond", "SBP Large Diamond", "PMVFAST" };
00039 static const char EPZS_FIXED_PREDICTORS[3][20] = { "Disabled", "All P", "All P + B" };
00040 static const char EPZS_OTHER_PREDICTORS[2][20] = { "Disabled", "Enabled" };
00041
00042
00043
00044 static const short pattern_data[5][12][4] =
00045 {
00046 {
00047 { 0, 4, 3, 3 }, { 4, 0, 0, 3 }, { 0, -4, 1, 3 }, { -4, 0, 2, 3 }
00048 },
00049 {
00050 { 0, 4, 7, 3 }, { 4, 4, 7, 5 }, { 4, 0, 1, 3 }, { 4, -4, 1, 5 },
00051 { 0, -4, 3, 3 }, { -4, -4, 3, 5 }, { -4, 0, 5, 3 }, { -4, 4, 5, 5 }
00052 },
00053 {
00054 { -4, 4, 10, 5 }, { 0, 8, 10, 8 }, { 0, 4, 10, 7 }, { 4, 4, 1, 5 },
00055 { 8, 0, 1, 8 }, { 4, 0, 1, 7 }, { 4, -4, 4, 5 }, { 0, -8, 4, 8 },
00056 { 0, -4, 4, 7 }, { -4, -4, 7, 5 }, { -8, 0, 7, 8 }, { -4, 0, 7, 7 }
00057
00058 },
00059 {
00060 { 0, 8, 6, 5 }, { 4, 4, 0, 3 }, { 8, 0, 0, 5 }, { 4, -4, 2, 3 },
00061 { 0, -8, 2, 5 }, { -4, -4, 4, 3 }, { -8, 0, 4, 5 }, { -4, 4, 6, 3 }
00062 },
00063 {
00064 { 0, 8, 6, 12 }, { 4, 4, 0, 12 }, { 8, 0, 0, 12 }, { 4, -4, 2, 12 },
00065 { 0, -8, 2, 12 }, { -4, -4, 4, 12 }, { -8, 0, 4, 12 }, { -4, 4, 6, 12 },
00066 { 0, 2, 6, 12 }, { 2, 0, 0, 12 }, { 0, -2, 2, 12 }, { -2, 0, 4, 12 }
00067 }
00068 };
00069
00070
00071
00072
00073
00074
00075
00076
00077 static int
00078 RoundLog2 (int iValue)
00079 {
00080 int iRet = 0;
00081 int iValue_square = iValue * iValue;
00082 while ((1 << (iRet + 1)) <= iValue_square)
00083 ++iRet;
00084
00085 iRet = (iRet + 1) >> 1;
00086 return iRet;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 static EPZSStructure *
00102 allocEPZSpattern (int searchpoints)
00103 {
00104 EPZSStructure *s;
00105 s = calloc (1, sizeof (EPZSStructure));
00106
00107 if (NULL == s)
00108 no_mem_exit ("alloc_EPZSpattern: s");
00109
00110 s->searchPoints = searchpoints;
00111 s->point = (SPoint *) calloc (searchpoints, sizeof (SPoint));
00112
00113 return s;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 static void
00127 freeEPZSpattern (EPZSStructure * p)
00128 {
00129 if (p)
00130 {
00131 free ((SPoint *) p->point);
00132 free (p);
00133 p = NULL;
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 static void
00146 assignEPZSpattern (EPZSStructure * pattern, int type, int stopSearch, int nextLast, EPZSStructure * nextpattern)
00147 {
00148 int i;
00149
00150 for (i = 0; i < pattern->searchPoints; ++i)
00151 {
00152 pattern->point[i].motion.mv_x = pattern_data[type][i][0];
00153 pattern->point[i].motion.mv_y = pattern_data[type][i][1];
00154 pattern->point[i].start_nmbr = pattern_data[type][i][2];
00155 pattern->point[i].next_points = pattern_data[type][i][3];
00156 }
00157 pattern->stopSearch = stopSearch;
00158 pattern->nextLast = nextLast;
00159 pattern->nextpattern = nextpattern;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 int
00169 EPZSInit (ImageParameters * p_Img)
00170 {
00171
00172 int memory_size = 0;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 p_Img->sdiamond = allocEPZSpattern (4);
00185 assignEPZSpattern (p_Img->sdiamond, SDIAMOND, TRUE, TRUE, p_Img->sdiamond);
00186 p_Img->square = allocEPZSpattern (8);
00187 assignEPZSpattern (p_Img->square, SQUARE, TRUE, TRUE, p_Img->square);
00188 p_Img->ediamond = allocEPZSpattern (12);
00189 assignEPZSpattern (p_Img->ediamond, EDIAMOND, TRUE, TRUE, p_Img->ediamond);
00190 p_Img->ldiamond = allocEPZSpattern (8);
00191 assignEPZSpattern (p_Img->ldiamond, LDIAMOND, TRUE, TRUE, p_Img->ldiamond);
00192 p_Img->sbdiamond = allocEPZSpattern (12);
00193 assignEPZSpattern (p_Img->sbdiamond, SBDIAMOND, FALSE, TRUE, p_Img->sdiamond);
00194 p_Img->pmvfast = allocEPZSpattern (8);
00195 assignEPZSpattern (p_Img->pmvfast, LDIAMOND, FALSE, TRUE, p_Img->sdiamond);
00196
00197 return memory_size;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 void
00207 EPZSDelete (ImageParameters * p_Img)
00208 {
00209
00210 freeEPZSpattern (p_Img->pmvfast);
00211 freeEPZSpattern (p_Img->sbdiamond);
00212 freeEPZSpattern (p_Img->ldiamond);
00213 freeEPZSpattern (p_Img->ediamond);
00214 freeEPZSpattern (p_Img->sdiamond);
00215 freeEPZSpattern (p_Img->square);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 static EPZSColocParams *
00235 allocEPZScolocated (int size_x, int size_y, int mb_adaptive_frame_field_flag)
00236 {
00237 EPZSColocParams *s;
00238 s = calloc (1, sizeof (EPZSColocParams));
00239 if (NULL == s)
00240 no_mem_exit ("alloc_EPZScolocated: s");
00241
00242 s->size_x = size_x;
00243 s->size_y = size_y;
00244 get_mem3Dmv (&(s->frame), 2, size_y / BLOCK_SIZE, size_x / BLOCK_SIZE);
00245
00246 if (mb_adaptive_frame_field_flag)
00247 {
00248 get_mem3Dmv (&(s->top), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
00249 get_mem3Dmv (&(s->bot), 2, size_y / (BLOCK_SIZE * 2), size_x / BLOCK_SIZE);
00250 }
00251
00252 s->mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag;
00253
00254 return s;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 static void
00268 freeEPZScolocated (EPZSColocParams * p)
00269 {
00270
00271 if (p)
00272 {
00273 free_mem3Dmv (p->frame);
00274 if (p->mb_adaptive_frame_field_flag)
00275 {
00276 free_mem3Dmv (p->top);
00277 free_mem3Dmv (p->bot);
00278 }
00279
00280 free (p);
00281 p = NULL;
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 static void
00292 EPZSWindowPredictorInit (short search_range, EPZSStructure * predictor, short mode)
00293 {
00294 short pos;
00295 short searchpos, fieldsearchpos;
00296 int prednum = -1;
00297 short i;
00298 short search_range_qpel = 2;
00299 SPoint *point = predictor->point;
00300
00301 if (mode == 0)
00302 {
00303 for (pos = (short) (RoundLog2 (search_range) - 2); pos > -1; pos--)
00304 {
00305 searchpos = ((search_range << search_range_qpel) >> pos);
00306
00307 for (i = 1; i >= -1; i -= 2)
00308 {
00309 point[++prednum].motion.mv_x = i * searchpos;
00310 point[prednum].motion.mv_y = 0;
00311 point[++prednum].motion.mv_x = i * searchpos;
00312 point[prednum].motion.mv_y = i * searchpos;
00313 point[++prednum].motion.mv_x = 0;
00314 point[prednum].motion.mv_y = i * searchpos;
00315 point[++prednum].motion.mv_x = -i * searchpos;
00316 point[prednum].motion.mv_y = i * searchpos;
00317 }
00318 }
00319 }
00320 else
00321 {
00322 for (pos = (short) (RoundLog2 (search_range) - 2); pos > -1; pos--)
00323 {
00324 searchpos = ((search_range << search_range_qpel) >> pos);
00325
00326 fieldsearchpos = ((3 * searchpos + 1) << search_range_qpel) >> 1;
00327 for (i = 1; i >= -1; i -= 2)
00328 {
00329 point[++prednum].motion.mv_x = i * searchpos;
00330 point[prednum].motion.mv_y = 0;
00331 point[++prednum].motion.mv_x = i * searchpos;
00332 point[prednum].motion.mv_y = i * searchpos;
00333 point[++prednum].motion.mv_x = 0;
00334 point[prednum].motion.mv_y = i * searchpos;
00335 point[++prednum].motion.mv_x = -i * searchpos;
00336 point[prednum].motion.mv_y = i * searchpos;
00337 }
00338
00339 for (i = 1; i >= -1; i -= 2)
00340 {
00341 point[++prednum].motion.mv_x = i * fieldsearchpos;
00342 point[prednum].motion.mv_y = -i * searchpos;
00343 point[++prednum].motion.mv_x = i * fieldsearchpos;
00344 point[prednum].motion.mv_y = 0;
00345 point[++prednum].motion.mv_x = i * fieldsearchpos;
00346 point[prednum].motion.mv_y = i * searchpos;
00347 point[++prednum].motion.mv_x = i * searchpos;
00348 point[prednum].motion.mv_y = i * fieldsearchpos;
00349 point[++prednum].motion.mv_x = 0;
00350 point[prednum].motion.mv_y = i * fieldsearchpos;
00351 point[++prednum].motion.mv_x = -i * searchpos;
00352 point[prednum].motion.mv_y = i * fieldsearchpos;
00353 }
00354 }
00355 }
00356
00357 predictor->searchPoints = prednum;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366 int
00367 EPZSStructInit (Slice * currSlice)
00368 {
00369 ImageParameters *p_Img = currSlice->p_Img;
00370 InputParameters *p_Inp = currSlice->p_Inp;
00371 EPZSParameters *p_EPZS = currSlice->p_EPZS;
00372 int max_list_number = p_Img->MbaffFrameFlag ? 6 : 2;
00373 int pel_error_me = 1 << (p_Img->bitdepth_luma - 8);
00374 int pel_error_me_cr = 1 << (p_Img->bitdepth_chroma - 8);
00375 int i, memory_size = 0;
00376 double chroma_weight =
00377 p_Inp->ChromaMEEnable ? pel_error_me_cr * p_Inp->ChromaMEWeight * (double) (p_Img->width_cr * p_Img->height_cr) /
00378 (double) (p_Img->width * p_Img->height) : 0;
00379 int searchlevels = RoundLog2 (p_Inp->search_range) - 1;
00380 int searcharray =
00381 p_Inp->BiPredMotionEstimation ? (2 * imax (p_Inp->search_range, p_Inp->BiPredMESearchRange) +
00382 1) << 2 : (2 * p_Inp->search_range + 1) << 2;
00383 p_EPZS->p_Img = p_Img;
00384 p_EPZS->BlkCount = 1;
00385
00386
00387
00388
00389
00390
00391 for (i = 0; i < 8; ++i)
00392 {
00393 p_EPZS->medthres[i] = p_Inp->EPZSMedThresScale * (MED_THRES_BASE[i] * pel_error_me + (int) (MED_THRES_BASE[i] * chroma_weight + 0.5));
00394 p_EPZS->maxthres[i] = p_Inp->EPZSMaxThresScale * (MAX_THRES_BASE[i] * pel_error_me + (int) (MAX_THRES_BASE[i] * chroma_weight + 0.5));
00395 p_EPZS->minthres[i] = p_Inp->EPZSMinThresScale * (MIN_THRES_BASE[i] * pel_error_me + (int) (MIN_THRES_BASE[i] * chroma_weight + 0.5));
00396 p_EPZS->subthres[i] = p_Inp->EPZSSubPelThresScale * (MED_THRES_BASE[i] * pel_error_me + (int) (MED_THRES_BASE[i] * chroma_weight + 0.5));
00397 }
00398
00399
00400
00401
00402 p_EPZS->window_predictor = allocEPZSpattern (searchlevels * 8);
00403 p_EPZS->window_predictor_ext = allocEPZSpattern (searchlevels * 20);
00404 EPZSWindowPredictorInit ((short) p_Inp->search_range, p_EPZS->window_predictor, 0);
00405 EPZSWindowPredictorInit ((short) p_Inp->search_range, p_EPZS->window_predictor_ext, 1);
00406
00407
00408
00409 p_EPZS->predictor = allocEPZSpattern (searchlevels * 20 + 5 + 5 + 9 * (p_Inp->EPZSTemporal) + 3 * (p_Inp->EPZSSpatialMem));
00410
00411
00412
00413
00414
00415 memory_size += get_mem3Dint (&(p_EPZS->distortion), max_list_number, 7, (p_Img->width + MB_BLOCK_SIZE)/ BLOCK_SIZE);
00416
00417 if (p_Inp->BiPredMotionEstimation)
00418 memory_size += get_mem3Dint (&(p_EPZS->bi_distortion), max_list_number, 7, (p_Img->width + MB_BLOCK_SIZE) / BLOCK_SIZE);
00419 memory_size += get_mem2Dshort ((short ***) &(p_EPZS->EPZSMap), searcharray, searcharray);
00420
00421 if (p_Inp->EPZSSpatialMem)
00422 {
00423 #if EPZSREF
00424 memory_size += get_mem5Dmv (&(p_EPZS->p_motion), 6, p_Img->max_num_references, 7, 4, p_Img->width / BLOCK_SIZE);
00425 #else
00426 memory_size += get_mem4Dmv (&(p_EPZS->p_motion), 6, 7, 4, p_Img->width / BLOCK_SIZE);
00427 #endif
00428 }
00429
00430 if (p_Inp->EPZSTemporal)
00431 p_EPZS->p_colocated = allocEPZScolocated (p_Img->width, p_Img->height, p_Img->active_sps->mb_adaptive_frame_field_flag);
00432
00433 switch (p_Inp->EPZSPattern)
00434 {
00435 case 5:
00436 p_EPZS->searchPattern = p_Img->pmvfast;
00437 break;
00438 case 4:
00439 p_EPZS->searchPattern = p_Img->sbdiamond;
00440 break;
00441 case 3:
00442 p_EPZS->searchPattern = p_Img->ldiamond;
00443 break;
00444 case 2:
00445 p_EPZS->searchPattern = p_Img->ediamond;
00446 break;
00447 case 1:
00448 p_EPZS->searchPattern = p_Img->square;
00449 break;
00450 case 0:
00451 default:
00452 p_EPZS->searchPattern = p_Img->sdiamond;
00453 break;
00454 }
00455
00456 switch (p_Inp->EPZSDual)
00457 {
00458 case 6:
00459 p_EPZS->searchPatternD = p_Img->pmvfast;
00460 break;
00461 case 5:
00462 p_EPZS->searchPatternD = p_Img->sbdiamond;
00463 break;
00464 case 4:
00465 p_EPZS->searchPatternD = p_Img->ldiamond;
00466 break;
00467 case 3:
00468 p_EPZS->searchPatternD = p_Img->ediamond;
00469 break;
00470 case 2:
00471 p_EPZS->searchPatternD = p_Img->square;
00472 break;
00473 case 1:
00474 default:
00475 p_EPZS->searchPatternD = p_Img->sdiamond;
00476 break;
00477 }
00478
00479 return memory_size;
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 void
00489 EPZSStructDelete (Slice * currSlice)
00490 {
00491 InputParameters *p_Inp = currSlice->p_Inp;
00492 EPZSParameters *p_EPZS = currSlice->p_EPZS;
00493 if (p_Inp->EPZSTemporal)
00494 freeEPZScolocated (p_EPZS->p_colocated);
00495
00496
00497 free_mem2Dshort ((short **) p_EPZS->EPZSMap);
00498 free_mem3Dint (p_EPZS->distortion);
00499
00500 if (p_Inp->BiPredMotionEstimation)
00501 free_mem3Dint (p_EPZS->bi_distortion);
00502
00503 freeEPZSpattern (p_EPZS->window_predictor_ext);
00504 freeEPZSpattern (p_EPZS->window_predictor);
00505 freeEPZSpattern (p_EPZS->predictor);
00506
00507 if (p_Inp->EPZSSpatialMem)
00508 {
00509 #if EPZSREF
00510 free_mem5Dmv (p_EPZS->p_motion);
00511 #else
00512 free_mem4Dmv (p_EPZS->p_motion);
00513 #endif
00514 }
00515
00516 free (currSlice->p_EPZS);
00517 currSlice->p_EPZS = NULL;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526
00527 void
00528 EPZSSliceInit (Slice * currSlice)
00529 {
00530 ImageParameters *p_Img = currSlice->p_Img;
00531 InputParameters *p_Inp = currSlice->p_Inp;
00532 StorablePicture *p_Pic = p_Img->enc_picture;
00533 EPZSColocParams *p = currSlice->p_EPZS->p_colocated;
00534 StorablePicture ***listX = p_Img->listX;
00535 StorablePicture *fs, *fs_top, *fs_bottom;
00536 StorablePicture *fs1, *fs_top1, *fs_bottom1, *fsx;
00537 EPZSParameters *p_EPZS = currSlice->p_EPZS;
00538 PicMotionParams *p_motion = NULL;
00539 int i, j, k, jj, jdiv, loffset;
00540 int prescale, iTRb, iTRp;
00541 int list = (currSlice->slice_type == B_SLICE) ? LIST_1 : LIST_0;
00542 int tempmv_scale[2];
00543 int epzs_scale[2][6][MAX_LIST_SIZE];
00544 int iref;
00545 int invmv_precision = 8;
00546
00547
00548
00549 for (j = LIST_0; j < 2 + (currSlice->MbaffFrameFlag << 2); ++j)
00550 {
00551 for (k = 0; k < p_Img->listXsize[j]; ++k)
00552 {
00553 for (i = 0; i < p_Img->listXsize[j]; ++i)
00554 {
00555 if ((j >> 1) == 0)
00556 {
00557 iTRb = iClip3 (-128, 127, p_Pic->poc - listX[j][i]->poc);
00558 iTRp = iClip3 (-128, 127, p_Pic->poc - listX[j][k]->poc);
00559 }
00560 else if ((j >> 1) == 1)
00561 {
00562 iTRb = iClip3 (-128, 127, p_Pic->top_poc - listX[j][i]->poc);
00563 iTRp = iClip3 (-128, 127, p_Pic->top_poc - listX[j][k]->poc);
00564 }
00565 else
00566 {
00567 iTRb = iClip3 (-128, 127, p_Pic->bottom_poc - listX[j][i]->poc);
00568 iTRp = iClip3 (-128, 127, p_Pic->bottom_poc - listX[j][k]->poc);
00569 }
00570
00571 if (iTRp != 0)
00572 {
00573 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00574 p_EPZS->mv_scale[j][i][k] = iClip3 (-2048, 2047, rshift_rnd_sf ((iTRb * prescale), 6));
00575 }
00576 else
00577 p_EPZS->mv_scale[j][i][k] = 256;
00578 }
00579 }
00580 }
00581
00582 if (p_Inp->EPZSTemporal)
00583 {
00584 MotionVector **MotionVector0 = p->frame[LIST_0];
00585 MotionVector **MotionVector1 = p->frame[LIST_1];
00586
00587 fs_top = fs_bottom = fs = listX[list][0];
00588 if (p_Img->listXsize[list] > 1)
00589 fs_top1 = fs_bottom1 = fs1 = listX[list][1];
00590 else
00591 fs_top1 = fs_bottom1 = fs1 = listX[list][0];
00592 for (j = 0; j < 6; ++j)
00593 {
00594 for (i = 0; i < 6; ++i)
00595 {
00596 epzs_scale[0][j][i] = 256;
00597 epzs_scale[1][j][i] = 256;
00598 }
00599 }
00600
00601 for (j = 0; j < 2 + (currSlice->MbaffFrameFlag << 2); j += 2)
00602 {
00603 for (i = 0; i < p_Img->listXsize[j]; ++i)
00604 {
00605 if (j == 0)
00606 iTRb = iClip3 (-128, 127, p_Pic->poc - listX[LIST_0 + j][i]->poc);
00607 else if (j == 2)
00608 iTRb = iClip3 (-128, 127, p_Pic->top_poc - listX[LIST_0 + j][i]->poc);
00609 else
00610 iTRb = iClip3 (-128, 127, p_Pic->bottom_poc - listX[LIST_0 + j][i]->poc);
00611 iTRp = iClip3 (-128, 127, listX[list + j][0]->poc - listX[LIST_0 + j][i]->poc);
00612
00613 if (iTRp != 0)
00614 {
00615 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00616 prescale = iClip3 (-2048, 2047, rshift_rnd_sf ((iTRb * prescale), 6));
00617
00618
00619 }
00620 else
00621 prescale = 256;
00622
00623 epzs_scale[0][j][i] = rshift_rnd_sf ((p_EPZS->mv_scale[j][0][i] * prescale), 8);
00624 epzs_scale[0][j + 1][i] = prescale - 256;
00625
00626 if (p_Img->listXsize[list + j] > 1)
00627 {
00628 iTRp = iClip3 (-128, 127, listX[list + j][1]->poc - listX[LIST_0 + j][i]->poc);
00629 if (iTRp != 0)
00630 {
00631 prescale = (16384 + iabs (iTRp / 2)) / iTRp;
00632 prescale = iClip3 (-2048, 2047, rshift_rnd_sf ((iTRb * prescale), 6));
00633
00634 }
00635 else
00636 prescale = 256;
00637
00638 epzs_scale[1][j][i] = rshift_rnd_sf ((p_EPZS->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
00649 if (currSlice->MbaffFrameFlag)
00650 {
00651 fs_top = listX[list + 2][0];
00652 fs_bottom = listX[list + 4][0];
00653
00654 if (p_Img->listXsize[0] > 1)
00655 {
00656 fs_top1 = listX[list + 2][1];
00657 fs_bottom1 = listX[list + 4][1];
00658 }
00659 }
00660 else
00661 {
00662 if (currSlice->structure != FRAME)
00663 {
00664 if ((currSlice->structure != fs->structure) && (fs->coded_frame))
00665 {
00666 if (currSlice->structure == TOP_FIELD)
00667 {
00668 fs_top = fs_bottom = fs = listX[list][0]->top_field;
00669 fs_top1 = fs_bottom1 = fs1 = listX[list][0]->bottom_field;
00670 }
00671 else
00672 {
00673 fs_top = fs_bottom = fs = listX[list][0]->bottom_field;
00674 fs_top1 = fs_bottom1 = fs1 = listX[list][0]->top_field;
00675 }
00676 }
00677 }
00678 }
00679
00680 p_motion = &fs->motion;
00681
00682 if (!currSlice->active_sps->frame_mbs_only_flag)
00683 {
00684 if (currSlice->MbaffFrameFlag)
00685 {
00686 for (j = 0; j < fs->size_y >> 2; ++j)
00687 {
00688 jj = j >> 1;
00689 jdiv = jj + 4 * (j >> 3);
00690 for (i = 0; i < fs->size_x >> 2; ++i)
00691 {
00692 if (p_motion->field_frame[j][i])
00693 {
00694
00695
00696
00697 if (iabs (p_Pic->poc - fs_bottom->poc) > iabs (p_Pic->poc - fs_top->poc))
00698 {
00699 tempmv_scale[LIST_0] = 256;
00700 tempmv_scale[LIST_1] = 0;
00701
00702 if (p_motion->ref_id[LIST_0][jdiv][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00703 {
00704 fsx = fs_top1;
00705 loffset = 1;
00706 }
00707 else
00708 {
00709 fsx = fs_top;
00710 loffset = 0;
00711 }
00712
00713 if (p_motion->ref_id[LIST_0][jdiv][i] != -1)
00714 {
00715 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
00716 {
00717 if (p_Pic->ref_pic_num[LIST_0][iref] == p_motion->ref_id[LIST_0][jdiv][i])
00718 {
00719 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00720 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00721 break;
00722 }
00723 }
00724
00725 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][jj][i], invmv_precision);
00726 }
00727 else
00728 {
00729 MotionVector0[j][i].mv_x = 0;
00730 MotionVector0[j][i].mv_y = 0;
00731 MotionVector1[j][i].mv_x = 0;
00732 MotionVector1[j][i].mv_y = 0;
00733 }
00734 }
00735 else
00736 {
00737 tempmv_scale[LIST_0] = 256;
00738 tempmv_scale[LIST_1] = 0;
00739 if (p_motion->ref_id[LIST_0][jdiv + 4][i] < 0 && p_Img->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 (p_motion->ref_id[LIST_0][jdiv + 4][i] != -1)
00751 {
00752 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
00753 {
00754 if (p_Pic->ref_pic_num[LIST_0][iref] == p_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
00762 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][jj][i], invmv_precision);
00763 }
00764 else
00765 {
00766 MotionVector0[j][i].mv_x = 0;
00767 MotionVector0[j][i].mv_y = 0;
00768 MotionVector1[j][i].mv_x = 0;
00769 MotionVector1[j][i].mv_y = 0;
00770 }
00771 }
00772 }
00773 else
00774 {
00775 tempmv_scale[LIST_0] = 256;
00776 tempmv_scale[LIST_1] = 0;
00777
00778 if (p_motion->ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00779 {
00780 fsx = fs1;
00781 loffset = 1;
00782 }
00783 else
00784 {
00785 fsx = fs;
00786 loffset = 0;
00787 }
00788
00789 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
00790 {
00791 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
00792 {
00793 if (p_Pic->ref_pic_num[LIST_0][iref] == fsx->motion.ref_id[LIST_0][j][i])
00794 {
00795 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00796 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00797 break;
00798 }
00799 }
00800 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
00801 }
00802 else
00803 {
00804 MotionVector0[j][i].mv_x = 0;
00805 MotionVector0[j][i].mv_y = 0;
00806 MotionVector1[j][i].mv_x = 0;
00807 MotionVector1[j][i].mv_y = 0;
00808 }
00809 }
00810 }
00811 }
00812 }
00813 else
00814 {
00815 for (j = 0; j < fs->size_y >> 2; ++j)
00816 {
00817 jj = j >> 1;
00818 jdiv = jj + 4 * (j >> 3);
00819 for (i = 0; i < fs->size_x >> 2; ++i)
00820 {
00821 tempmv_scale[LIST_0] = 256;
00822 tempmv_scale[LIST_1] = 0;
00823 if (p_motion->ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00824 {
00825 fsx = fs1;
00826 loffset = 1;
00827 }
00828 else
00829 {
00830 fsx = fs;
00831 loffset = 0;
00832 }
00833
00834 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
00835 {
00836 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
00837 {
00838 if (p_Pic->ref_pic_num[LIST_0][iref] == fsx->motion.ref_id[LIST_0][j][i])
00839 {
00840 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00841 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00842
00843 break;
00844 }
00845 }
00846
00847 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
00848 }
00849 else
00850 {
00851 MotionVector0[j][i].mv_x = 0;
00852 MotionVector0[j][i].mv_y = 0;
00853 MotionVector1[j][i].mv_x = 0;
00854 MotionVector1[j][i].mv_y = 0;
00855 }
00856 }
00857 }
00858 }
00859
00860
00861 if (currSlice->structure || currSlice->MbaffFrameFlag)
00862 {
00863 for (j = 0; j < fs->size_y >> 3; ++j)
00864 {
00865 for (i = 0; i < fs->size_x >> 2; ++i)
00866 {
00867 if (!currSlice->MbaffFrameFlag)
00868 {
00869 tempmv_scale[LIST_0] = 256;
00870 tempmv_scale[LIST_1] = 0;
00871 if (p_motion->ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00872 {
00873 fsx = fs1;
00874 loffset = 1;
00875 }
00876 else
00877 {
00878 fsx = fs;
00879 loffset = 0;
00880 }
00881
00882 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
00883 {
00884 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
00885 {
00886 if (p_Pic->ref_pic_num[LIST_0][iref] == fsx->motion.ref_id[LIST_0][j][i])
00887 {
00888 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
00889 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
00890 break;
00891 }
00892 }
00893 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
00894 }
00895 else
00896 {
00897 MotionVector0[j][i].mv_x = 0;
00898 MotionVector0[j][i].mv_y = 0;
00899 MotionVector1[j][i].mv_x = 0;
00900 MotionVector1[j][i].mv_y = 0;
00901 }
00902 }
00903 else
00904 {
00905 tempmv_scale[LIST_0] = 256;
00906 tempmv_scale[LIST_1] = 0;
00907 if (fs_bottom->motion.ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00908 {
00909 fsx = fs_bottom1;
00910 loffset = 1;
00911 }
00912 else
00913 {
00914 fsx = fs_bottom;
00915 loffset = 0;
00916 }
00917
00918 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
00919 {
00920 for (iref = 0; iref < imin (2 * currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0 + 4]); ++iref)
00921 {
00922 if (p_Pic->ref_pic_num[LIST_0 + 4][iref] == fsx->motion.ref_id[LIST_0][j][i])
00923 {
00924 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 4][iref];
00925 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 4][iref];
00926 break;
00927 }
00928 }
00929
00930 compute_scaled (&p->bot[LIST_0][j][i], &p->bot[LIST_1][j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
00931 }
00932 else
00933 {
00934 p->bot[LIST_0][j][i].mv_x = 0;
00935 p->bot[LIST_0][j][i].mv_y = 0;
00936 p->bot[LIST_1][j][i].mv_x = 0;
00937 p->bot[LIST_1][j][i].mv_y = 0;
00938 }
00939
00940 if (!p_motion->field_frame[2 * j][i])
00941 {
00942 p->bot[LIST_0][j][i].mv_y = (p->bot[LIST_0][j][i].mv_y + 1) >> 1;
00943 p->bot[LIST_1][j][i].mv_y = (p->bot[LIST_1][j][i].mv_y + 1) >> 1;
00944 }
00945
00946 tempmv_scale[LIST_0] = 256;
00947 tempmv_scale[LIST_1] = 0;
00948 if (fs_top->motion.ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
00949 {
00950 fsx = fs_top1;
00951 loffset = 1;
00952 }
00953 else
00954 {
00955 fsx = fs_top;
00956 loffset = 0;
00957 }
00958 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
00959 {
00960 for (iref = 0; iref < imin (2 * currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0 + 2]); ++iref)
00961 {
00962 if (p_Pic->ref_pic_num[LIST_0 + 2][iref] == fsx->motion.ref_id[LIST_0][j][i])
00963 {
00964 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0 + 2][iref];
00965 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1 + 2][iref];
00966 break;
00967 }
00968 }
00969
00970 compute_scaled (&p->top[LIST_0][j][i], &p->top[LIST_1][j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
00971 }
00972 else
00973 {
00974 p->top[LIST_0][j][i].mv_x = 0;
00975 p->top[LIST_0][j][i].mv_y = 0;
00976 p->top[LIST_1][j][i].mv_x = 0;
00977 p->top[LIST_1][j][i].mv_y = 0;
00978 }
00979
00980 if (!p_motion->field_frame[2 * j][i])
00981 {
00982 p->top[LIST_0][j][i].mv_y = (p->top[LIST_0][j][i].mv_y + 1) >> 1;
00983 p->top[LIST_1][j][i].mv_y = (p->top[LIST_1][j][i].mv_y + 1) >> 1;
00984 }
00985 }
00986 }
00987 }
00988 }
00989
00990
00991
00992 if (!currSlice->structure)
00993 {
00994 for (j = 0; j < fs->size_y >> 2; ++j)
00995 {
00996 jj = j >> 1;
00997 jdiv = (j >> 1) + ((j >> 3) << 2);
00998 for (i = 0; i < fs->size_x >> 2; ++i)
00999 {
01000 if (p_motion->field_frame[j][i])
01001 {
01002 tempmv_scale[LIST_0] = 256;
01003 tempmv_scale[LIST_1] = 0;
01004 if (p_motion->ref_id[LIST_0][jdiv][i] < 0 && p_Img->listXsize[LIST_0] > 1)
01005 {
01006 fsx = fs1;
01007 loffset = 1;
01008 }
01009 else
01010 {
01011 fsx = fs;
01012 loffset = 0;
01013 }
01014
01015 if (fsx->motion.ref_id[LIST_0][jdiv][i] != -1)
01016 {
01017 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
01018 {
01019 if (p_Pic->ref_pic_num[LIST_0][iref] == fsx->motion.ref_id[LIST_0][jdiv][i])
01020 {
01021 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
01022 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
01023 break;
01024 }
01025 }
01026 if (iabs (p_Pic->poc - fsx->bottom_field->poc) > iabs (p_Pic->poc - fsx->top_field->poc))
01027 {
01028 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale,
01029 fsx->top_field->motion.mv[LIST_0][j][i], invmv_precision);
01030 }
01031 else
01032 {
01033 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale,
01034 fsx->bottom_field->motion.mv[LIST_0][j][i], invmv_precision);
01035 }
01036 }
01037 else
01038 {
01039 MotionVector0[j][i].mv_x = 0;
01040 MotionVector0[j][i].mv_y = 0;
01041 MotionVector1[j][i].mv_x = 0;
01042 MotionVector1[j][i].mv_y = 0;
01043 }
01044 }
01045 }
01046 }
01047 }
01048 }
01049 else
01050 {
01051 for (j = 0; j < fs->size_y >> 2; ++j)
01052 {
01053 for (i = 0; i < fs->size_x >> 2; ++i)
01054 {
01055 tempmv_scale[LIST_0] = 256;
01056 tempmv_scale[LIST_1] = 0;
01057
01058 if (p_motion->ref_id[LIST_0][j][i] < 0 && p_Img->listXsize[LIST_0] > 1)
01059 {
01060 fsx = fs1;
01061 loffset = 1;
01062 }
01063 else
01064 {
01065 fsx = fs;
01066 loffset = 0;
01067 }
01068 if (fsx->motion.ref_id[LIST_0][j][i] != -1)
01069 {
01070 for (iref = 0; iref < imin (currSlice->num_ref_idx_active[LIST_0], p_Img->listXsize[LIST_0]); ++iref)
01071 {
01072 if (p_Pic->ref_pic_num[LIST_0][iref] == fsx->motion.ref_id[LIST_0][j][i])
01073 {
01074 tempmv_scale[LIST_0] = epzs_scale[loffset][LIST_0][iref];
01075 tempmv_scale[LIST_1] = epzs_scale[loffset][LIST_1][iref];
01076 break;
01077 }
01078 }
01079
01080 compute_scaled (&MotionVector0[j][i], &MotionVector1[j][i], tempmv_scale, fsx->motion.mv[LIST_0][j][i], invmv_precision);
01081 }
01082 else
01083 {
01084 MotionVector0[j][i].mv_x = 0;
01085 MotionVector0[j][i].mv_y = 0;
01086 MotionVector1[j][i].mv_x = 0;
01087 MotionVector1[j][i].mv_y = 0;
01088 }
01089 }
01090 }
01091 }
01092
01093 if (!currSlice->active_sps->frame_mbs_only_flag)
01094 {
01095 for (j = 0; j < fs->size_y >> 2; ++j)
01096 {
01097 for (i = 0; i < fs->size_x >> 2; ++i)
01098 {
01099 if ((!currSlice->MbaffFrameFlag && !currSlice->structure && p_motion->field_frame[j][i])
01100 || (currSlice->MbaffFrameFlag && p_motion->field_frame[j][i]))
01101 {
01102 MotionVector0[j][i].mv_y *= 2;
01103 MotionVector1[j][i].mv_y *= 2;
01104 }
01105 else if (currSlice->structure && !p_motion->field_frame[j][i])
01106 {
01107 MotionVector0[j][i].mv_y = (short) rshift_rnd_sf (MotionVector0[j][i].mv_y, 1);
01108 MotionVector1[j][i].mv_y = (short) rshift_rnd_sf (MotionVector1[j][i].mv_y, 1);
01109 }
01110 }
01111 }
01112 }
01113 }
01114 }
01115
01116
01117 static void
01118 is_block_available (Macroblock * currMB, StorablePicture * ref_picture, MEBlock * mv_block, int block_available[4])
01119 {
01120 if ((mv_block->block_y << 2) > 0)
01121 {
01122 if ((mv_block->block_x << 2) < 8)
01123 {
01124 if ((mv_block->block_y << 2) == 8)
01125 {
01126 block_available[0] = (mv_block->blocksize_x != MB_BLOCK_SIZE) || (currMB->mb_x < (ref_picture->size_x >> 4) - 1);
01127 }
01128 else
01129 {
01130 block_available[0] = ((mv_block->block_x << 2) + mv_block->blocksize_x != 8)
01131 || (currMB->mb_x < (ref_picture->size_x >> 4) - 1);
01132 }
01133 }
01134 else
01135 {
01136 block_available[0] = ((mv_block->block_x << 2) + mv_block->blocksize_x != MB_BLOCK_SIZE) || (currMB->mb_x < (ref_picture->size_x >> 4) - 1);
01137 }
01138 }
01139 else
01140 {
01141 block_available[0] = ((mv_block->block_x << 2) + mv_block->blocksize_x != MB_BLOCK_SIZE) || (currMB->mb_x < (ref_picture->size_x >> 4) - 1);
01142 }
01143
01144 block_available[1] = ((mv_block->block_y << 2) + mv_block->blocksize_y != MB_BLOCK_SIZE) || ((currMB->mb_y < (ref_picture->size_y >> 4) - 1));
01145 block_available[2] = mv_block->block[0].available;
01146 block_available[3] = mv_block->block[1].available;
01147 }
01148
01149
01150
01151
01152
01153
01154
01155 void
01156 EPZSBlockTypePredictorsMB (Slice * currSlice, MEBlock * mv_block, SPoint * point, int *prednum)
01157 {
01158 int blocktype = mv_block->blocktype;
01159 int block_x = mv_block->block_x;
01160 int block_y = mv_block->block_y;
01161 int list = mv_block->list;
01162 int ref = mv_block->ref_idx;
01163 EPZSParameters *p_EPZS = currSlice->p_EPZS;
01164 short *****all_mv = currSlice->all_mv[list];
01165 MotionVector *cur_mv = &point[*prednum].motion;
01166
01167 if (blocktype != 1)
01168 {
01169 short *mv = all_mv[ref][BLOCK_PARENT[blocktype]][block_y][block_x];
01170 cur_mv->mv_x = mv[0];
01171 cur_mv->mv_y = mv[1];
01172
01173 *prednum += (*((int *) cur_mv) != 0);
01174
01175 cur_mv = &point[*prednum].motion;
01176 mv = all_mv[ref][1][block_y][block_x];
01177 cur_mv->mv_x = mv[0];
01178 cur_mv->mv_y = mv[1];
01179
01180 *prednum += (*((int *) cur_mv) != 0);
01181 }
01182
01183 if (ref > 0)
01184 {
01185 cur_mv = &point[*prednum].motion;
01186 scale_mv (cur_mv, p_EPZS->mv_scale[list][ref][ref - 1], all_mv[ref - 1][blocktype][block_y][block_x], 8);
01187
01188 *prednum += (*((int *) cur_mv) != 0);
01189
01190 if (ref > 1)
01191 {
01192 cur_mv = &point[*prednum].motion;
01193 scale_mv (cur_mv, p_EPZS->mv_scale[list][ref][0], all_mv[0][blocktype][block_y][block_x], 8);
01194
01195 *prednum += (*((int *) cur_mv) != 0);
01196 }
01197 }
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207 short
01208 EPZSSpatialPredictors (EPZSParameters * p_EPZS, PixelPos * block, int list, int list_offset, short ref, char **refPic, short ***tmp_mv)
01209 {
01210 short refA = 0, refB = 0, refC = 0, refD = 0;
01211 ImageParameters *p_Img = p_EPZS->p_Img;
01212 int *mot_scale = p_EPZS->mv_scale[list + list_offset][ref];
01213 SPoint *point = p_EPZS->predictor->point;
01214
01215
01216 (point)->motion.mv_x = 0;
01217 (point++)->motion.mv_y = 0;
01218
01219
01220 if (!p_Img->MbaffFrameFlag)
01221 {
01222 refA = block[0].available ? (short) refPic[block[0].pos_y][block[0].pos_x] : -1;
01223 refB = block[1].available ? (short) refPic[block[1].pos_y][block[1].pos_x] : -1;
01224 refC = block[2].available ? (short) refPic[block[2].pos_y][block[2].pos_x] : -1;
01225 refD = block[3].available ? (short) refPic[block[3].pos_y][block[3].pos_x] : -1;
01226
01227
01228 if (block[0].available)
01229 {
01230 scale_mv (&point->motion, mot_scale[refA], tmp_mv[block[0].pos_y][block[0].pos_x], 8);
01231
01232
01233
01234
01235
01236
01237
01238 ++point;
01239 }
01240 else
01241 {
01242 (point)->motion.mv_x = 12;
01243 (point++)->motion.mv_y = 0;
01244 }
01245
01246 if (block[1].available)
01247 {
01248 scale_mv (&point->motion, mot_scale[refB], tmp_mv[block[1].pos_y][block[1].pos_x], 8);
01249
01250
01251
01252
01253
01254
01255
01256 ++point;
01257 }
01258 else
01259 {
01260 (point)->motion.mv_x = 0;
01261 (point++)->motion.mv_y = 12;
01262 }
01263
01264
01265 if (block[2].available)
01266 {
01267 scale_mv (&point->motion, mot_scale[refC], tmp_mv[block[2].pos_y][block[2].pos_x], 8);
01268
01269
01270
01271
01272
01273
01274
01275 ++point;
01276 }
01277 else
01278 {
01279 (point)->motion.mv_x = -12;
01280 (point++)->motion.mv_y = 0;
01281 }
01282
01283
01284 if (block[3].available)
01285 {
01286 scale_mv (&point->motion, mot_scale[refD], tmp_mv[block[3].pos_y][block[3].pos_x], 8);
01287
01288
01289
01290
01291
01292
01293
01294 ++point;
01295 }
01296 else
01297 {
01298 (point)->motion.mv_x = 0;
01299 (point++)->motion.mv_y = -12;
01300 }
01301 }
01302 else
01303 {
01304
01305 if (list_offset)
01306 {
01307 refA = block[0].available ? p_Img->mb_data[block[0].mb_addr].mb_field ? (short) refPic[block[0].pos_y][block[0].pos_x]
01308 : (short) refPic[block[0].pos_y][block[0].pos_x] * 2 : -1;
01309 refB = block[1].available ? p_Img->mb_data[block[1].mb_addr].mb_field ? (short) refPic[block[1].pos_y][block[1].pos_x]
01310 : (short) refPic[block[1].pos_y][block[1].pos_x] * 2 : -1;
01311 refC = block[2].available ? p_Img->mb_data[block[2].mb_addr].mb_field ? (short) refPic[block[2].pos_y][block[2].pos_x]
01312 : (short) refPic[block[2].pos_y][block[2].pos_x] * 2 : -1;
01313 refD = block[3].available ? p_Img->mb_data[block[3].mb_addr].mb_field ? (short) refPic[block[3].pos_y][block[3].pos_x]
01314 : (short) refPic[block[3].pos_y][block[3].pos_x] * 2 : -1;
01315
01316
01317 if (block[0].available)
01318 {
01319 scale_mv (&point->motion, mot_scale[refA], tmp_mv[block[0].pos_y][block[0].pos_x], 8);
01320 if (!p_Img->mb_data[block[0].mb_addr].mb_field)
01321
01322 point->motion.mv_y <<= 1;
01323 ++point;
01324 }
01325 else
01326 {
01327 (point)->motion.mv_x = 12;
01328 (point++)->motion.mv_y = 0;
01329 }
01330
01331
01332 if (block[1].available)
01333 {
01334 scale_mv (&point->motion, mot_scale[refB], tmp_mv[block[1].pos_y][block[1].pos_x], 8);
01335 if (!p_Img->mb_data[block[1].mb_addr].mb_field)
01336
01337 point->motion.mv_y <<= 1;
01338 ++point;
01339 }
01340 else
01341 {
01342 (point)->motion.mv_x = 0;
01343 (point++)->motion.mv_y = 12;
01344 }
01345
01346
01347 if (block[2].available)
01348 {
01349 scale_mv (&point->motion, mot_scale[refC], tmp_mv[block[2].pos_y][block[2].pos_x], 8);
01350 if (!p_Img->mb_data[block[2].mb_addr].mb_field)
01351
01352 point->motion.mv_y <<= 1;
01353 ++point;
01354 }
01355 else
01356 {
01357 (point)->motion.mv_x = -12;
01358 (point++)->motion.mv_y = 0;
01359 }
01360
01361
01362 if (block[3].available)
01363 {
01364 scale_mv (&point->motion, mot_scale[refD], tmp_mv[block[3].pos_y][block[3].pos_x], 8);
01365 if (!p_Img->mb_data[block[3].mb_addr].mb_field)
01366
01367 point->motion.mv_y <<= 1;
01368 ++point;
01369 }
01370 else
01371 {
01372 (point)->motion.mv_x = 0;
01373 (point++)->motion.mv_y = -12;
01374 }
01375 }
01376 else
01377 {
01378 refA = block[0].available
01379 ? p_Img->mb_data[block[0].mb_addr].mb_field
01380 ? (short) refPic[block[0].pos_y][block[0].pos_x] >> 1 : (short) refPic[block[0].pos_y][block[0].pos_x] : -1;
01381 refB = block[1].available
01382 ? p_Img->mb_data[block[1].mb_addr].mb_field
01383 ? (short) refPic[block[1].pos_y][block[1].pos_x] >> 1 : (short) refPic[block[1].pos_y][block[1].pos_x] : -1;
01384 refC = block[2].available
01385 ? p_Img->mb_data[block[2].mb_addr].mb_field
01386 ? (short) refPic[block[2].pos_y][block[2].pos_x] >> 1 : (short) refPic[block[2].pos_y][block[2].pos_x] : -1;
01387 refD = block[3].available
01388 ? p_Img->mb_data[block[3].mb_addr].mb_field
01389 ? (short) refPic[block[3].pos_y][block[3].pos_x] >> 1 : (short) refPic[block[3].pos_y][block[3].pos_x] : -1;
01390
01391
01392 if (block[0].available)
01393 {
01394 scale_mv (&point->motion, mot_scale[refA], tmp_mv[block[0].pos_y][block[0].pos_x], 8);
01395 if (p_Img->mb_data[block[0].mb_addr].mb_field)
01396 point->motion.mv_y = (short) rshift_rnd_sf (point->motion.mv_y, 1);
01397 ++point;
01398 }
01399 else
01400 {
01401 (point)->motion.mv_x = 12;
01402 (point++)->motion.mv_y = 0;
01403 }
01404
01405
01406 if (block[1].available)
01407 {
01408 scale_mv (&point->motion, mot_scale[refB], tmp_mv[block[1].pos_y][block[1].pos_x], 8);
01409 if (p_Img->mb_data[block[1].mb_addr].mb_field)
01410 point->motion.mv_y = (short) rshift_rnd_sf (point->motion.mv_y, 1);
01411 ++point;
01412 }
01413 else
01414 {
01415 (point)->motion.mv_x = 0;
01416 (point++)->motion.mv_y = 12;
01417 }
01418
01419
01420 if (block[2].available)
01421 {
01422 scale_mv (&point->motion, mot_scale[refC], tmp_mv[block[2].pos_y][block[2].pos_x], 8);
01423 if (p_Img->mb_data[block[2].mb_addr].mb_field)
01424 point->motion.mv_y = (short) rshift_rnd_sf (point->motion.mv_y, 1);
01425 ++point;
01426 }
01427 else
01428 {
01429 (point)->motion.mv_x = -12;
01430 (point++)->motion.mv_y = 0;
01431 }
01432
01433
01434 if (block[3].available)
01435 {
01436 scale_mv (&point->motion, mot_scale[refD], tmp_mv[block[3].pos_y][block[3].pos_x], 8);
01437 if (p_Img->mb_data[block[3].mb_addr].mb_field)
01438 point->motion.mv_y = (short) rshift_rnd_sf (point->motion.mv_y, 1);
01439 ++point;
01440 }
01441 else
01442 {
01443 (point)->motion.mv_x = 12;
01444 (point++)->motion.mv_y = 0;
01445 }
01446 }
01447 }
01448
01449 return ((refA == -1) + (refB == -1) + ((refC == -1) && (refD == -1)));
01450 }
01451
01452
01453
01454
01455
01456
01457
01458
01459 void
01460 EPZSTemporalPredictors (Macroblock *currMB,
01461 StorablePicture *ref_picture,
01462 EPZSParameters * p_EPZS,
01463 MEBlock *mv_block,
01464 int *prednum,
01465 int stopCriterion,
01466 int min_mcost)
01467 {
01468 int list_offset = currMB->list_offset;
01469 int blockshape_x = (mv_block->blocksize_x >> 2);
01470 int blockshape_y = (mv_block->blocksize_y >> 2);
01471 int o_block_x = mv_block->pos_x2;
01472 int o_block_y = mv_block->pos_y2;
01473 int list = mv_block->list;
01474 int ref = mv_block->ref_idx;
01475
01476 EPZSColocParams *p_Coloc = p_EPZS->p_colocated;
01477 SPoint * point = p_EPZS->predictor->point;
01478 int mvScale = p_EPZS->mv_scale[list + list_offset][ref][0];
01479 MotionVector **col_mv = (list_offset == 0) ? p_Coloc->frame[list] : (list_offset == 2) ? p_Coloc->top[list] : p_Coloc->bot[list];
01480 MotionVector *cur_mv = &point[*prednum].motion;
01481
01482 *prednum += add_predictor (cur_mv, col_mv[o_block_y][o_block_x], mvScale, 8);
01483
01484 if (min_mcost > stopCriterion && ref < 2)
01485 {
01486 int block_available[4];
01487 is_block_available (currMB, ref_picture, mv_block, block_available);
01488
01489 if (block_available[2])
01490 {
01491 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y][o_block_x - 1], mvScale, 8);
01492
01493
01494 if (block_available[3])
01495 {
01496 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y - 1][o_block_x - 1], mvScale, 8);
01497 }
01498
01499
01500 if (block_available[1])
01501 {
01502 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x - 1], mvScale, 8);
01503 }
01504 }
01505
01506
01507 if (block_available[3])
01508 {
01509 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y - 1][o_block_x], mvScale, 8);
01510 }
01511
01512
01513 if (block_available[0])
01514 {
01515 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y][o_block_x + blockshape_x], mvScale, 8);
01516 if (block_available[3])
01517 {
01518 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y - 1][o_block_x + blockshape_x], mvScale, 8);
01519 }
01520
01521 if (block_available[1])
01522 {
01523 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x + blockshape_x], mvScale, 8);
01524 }
01525 }
01526
01527 if (block_available[1])
01528 {
01529 *prednum += add_predictor (&point[*prednum].motion, col_mv[o_block_y + blockshape_y][o_block_x], mvScale, 8);
01530 }
01531 }
01532 }
01533
01534
01535
01536
01537
01538
01539
01540 void
01541 EPZSBlockTypePredictors (Slice * currSlice, MEBlock *mv_block, SPoint * point, int *prednum)
01542 {
01543 int blocktype = mv_block->blocktype;
01544 int block_x = mv_block->block_x;
01545 int block_y = mv_block->block_y;
01546 int list = mv_block->list;
01547 int ref = mv_block->ref_idx;
01548 short *****all_mv = currSlice->all_mv[list];
01549 short *mv = all_mv[ref][BLOCK_PARENT[blocktype]][block_y][block_x];
01550 MotionVector *cur_mv = &point[*prednum].motion;
01551
01552 cur_mv->mv_x = mv[0];
01553 cur_mv->mv_y = mv[1];
01554
01555
01556 *prednum += (*((int *) cur_mv) != 0);
01557
01558 if ((ref > 0) && (currSlice->structure != FRAME))
01559 {
01560 EPZSParameters *p_EPZS = currSlice->p_EPZS;
01561 cur_mv = &point[*prednum].motion;
01562 scale_mv (cur_mv, p_EPZS->mv_scale[list][ref][ref - 1], all_mv[ref - 1][blocktype][block_y][block_x], 8);
01563
01564
01565 *prednum += (*((int *) cur_mv) != 0);
01566 if (ref > 1)
01567 {
01568 cur_mv = &point[*prednum].motion;
01569 scale_mv (cur_mv, p_EPZS->mv_scale[list][ref][0], all_mv[0][blocktype][block_y][block_x], 8);
01570
01571 *prednum += (*((int *) cur_mv) != 0);
01572 }
01573 }
01574
01575 cur_mv = &point[*prednum].motion;
01576 mv = all_mv[ref][1][block_y][block_x];
01577 cur_mv->mv_x = mv[0];
01578 cur_mv->mv_y = mv[1];
01579
01580 *prednum += (*((int *) cur_mv) != 0);
01581 }
01582
01583
01584
01585
01586
01587
01588
01589 void
01590 EPZSWindowPredictors (MotionVector * mv, EPZSStructure * predictor, int *prednum, EPZSStructure * windowPred)
01591 {
01592 int pos;
01593 SPoint *wPoint = &windowPred->point[0];
01594 SPoint *pPoint = &predictor->point[(*prednum)];
01595
01596 for (pos = 0; pos < windowPred->searchPoints; ++pos)
01597 {
01598 (pPoint++)->motion = add_MVs ((wPoint++)->motion, mv);
01599 }
01600 *prednum += windowPred->searchPoints;
01601 }
01602
01603
01604
01605
01606
01607
01608
01609
01610 void
01611 EPZSSpatialMemPredictors (EPZSParameters * p_EPZS,
01612 MEBlock * mv_block,
01613 int list,
01614 int *prednum,
01615 int img_width)
01616 {
01617
01618 SPoint *point = p_EPZS->predictor->point;
01619
01620 int blocktype = mv_block->blocktype - 1;
01621
01622 int by = mv_block->block_y;
01623
01624 int bs_x = (mv_block->blocksize_x >> 2);
01625 int bs_y = (mv_block->blocksize_y >> 2);
01626 int pic_x = mv_block->pos_x2;
01627
01628 int ref = mv_block->ref_idx;
01629
01630 #if EPZSREF
01631 MotionVector **prd_mv = p_EPZS->p_motion[list][ref][blocktype];
01632 MotionVector *cur_mv = &point[*prednum].motion;
01633
01634
01635 if (pic_x > 0)
01636 {
01637 *cur_mv = prd_mv[by][pic_x - bs_x];
01638 *prednum += (*((int *) cur_mv) != 0);
01639 cur_mv = &point[*prednum].motion;
01640 }
01641
01642 by = (by > 0) ? by - bs_y : 4 - bs_y;
01643
01644
01645 *cur_mv = prd_mv[by][pic_x];
01646 *prednum += (*((int *) cur_mv) != 0);
01647
01648
01649 if (pic_x + bs_x < img_width)
01650 {
01651 cur_mv = &point[*prednum].motion;
01652 *cur_mv = prd_mv[by][pic_x + bs_x];
01653 *prednum += (*((int *) cur_mv) != 0);
01654 }
01655 #else
01656 int mot_scale = p_EPZS->mv_scale[list][ref][0];
01657
01658 MotionVector **prd_mv = p_EPZS->p_motion[list][blocktype];
01659
01660
01661 point[*prednum].motion.mv_x = (pic_x > 0)
01662 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by][pic_x - bs_x].mv_x), 8)
01663 : 0;
01664 point[*prednum].motion.mv_y = (pic_x > 0)
01665 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by][pic_x - bs_x].mv_y), 8)
01666 : 0;
01667 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01668
01669
01670 point[*prednum].motion.mv_x = (by > 0)
01671 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by - bs_y][pic_x].mv_x), 8)
01672 : (short) rshift_rnd_sf ((mot_scale * prd_mv[4 - bs_y][pic_x].mv_x), 8);
01673 point[*prednum].motion.mv_y = (by > 0)
01674 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by - bs_y][pic_x].mv_y), 8)
01675 : (short) rshift_rnd_sf ((mot_scale * prd_mv[4 - bs_y][pic_x].mv_y), 8);
01676 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01677
01678
01679 point[*prednum].motion.mv_x = (pic_x + bs_x < img_width)
01680 ? (by > 0)
01681 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by - bs_y][pic_x + bs_x].mv_x), 8)
01682 : (short) rshift_rnd_sf ((mot_scale * prd_mv[4 - bs_y][pic_x + bs_x].mv_x), 8)
01683 : 0;
01684 point[*prednum].motion.mv_y = (pic_x + bs_x < img_width)
01685 ? (by > 0)
01686 ? (short) rshift_rnd_sf ((mot_scale * prd_mv[by - bs_y][pic_x + bs_x].mv_y), 8)
01687 : (short) rshift_rnd_sf ((mot_scale * prd_mv[4 - bs_y][pic_x + bs_x].mv_y), 8)
01688 : 0;
01689 *prednum += ((point[*prednum].motion.mv_x != 0) || (point[*prednum].motion.mv_y != 0));
01690 #endif
01691 }
01692
01693
01694
01695
01696
01697
01698
01699 int
01700 EPZSDetermineStopCriterion (EPZSParameters * p_EPZS, int *prevSad, MEBlock * mv_block, int lambda_dist)
01701 {
01702 int blocktype = mv_block->blocktype;
01703 int blockshape_x = (mv_block->blocksize_x >> 2);
01704 PixelPos *block = mv_block->block;
01705 int sadA, sadB, sadC, stopCriterion;
01706 sadA = block[0].available ? prevSad[-blockshape_x] : INT_MAX;
01707 sadB = block[1].available ? prevSad[0] : INT_MAX;
01708 sadC = block[2].available ? prevSad[blockshape_x] : INT_MAX;
01709
01710 stopCriterion = imin (sadA, imin (sadB, sadC));
01711 stopCriterion = imax (stopCriterion, p_EPZS->minthres[blocktype]);
01712 stopCriterion = imin (stopCriterion, p_EPZS->maxthres[blocktype] + lambda_dist);
01713 stopCriterion = (9 * imax (p_EPZS->medthres[blocktype] + lambda_dist, stopCriterion) + 2 * p_EPZS->medthres[blocktype]) >> 3;
01714
01715 return stopCriterion + lambda_dist;
01716 }
01717
01718
01719
01720
01721
01722
01723
01724
01725 void
01726 EPZSOutputStats (InputParameters * p_Inp, FILE * stat, short stats_file)
01727 {
01728 if (stats_file == 1)
01729 {
01730 fprintf (stat, " EPZS Pattern : %s\n", EPZS_PATTERN[p_Inp->EPZSPattern]);
01731 fprintf (stat, " EPZS Dual Pattern : %s\n", EPZS_DUAL_PATTERN[p_Inp->EPZSDual]);
01732 fprintf (stat, " EPZS Fixed Predictors : %s\n", EPZS_FIXED_PREDICTORS[p_Inp->EPZSFixed]);
01733 fprintf (stat, " EPZS Temporal Predictors : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSTemporal]);
01734 fprintf (stat, " EPZS Spatial Predictors : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSpatialMem]);
01735 fprintf (stat, " EPZS Threshold Multipliers : (%d %d %d)\n", p_Inp->EPZSMedThresScale, p_Inp->EPZSMinThresScale, p_Inp->EPZSMaxThresScale);
01736 fprintf (stat, " EPZS Subpel ME : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSubPelME]);
01737 fprintf (stat, " EPZS Subpel ME BiPred : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSubPelMEBiPred]);
01738 }
01739 else
01740 {
01741 fprintf (stat, " EPZS Pattern : %s\n", EPZS_PATTERN[p_Inp->EPZSPattern]);
01742 fprintf (stat, " EPZS Dual Pattern : %s\n", EPZS_DUAL_PATTERN[p_Inp->EPZSDual]);
01743 fprintf (stat, " EPZS Fixed Predictors : %s\n", EPZS_FIXED_PREDICTORS[p_Inp->EPZSFixed]);
01744 fprintf (stat, " EPZS Temporal Predictors : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSTemporal]);
01745 fprintf (stat, " EPZS Spatial Predictors : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSpatialMem]);
01746 fprintf (stat, " EPZS Threshold Multipliers : (%d %d %d)\n", p_Inp->EPZSMedThresScale, p_Inp->EPZSMinThresScale, p_Inp->EPZSMaxThresScale);
01747 fprintf (stat, " EPZS Subpel ME : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSubPelME]);
01748 fprintf (stat, " EPZS Subpel ME BiPred : %s\n", EPZS_OTHER_PREDICTORS[p_Inp->EPZSSubPelMEBiPred]);
01749 }
01750 }