00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "contributors.h"
00018 #include <limits.h>
00019
00020 #include "global.h"
00021 #include "image.h"
00022 #include "memalloc.h"
00023 #include "mb_access.h"
00024 #include "refbuf.h"
00025
00026 #include "me_distortion.h"
00027 #include "me_fullsearch.h"
00028 #include "me_fullfast.h"
00029 #include "conformance.h"
00030 #include "mv_search.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 void InitializeFastFullIntegerSearch (ImageParameters *p_Img, InputParameters *p_Inp)
00049 {
00050 int i, j, k, list;
00051 int search_range = p_Inp->search_range;
00052 int max_pos = (2*search_range+1) * (2*search_range+1);
00053 MEFullFast *p_me_ffast = NULL;
00054
00055 if ((p_Img->p_ffast_me = calloc (1, sizeof (MEFullFast))) == NULL)
00056 no_mem_exit ("InitializeFastFullIntegerSearch: p_Img->p_ffast_me");
00057 p_me_ffast = p_Img->p_ffast_me;
00058
00059 if ((p_me_ffast->BlockSAD = (distpel*****)malloc (2 * sizeof(distpel****))) == NULL)
00060 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->BlockSAD");
00061
00062 for (list=0; list<2;list++)
00063 {
00064 if ((p_me_ffast->BlockSAD[list] = (distpel****)malloc ((p_Img->max_num_references) * sizeof(distpel***))) == NULL)
00065 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->BlockSAD");
00066 for (i = 0; i < p_Img->max_num_references; i++)
00067 {
00068 if ((p_me_ffast->BlockSAD[list][i] = (distpel***)malloc (8 * sizeof(distpel**))) == NULL)
00069 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->BlockSAD");
00070 for (j = 1; j < 8; j++)
00071 {
00072 if ((p_me_ffast->BlockSAD[list][i][j] = (distpel**)malloc (16 * sizeof(distpel*))) == NULL)
00073 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->BlockSAD");
00074 for (k = 0; k < 16; k++)
00075 {
00076 if ((p_me_ffast->BlockSAD[list][i][j][k] = (distpel*)malloc (max_pos * sizeof(distpel))) == NULL)
00077 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->BlockSAD");
00078 }
00079 }
00080 }
00081 }
00082
00083 if ((p_me_ffast->search_setup_done = (int**)malloc (2*sizeof(int*)))==NULL)
00084 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_setup_done");
00085 if ((p_me_ffast->search_center = (MotionVector**) malloc (2 * sizeof(MotionVector*)))==NULL)
00086 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_center");
00087 if ((p_me_ffast->search_center_padded = (MotionVector**) malloc (2 * sizeof(MotionVector*)))==NULL)
00088 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_center_padded");
00089
00090 if ((p_me_ffast->pos_00 = (int**)malloc (2*sizeof(int*)))==NULL)
00091 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->pos_00");
00092 if ((p_me_ffast->max_search_range = (int**)malloc (2*sizeof(int*)))==NULL)
00093 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->max_search_range");
00094
00095 for (list=0; list<2; list++)
00096 {
00097 if ((p_me_ffast->search_setup_done[list] = (int*)malloc ((p_Img->max_num_references)*sizeof(int)))==NULL)
00098 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_setup_done");
00099 if ((p_me_ffast->search_center[list] = (MotionVector*) malloc ((p_Img->max_num_references) * sizeof(MotionVector)))==NULL)
00100 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_center");
00101 if ((p_me_ffast->search_center_padded[list] = (MotionVector*) malloc ((p_Img->max_num_references) * sizeof(MotionVector)))==NULL)
00102 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->search_center_padded");
00103
00104
00105 if ((p_me_ffast->pos_00[list] = (int*)malloc ((p_Img->max_num_references)*sizeof(int)))==NULL)
00106 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->pos_00");
00107 if ((p_me_ffast->max_search_range[list] = (int*)malloc ((p_Img->max_num_references)*sizeof(int)))==NULL)
00108 no_mem_exit ("InitializeFastFullIntegerSearch: p_me_ffast->max_search_range");
00109 }
00110
00111
00112 if (p_Inp->full_search == 2)
00113 {
00114 for (list=0;list<2;list++)
00115 for (i=0; i<p_Img->max_num_references; i++)
00116 p_me_ffast->max_search_range[list][i] = search_range;
00117 }
00118 else
00119 {
00120 for (list=0;list<2;list++)
00121 {
00122 p_me_ffast->max_search_range[list][0] = search_range;
00123 for (i=1; i< p_Img->max_num_references; i++) p_me_ffast->max_search_range[list][i] = search_range / 2;
00124 }
00125 }
00126 }
00127
00128
00129
00130
00131
00132
00133
00134 void
00135 ClearFastFullIntegerSearch (ImageParameters *p_Img)
00136 {
00137 int i, j, k, list;
00138 MEFullFast *p_me_ffast = p_Img->p_ffast_me;
00139
00140 for (list=0; list<2; list++)
00141 {
00142 for (i = 0; i < p_Img->max_num_references; i++)
00143 {
00144 for (j = 1; j < 8; j++)
00145 {
00146 for (k = 0; k < 16; k++)
00147 {
00148 free (p_me_ffast->BlockSAD[list][i][j][k]);
00149 }
00150 free (p_me_ffast->BlockSAD[list][i][j]);
00151 }
00152 free (p_me_ffast->BlockSAD[list][i]);
00153 }
00154 free (p_me_ffast->BlockSAD[list]);
00155 }
00156 free (p_me_ffast->BlockSAD);
00157
00158 for (list=0; list<2; list++)
00159 {
00160 free (p_me_ffast->search_setup_done[list]);
00161 free (p_me_ffast->search_center_padded[list]);
00162 free (p_me_ffast->search_center[list]);
00163 free (p_me_ffast->pos_00[list]);
00164 free (p_me_ffast->max_search_range[list]);
00165 }
00166 free (p_me_ffast->search_setup_done);
00167 free (p_me_ffast->search_center_padded);
00168 free (p_me_ffast->search_center);
00169 free (p_me_ffast->pos_00);
00170 free (p_me_ffast->max_search_range);
00171 free (p_me_ffast);
00172
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void ResetFastFullIntegerSearch (ImageParameters *p_Img)
00184 {
00185 int list;
00186 for (list=0; list<2; list++)
00187 memset(&p_Img->p_ffast_me->search_setup_done [list][0], 0, p_Img->max_num_references * sizeof(int));
00188 }
00189
00190
00191
00192
00193
00194
00195 void
00196 SetupLargerBlocks (MEFullFast *p_ffast_me, int list, int refindex, int max_pos)
00197 {
00198 #define ADD_UP_BLOCKS() _o=*_bo; _i=*_bi; _j=*_bj; for(pos=0;pos<max_pos;pos++) _o[pos] = _i[pos] + _j[pos];
00199 #define INCREMENT(inc) _bo+=inc; _bi+=inc; _bj+=inc;
00200 distpel *****BlockSAD = p_ffast_me->BlockSAD;
00201
00202 int pos;
00203 distpel **_bo, **_bi, **_bj;
00204 distpel *_o, *_i, *_j;
00205
00206
00207 _bo = BlockSAD[list][refindex][6];
00208 _bi = BlockSAD[list][refindex][7];
00209 _bj = _bi + 4;
00210 ADD_UP_BLOCKS(); INCREMENT(1);
00211 ADD_UP_BLOCKS(); INCREMENT(1);
00212 ADD_UP_BLOCKS(); INCREMENT(1);
00213 ADD_UP_BLOCKS(); INCREMENT(5);
00214 ADD_UP_BLOCKS(); INCREMENT(1);
00215 ADD_UP_BLOCKS(); INCREMENT(1);
00216 ADD_UP_BLOCKS(); INCREMENT(1);
00217 ADD_UP_BLOCKS();
00218
00219
00220 _bo = BlockSAD[list][refindex][5];
00221 _bi = BlockSAD[list][refindex][7];
00222 _bj = _bi + 1;
00223 ADD_UP_BLOCKS(); INCREMENT(2);
00224 ADD_UP_BLOCKS(); INCREMENT(2);
00225 ADD_UP_BLOCKS(); INCREMENT(2);
00226 ADD_UP_BLOCKS(); INCREMENT(2);
00227 ADD_UP_BLOCKS(); INCREMENT(2);
00228 ADD_UP_BLOCKS(); INCREMENT(2);
00229 ADD_UP_BLOCKS(); INCREMENT(2);
00230 ADD_UP_BLOCKS();
00231
00232
00233 _bo = BlockSAD[list][refindex][4];
00234 _bi = BlockSAD[list][refindex][6];
00235 _bj = _bi + 1;
00236 ADD_UP_BLOCKS(); INCREMENT(2);
00237 ADD_UP_BLOCKS(); INCREMENT(6);
00238 ADD_UP_BLOCKS(); INCREMENT(2);
00239 ADD_UP_BLOCKS();
00240
00241
00242 _bo = BlockSAD[list][refindex][3];
00243 _bi = BlockSAD[list][refindex][4];
00244 _bj = _bi + 8;
00245 ADD_UP_BLOCKS(); INCREMENT(2);
00246 ADD_UP_BLOCKS();
00247
00248
00249 _bo = BlockSAD[list][refindex][2];
00250 _bi = BlockSAD[list][refindex][4];
00251 _bj = _bi + 2;
00252 ADD_UP_BLOCKS(); INCREMENT(8);
00253 ADD_UP_BLOCKS();
00254
00255
00256 _bo = BlockSAD[list][refindex][1];
00257 _bi = BlockSAD[list][refindex][3];
00258 _bj = _bi + 2;
00259 ADD_UP_BLOCKS();
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 void SetupFastFullPelSearch (Macroblock *currMB, MEBlock *mv_block, int list)
00270 {
00271 Slice *currSlice = currMB->p_slice;
00272 ImageParameters *p_Img = currSlice->p_Img;
00273 InputParameters *p_Inp = currSlice->p_Inp;
00274 PicMotionParams *motion = &p_Img->enc_picture->motion;
00275 int (*dist_method) (int x) = p_Inp->MEErrorMetric[0] ? iabs2 : iabs;
00276 #if (JM_MEM_DISTORTION)
00277 int* imgpel_dist = p_Inp->MEErrorMetric[0] ? p_Img->imgpel_quad : p_Img->imgpel_abs;
00278 #endif
00279 short pmv[2];
00280 imgpel orig_pels[768];
00281 imgpel *srcptr = orig_pels, *refptr;
00282 int k, x, y;
00283 MotionVector cand, offset;
00284 int ref_x, ref_y, pos, bindex, blky;
00285 int LineSadBlk0, LineSadBlk1, LineSadBlk2, LineSadBlk3;
00286 PixelPos block[4];
00287 MEFullFast *p_me_ffast = p_Img->p_ffast_me;
00288
00289
00290 short ref = mv_block->ref_idx;
00291 distpel** block_sad = p_me_ffast->BlockSAD[list][ref][7];
00292 int search_range = p_me_ffast->max_search_range[list][ref];
00293 int max_pos = (2*search_range+1) * (2*search_range+1);
00294
00295 int list_offset = p_Img->mb_data[currMB->mbAddrX].list_offset;
00296 int apply_weights = ( (p_Img->active_pps->weighted_pred_flag && (currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE)) ||
00297 (p_Img->active_pps->weighted_bipred_idc && (currSlice->slice_type == B_SLICE))) && p_Inp->UseWeightedReferenceME;
00298 int weighted_pel;
00299 StorablePicture *ref_picture = p_Img->listX[list+list_offset][ref];
00300
00301 int wp_luma_round = 0;
00302 short luma_log_weight_denom = 5;
00303 short chroma_log_weight_denom = 5;
00304 int wp_chroma_round = 0;
00305 short weight_luma = mv_block->weight_luma, weight_cr[2];
00306 short offset_luma = mv_block->offset_luma, offset_cr[2];
00307 search_range <<= 2;
00308
00309
00310 get_neighbors(currMB, block, 0, 0, 16);
00311 currMB->GetMVPredictor (currMB, block, pmv, ref, motion->ref_idx[list], motion->mv[list], 0, 0, 16, 16);
00312
00313 #if (JM_INT_DIVIDE)
00314 p_Img->p_ffast_me->search_center[list][ref].mv_x = ((pmv[0] + 2) >> 2) * 4;
00315 p_Img->p_ffast_me->search_center[list][ref].mv_y = ((pmv[1] + 2) >> 2) * 4;
00316 #else
00317 p_Img->p_ffast_me->search_center[list][ref].mv_x = (pmv[0] / 4) * 4;
00318 p_Img->p_ffast_me->search_center[list][ref].mv_y = (pmv[1] / 4) * 4;
00319 #endif
00320 if (!p_Inp->rdopt)
00321 {
00322
00323 p_Img->p_ffast_me->search_center[list][ref].mv_x = (short) iClip3(-search_range, search_range, p_Img->p_ffast_me->search_center[list][ref].mv_x);
00324 p_Img->p_ffast_me->search_center[list][ref].mv_y = (short) iClip3(-search_range, search_range, p_Img->p_ffast_me->search_center[list][ref].mv_y);
00325 }
00326
00327 p_Img->p_ffast_me->search_center[list][ref].mv_x = (short) iClip3(p_Img->MaxHmvR[4] + search_range, p_Img->MaxHmvR[5] - search_range, p_Img->p_ffast_me->search_center[list][ref].mv_x);
00328 p_Img->p_ffast_me->search_center[list][ref].mv_y = (short) iClip3(p_Img->MaxVmvR[4] + search_range, p_Img->MaxVmvR[5] - search_range, p_Img->p_ffast_me->search_center[list][ref].mv_y);
00329
00330 p_Img->p_ffast_me->search_center_padded[list][ref] = pad_MVs(p_Img->p_ffast_me->search_center[list][ref], mv_block);
00331
00332 offset = p_Img->p_ffast_me->search_center_padded[list][ref];
00333
00334 for (y = currMB->opix_y; y < currMB->opix_y + MB_BLOCK_SIZE; y++)
00335 {
00336 memcpy(srcptr, &p_Img->pCurImg[y][currMB->pix_x], MB_BLOCK_SIZE * sizeof(imgpel));
00337 srcptr += MB_BLOCK_SIZE;
00338 }
00339
00340 if ( mv_block->ChromaMEEnable)
00341 {
00342 for (k = 1; k < 3; k++)
00343 {
00344 for (y = currMB->opix_c_y; y < currMB->opix_c_y + p_Img->mb_cr_size_y; y++)
00345 {
00346 memcpy(srcptr, &p_Img->pImgOrg[k][y][currMB->pix_c_x], p_Img->mb_cr_size_x * sizeof(imgpel));
00347 srcptr += p_Img->mb_cr_size_x;
00348 }
00349 }
00350 }
00351
00352
00353
00354 if (!p_Inp->rdopt)
00355 {
00356 ref_x = mv_block->pos_x_padded - offset.mv_x;
00357 ref_y = mv_block->pos_y_padded - offset.mv_y;
00358
00359 for (pos = 0; pos < max_pos; pos++)
00360 {
00361 if (ref_x == p_Img->spiral_qpel_search[pos].mv_x && ref_y == p_Img->spiral_qpel_search[pos].mv_y)
00362 {
00363 p_me_ffast->pos_00[list][ref] = pos;
00364 break;
00365 }
00366 }
00367 }
00368
00369
00370 if (apply_weights)
00371 {
00372 weight_luma = currSlice->wp_weight[list + list_offset][ref][0];
00373 offset_luma = currSlice->wp_offset[list + list_offset][ref][0];
00374 wp_luma_round = currSlice->wp_luma_round;
00375 luma_log_weight_denom = currSlice->luma_log_weight_denom;
00376 chroma_log_weight_denom = currSlice->chroma_log_weight_denom;
00377 wp_chroma_round = currSlice->wp_chroma_round;
00378
00379 if (mv_block->ChromaMEEnable)
00380 {
00381 weight_cr[0] = currSlice->wp_weight[list + list_offset][ref][1];
00382 weight_cr[1] = currSlice->wp_weight[list + list_offset][ref][2];
00383 offset_cr[0] = currSlice->wp_offset[list + list_offset][ref][1];
00384 offset_cr[1] = currSlice->wp_offset[list + list_offset][ref][2];
00385 }
00386
00387 for (pos = 0; pos < max_pos; pos++)
00388 {
00389 cand = add_MVs(offset, &p_Img->spiral_qpel_search[pos]);
00390
00391 srcptr = orig_pels;
00392 bindex = 0;
00393
00394 refptr = UMVLine4X (ref_picture, cand.mv_y, cand.mv_x);
00395
00396 for (blky = 0; blky < 4; blky++)
00397 {
00398 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00399
00400 for (y = 0; y < 4; y++)
00401 {
00402 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00403 LineSadBlk0 += dist_method (weighted_pel - *srcptr++);
00404 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00405 LineSadBlk0 += dist_method (weighted_pel - *srcptr++);
00406 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00407 LineSadBlk0 += dist_method (weighted_pel - *srcptr++);
00408 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00409 LineSadBlk0 += dist_method (weighted_pel - *srcptr++);
00410 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00411 LineSadBlk1 += dist_method (weighted_pel - *srcptr++);
00412 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00413 LineSadBlk1 += dist_method (weighted_pel - *srcptr++);
00414 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00415 LineSadBlk1 += dist_method (weighted_pel - *srcptr++);
00416 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00417 LineSadBlk1 += dist_method (weighted_pel - *srcptr++);
00418 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00419 LineSadBlk2 += dist_method (weighted_pel - *srcptr++);
00420 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00421 LineSadBlk2 += dist_method (weighted_pel - *srcptr++);
00422 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00423 LineSadBlk2 += dist_method (weighted_pel - *srcptr++);
00424 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00425 LineSadBlk2 += dist_method (weighted_pel - *srcptr++);
00426 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00427 LineSadBlk3 += dist_method (weighted_pel - *srcptr++);
00428 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00429 LineSadBlk3 += dist_method (weighted_pel - *srcptr++);
00430 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00431 LineSadBlk3 += dist_method (weighted_pel - *srcptr++);
00432 weighted_pel = iClip1( p_Img->max_imgpel_value, ((weight_luma * *refptr++ + wp_luma_round) >> luma_log_weight_denom) + offset_luma);
00433 LineSadBlk3 += dist_method (weighted_pel - *srcptr++);
00434 refptr += p_Img->padded_size_x - MB_BLOCK_SIZE;
00435 }
00436
00437 block_sad[bindex++][pos] = (distpel) LineSadBlk0;
00438 block_sad[bindex++][pos] = (distpel) LineSadBlk1;
00439 block_sad[bindex++][pos] = (distpel) LineSadBlk2;
00440 block_sad[bindex++][pos] = (distpel) LineSadBlk3;
00441 }
00442 if (mv_block->ChromaMEEnable)
00443 {
00444 int max_imgpel_value_uv = p_Img->max_pel_value_comp[1];
00445 for (k = 0; k < 2; k ++)
00446 {
00447 bindex = 0;
00448
00449 refptr = UMVLine8X_chroma (ref_picture, k+1, cand.mv_y, cand.mv_x);
00450 for (blky = 0; blky < 4; blky++)
00451 {
00452 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00453
00454 for (y = 0; y < p_Img->mb_cr_size_y; y+=BLOCK_SIZE)
00455 {
00456 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00457 {
00458 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00459 LineSadBlk0 += dist_method (weighted_pel - *srcptr++);
00460 }
00461 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00462 {
00463 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00464 LineSadBlk1 += dist_method (weighted_pel - *srcptr++);
00465 }
00466 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00467 {
00468 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00469 LineSadBlk2 += dist_method (weighted_pel - *srcptr++);
00470 }
00471 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00472 {
00473 weighted_pel = iClip1( max_imgpel_value_uv, ((weight_cr[k] * *refptr++ + wp_chroma_round) >> chroma_log_weight_denom) + offset_cr[k]);
00474 LineSadBlk3 += dist_method (weighted_pel - *srcptr++);
00475 }
00476 refptr += p_Img->cr_padded_size_x - p_Img->mb_cr_size_x;
00477 }
00478
00479 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk0);
00480 ++bindex;
00481 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk1);
00482 ++bindex;
00483 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk2);
00484 ++bindex;
00485 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk3);
00486 ++bindex;
00487 }
00488 }
00489 }
00490 }
00491 }
00492 else
00493 {
00494 for (pos = 0; pos < max_pos; pos++)
00495 {
00496 cand = add_MVs(offset, &p_Img->spiral_qpel_search[pos]);
00497 srcptr = orig_pels;
00498 bindex = 0;
00499
00500 refptr = UMVLine4X (ref_picture, cand.mv_y, cand.mv_x);
00501
00502 for (blky = 0; blky < 4; blky++)
00503 {
00504 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00505
00506 for (y = 0; y < 4; y++)
00507 {
00508 #if (JM_MEM_DISTORTION)
00509
00510 LineSadBlk0 += imgpel_dist[ *refptr++ - *srcptr++ ];
00511 LineSadBlk0 += imgpel_dist[ *refptr++ - *srcptr++ ];
00512 LineSadBlk0 += imgpel_dist[ *refptr++ - *srcptr++ ];
00513 LineSadBlk0 += imgpel_dist[ *refptr++ - *srcptr++ ];
00514
00515 LineSadBlk1 += imgpel_dist[ *refptr++ - *srcptr++ ];
00516 LineSadBlk1 += imgpel_dist[ *refptr++ - *srcptr++ ];
00517 LineSadBlk1 += imgpel_dist[ *refptr++ - *srcptr++ ];
00518 LineSadBlk1 += imgpel_dist[ *refptr++ - *srcptr++ ];
00519
00520 LineSadBlk2 += imgpel_dist[ *refptr++ - *srcptr++ ];
00521 LineSadBlk2 += imgpel_dist[ *refptr++ - *srcptr++ ];
00522 LineSadBlk2 += imgpel_dist[ *refptr++ - *srcptr++ ];
00523 LineSadBlk2 += imgpel_dist[ *refptr++ - *srcptr++ ];
00524
00525 LineSadBlk3 += imgpel_dist[ *refptr++ - *srcptr++ ];
00526 LineSadBlk3 += imgpel_dist[ *refptr++ - *srcptr++ ];
00527 LineSadBlk3 += imgpel_dist[ *refptr++ - *srcptr++ ];
00528 LineSadBlk3 += imgpel_dist[ *refptr++ - *srcptr++ ];
00529 #else
00530
00531 LineSadBlk0 += dist_method (*refptr++ - *srcptr++);
00532 LineSadBlk0 += dist_method (*refptr++ - *srcptr++);
00533 LineSadBlk0 += dist_method (*refptr++ - *srcptr++);
00534 LineSadBlk0 += dist_method (*refptr++ - *srcptr++);
00535
00536 LineSadBlk1 += dist_method (*refptr++ - *srcptr++);
00537 LineSadBlk1 += dist_method (*refptr++ - *srcptr++);
00538 LineSadBlk1 += dist_method (*refptr++ - *srcptr++);
00539 LineSadBlk1 += dist_method (*refptr++ - *srcptr++);
00540
00541 LineSadBlk2 += dist_method (*refptr++ - *srcptr++);
00542 LineSadBlk2 += dist_method (*refptr++ - *srcptr++);
00543 LineSadBlk2 += dist_method (*refptr++ - *srcptr++);
00544 LineSadBlk2 += dist_method (*refptr++ - *srcptr++);
00545
00546 LineSadBlk3 += dist_method (*refptr++ - *srcptr++);
00547 LineSadBlk3 += dist_method (*refptr++ - *srcptr++);
00548 LineSadBlk3 += dist_method (*refptr++ - *srcptr++);
00549 LineSadBlk3 += dist_method (*refptr++ - *srcptr++);
00550 #endif
00551
00552 refptr += p_Img->padded_size_x - MB_BLOCK_SIZE;
00553 }
00554
00555 block_sad[bindex++][pos] = (distpel) LineSadBlk0;
00556 block_sad[bindex++][pos] = (distpel) LineSadBlk1;
00557 block_sad[bindex++][pos] = (distpel) LineSadBlk2;
00558 block_sad[bindex++][pos] = (distpel) LineSadBlk3;
00559 }
00560
00561 if (mv_block->ChromaMEEnable)
00562 {
00563 for (k = 0; k < 2; k ++)
00564 {
00565 bindex = 0;
00566
00567 refptr = UMVLine8X_chroma (ref_picture, k+1, cand.mv_y, cand.mv_x);
00568 for (blky = 0; blky < 4; blky++)
00569 {
00570 LineSadBlk0 = LineSadBlk1 = LineSadBlk2 = LineSadBlk3 = 0;
00571
00572 for (y = 0; y < p_Img->mb_cr_size_y; y+=BLOCK_SIZE)
00573 {
00574 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00575 {
00576 LineSadBlk0 += dist_method (*refptr++ - *srcptr++);
00577 }
00578 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00579 {
00580 LineSadBlk1 += dist_method (*refptr++ - *srcptr++);
00581 }
00582 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00583 {
00584 LineSadBlk2 += dist_method (*refptr++ - *srcptr++);
00585 }
00586 for (x = 0; x < p_Img->mb_cr_size_x; x += BLOCK_SIZE)
00587 {
00588 LineSadBlk3 += dist_method (*refptr++ - *srcptr++);
00589 }
00590 refptr += p_Img->cr_padded_size_x - p_Img->mb_cr_size_x;
00591 }
00592 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk0);
00593 ++bindex;
00594 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk1);
00595 ++bindex;
00596 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk2);
00597 ++bindex;
00598 block_sad[bindex][pos] = block_sad[bindex][pos] + ((distpel) LineSadBlk3);
00599 ++bindex;
00600 }
00601 }
00602 }
00603 }
00604 }
00605
00606
00607 SetupLargerBlocks (p_Img->p_ffast_me, list, ref, max_pos);
00608
00609
00610 p_Img->p_ffast_me->search_setup_done[list][ref] = 1;
00611 }
00612
00613
00614
00615
00616
00617
00618
00619
00620 int
00621 FastFullPelBlockMotionSearch (Macroblock *currMB,
00622 MotionVector *pred_mv,
00623 MEBlock *mv_block,
00624 int min_mcost,
00625 int lambda_factor
00626 )
00627 {
00628 ImageParameters *p_Img = currMB->p_Img;
00629 InputParameters *p_Inp = currMB->p_Inp;
00630 MEFullFast *p_me_ffast = p_Img->p_ffast_me;
00631
00632 int pos, mcost;
00633 int search_range = mv_block->searchRange.max_x >> 2;
00634 int max_pos = (2*search_range+1)*(2*search_range+1);
00635 int best_pos = 0;
00636 int block_index;
00637 distpel* block_sad;
00638 int list = mv_block->list;
00639 short ref = mv_block->ref_idx;
00640 MotionVector cand = {0, 0}, *offset = &p_Img->p_ffast_me->search_center[list][ref];
00641
00642 block_index = (mv_block->block_y << 2) + (mv_block->block_x);
00643 block_sad = p_me_ffast->BlockSAD[list][ref][mv_block->blocktype][block_index];
00644
00645
00646 if (!p_Img->p_ffast_me->search_setup_done[list][ref])
00647 {
00648 SetupFastFullPelSearch (currMB, mv_block, list);
00649 }
00650
00651
00652
00653 if (!p_Inp->rdopt)
00654 {
00655 min_mcost = block_sad[p_me_ffast->pos_00[list][ref]] + mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00656
00657 best_pos = p_me_ffast->pos_00[list][ref];
00658 }
00659
00660
00661 for (pos=0; pos<max_pos; pos++, block_sad++)
00662 {
00663
00664 if ((int) *block_sad < min_mcost)
00665 {
00666
00667 cand = add_MVs (p_Img->spiral_qpel_search[pos], offset);
00668
00669 mcost = *block_sad;
00670 mcost += mv_cost (p_Img, lambda_factor, &cand, pred_mv);
00671
00672
00673 if (mcost < min_mcost)
00674 {
00675 min_mcost = mcost;
00676 best_pos = pos;
00677 }
00678 }
00679 }
00680
00681
00682 mv_block->mv[list] = add_MVs (p_Img->spiral_qpel_search[best_pos], offset);
00683
00684 return min_mcost;
00685 }
00686