00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "mot_util.h"
00042
00043
00044 #define ABSDOUBLE(x) (((x) > 0.0001) ? (x) : (((x) < -0.0001) ? -(x): 0.0 ))
00045 #define ARE_EQUAL(x,y) ( (ABSDOUBLE((Float)(x)-(y))>0.1)?(0):(1) )
00046
00047
00048 #define INDEX_BIG(x,y) ((x)+(y)*(vop_width))
00049 #define INDEX_NOR(x,y) ((x)+(y)*(MB_SIZE))
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 static Void
00064 RangeInSearchArea(
00065 Int i,
00066 Int j,
00067 Int block,
00068 Int prev_x,
00069 Int prev_y,
00070 Int vop_width,
00071 Int vop_height,
00072 Int br_x,
00073 Int br_y,
00074 Int edge,
00075 Int f_code,
00076 Float *mv_x_min,
00077 Float *mv_x_max,
00078 Float *mv_y_min,
00079 Float *mv_y_max,
00080 Int *out
00081 )
00082 {
00083 Int dim_curr_x_max,
00084 dim_curr_y_max,
00085 dim_curr_x_min,
00086 dim_curr_y_min;
00087 Int dim_prev_x_max,
00088 dim_prev_y_max,
00089 dim_prev_x_min,
00090 dim_prev_y_min;
00091 Int mb_b_size,
00092 block_x,
00093 block_y;
00094
00095 *out=0;
00096
00097 switch (block)
00098 {
00099 case 0:
00100 block_x=0;
00101 block_y=0;
00102 mb_b_size=MB_SIZE;
00103 break;
00104 case 1:
00105 block_x=0;
00106 block_y=0;
00107 mb_b_size=B_SIZE;
00108 break;
00109 case 2:
00110 block_x=B_SIZE;
00111 block_y=0;
00112 mb_b_size=B_SIZE;
00113 break;
00114 case 3:
00115 block_x=0;
00116 block_y=B_SIZE;
00117 mb_b_size=B_SIZE;
00118 break;
00119 case 4:
00120 block_x=B_SIZE;
00121 block_y=B_SIZE;
00122 mb_b_size=B_SIZE;
00123 break;
00124 default:
00125 return;
00126 }
00127
00128
00129 dim_curr_x_min=(Int)(br_x+i*MB_SIZE+*mv_x_min+block_x);
00130 dim_curr_y_min=(Int)(br_y+j*MB_SIZE+*mv_y_min+block_y);
00131 dim_prev_x_min=prev_x;
00132 dim_prev_y_min=prev_y;
00133
00134
00135
00136 dim_curr_x_max=(Int)(br_x+i*MB_SIZE+*mv_x_max+mb_b_size+block_x);
00137
00138 dim_curr_y_max=(Int)(br_y+j*MB_SIZE+*mv_y_max+mb_b_size+block_y);
00139 dim_prev_x_max=prev_x+vop_width ;
00140 dim_prev_y_max=prev_y+vop_height;
00141
00142
00143
00144 if (dim_curr_x_min > dim_prev_x_max)
00145 {
00146 *out=1;
00147 }
00148 else if(dim_curr_x_min < dim_prev_x_min)
00149 {
00150 *mv_x_min = *mv_x_min + ( dim_prev_x_min - dim_curr_x_min ) ;
00151 }
00152
00153 if(!(*out))
00154 {
00155 if (dim_curr_y_min > dim_prev_y_max)
00156 {
00157 *out=1;
00158 }
00159 else if(dim_curr_y_min < dim_prev_y_min)
00160 {
00161 *mv_y_min = *mv_y_min + ( dim_prev_y_min - dim_curr_y_min ) ;
00162 }
00163 }
00164
00165
00166 if(!(*out))
00167 {
00168 if(dim_curr_x_max < dim_prev_x_min)
00169 {
00170 *out=1;
00171 }
00172 if ((!(*out))&&(dim_curr_x_max > dim_prev_x_max))
00173 {
00174 *mv_x_max = *mv_x_max - ( dim_curr_x_max - dim_prev_x_max) ;
00175 }
00176 }
00177
00178 if(!(*out))
00179 {
00180 if(dim_curr_y_max < dim_prev_y_min)
00181 {
00182 *out=1;
00183 }
00184 if ((!(*out))&&(dim_curr_y_max > dim_prev_y_max))
00185 {
00186 *mv_y_max = *mv_y_max - ( dim_curr_y_max - dim_prev_y_max) ;
00187 }
00188 }
00189
00190 if(*mv_x_min>*mv_x_max)
00191 {
00192 *out=1;
00193 }
00194
00195 if ( (!(*out)) && (*mv_y_min>*mv_y_max))
00196 {
00197 *out=1;
00198 }
00199
00200 return;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 static Int
00219 Obtain_Range(
00220 Int f_code,
00221 Int sr,
00222 Int type,
00223 Float pmv_x,
00224 Float pmv_y,
00225 Float *mv_x_min,
00226 Float *mv_x_max,
00227 Float *mv_y_min,
00228 Float *mv_y_max,
00229 Int quarter_pel
00230 )
00231 {
00232 Int error;
00233
00234 Float aux_x_min, aux_y_min,
00235 aux_x_max, aux_y_max;
00236
00237 Float range;
00238
00239 error=0;
00240
00241 if ((f_code==0) && (!quarter_pel))
00242 {
00243 *mv_x_min=0;
00244 *mv_x_max=0;
00245 *mv_y_min=0;
00246 *mv_y_max=0;
00247 }
00248 else
00249 {
00250 range = sr;
00251
00252 *mv_x_min=-range; *mv_x_max= range - 0.5f;
00253
00254 *mv_y_min=-range; *mv_y_max= range - 0.5f;
00255 }
00256
00257 if (type==MBM_INTER8)
00258 {
00259 aux_x_min=pmv_x - DEFAULT_8_WIN;
00260 aux_y_min=pmv_y - DEFAULT_8_WIN;
00261 aux_x_max=pmv_x + DEFAULT_8_WIN;
00262 aux_y_max=pmv_y + DEFAULT_8_WIN;
00263
00264 if(*mv_x_min < aux_x_min)
00265 *mv_x_min = aux_x_min;
00266 if(*mv_y_min < aux_y_min)
00267 *mv_y_min = aux_y_min;
00268 if(*mv_x_max > aux_x_max)
00269 *mv_x_max = aux_x_max;
00270 if(*mv_y_max > aux_y_max)
00271 *mv_y_max = aux_y_max;
00272 }
00273
00274 if (error==1)
00275 return(0);
00276 else
00277 return(1);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 Void
00294 MBMotionEstimation(
00295 SInt *curr,
00296 SInt *prev,
00297 Int br_x,
00298 Int br_y,
00299 Int br_width,
00300 Int i,
00301 Int j,
00302 Int prev_x,
00303 Int prev_y,
00304 Int vop_width,
00305 Int vop_height,
00306 Int enable_8x8_mv,
00307 Int edge,
00308 Int f_code,
00309 Int sr,
00310 Float hint_mv_w,
00311 Float hint_mv_h,
00312 Float *mv16_w,
00313 Float *mv16_h,
00314 Float *mv8_w,
00315 Float *mv8_h,
00316 Int *min_error,
00317 SInt *flags
00318 )
00319 {
00320 Int x, y;
00321 Int sad, sad_min=MV_MAX_ERROR;
00322 Int mv_x, mv_y;
00323 Int block;
00324 Float pmv_x, pmv_y;
00325 SInt act_block[MB_SIZE*MB_SIZE];
00326
00327 Float mv_x_min, mv_x_max,
00328 mv_y_min, mv_y_max;
00329 Int int_mv_x_min=0, int_mv_x_max=0,
00330 int_mv_y_min=0, int_mv_y_max=0;
00331
00332 Int pos16, pos8;
00333 Int mvm_width = br_width/MB_SIZE;
00334
00335 Int x_curr = i*MB_SIZE,
00336 y_curr = j*MB_SIZE;
00337 Int hb,vb;
00338 Int out;
00339
00340 Int rel_ori_x;
00341 Int rel_ori_y;
00342
00343 Int min_error16, min_error8 = 0;
00344
00345 #ifndef _FULL_SEARCH_
00346 typedef struct
00347 {
00348 Int x;
00349 Int y;
00350 SInt start_nmbr;
00351 } DPoint;
00352
00353 typedef struct
00354 {
00355 DPoint point[8];
00356 } Diamond;
00357
00358 SInt d_type=1,stop_flag=0,pt_nmbr=0,check_pts,total_check_pts=8,mot_dirn=0;
00359 Int d_centre_x=0,d_centre_y=0,check_pt_x,check_pt_y;
00360 Diamond diamond[2]=
00361 {
00362 {
00363 { {0,1,0}, {1,0,0}, {0,-1,0}, {-1,0,0} }
00364 }
00365 ,
00366 {
00367 { {0,2,6}, {1,1,0}, {2,0,0}, {1,-1,2},
00368 {0,-2,2}, {-1,-1,4}, {-2,0,4}, {-1,1,6} }
00369 }
00370 };
00371 #endif
00372
00373 d_centre_x = (int)hint_mv_w;
00374 d_centre_y = (int)hint_mv_h;
00375
00376 rel_ori_x=br_x-prev_x;
00377 rel_ori_y=br_y-prev_y;
00378
00379
00380
00381 LoadArea(curr, x_curr,y_curr,MB_SIZE,MB_SIZE,br_width, act_block);
00382
00383
00384
00385
00386
00387 Obtain_Range (f_code, sr, MBM_INTER16,
00388 0.0, 0.0, &mv_x_min, &mv_x_max,
00389
00390 &mv_y_min, &mv_y_max, 0);
00391
00392 RangeInSearchArea (i,j,0, prev_x, prev_y, vop_width, vop_height,
00393 br_x, br_y, edge,f_code, &mv_x_min, &mv_x_max,
00394
00395 &mv_y_min, &mv_y_max,&out);
00396
00397
00398
00399 if(!out)
00400 {
00401 int_mv_x_min=(int)ceil((double)mv_x_min);
00402 int_mv_y_min=(int)ceil((double)mv_y_min);
00403 int_mv_x_max=(int)floor((double)mv_x_max);
00404 int_mv_y_max=(int)floor((double)mv_y_max);
00405 flags[0]=ARE_EQUAL(int_mv_x_min,mv_x_min);
00406 flags[1]=ARE_EQUAL(int_mv_x_max,mv_x_max);
00407 flags[2]=ARE_EQUAL(int_mv_y_min,mv_y_min);
00408 flags[3]=ARE_EQUAL(int_mv_y_max,mv_y_max);
00409
00410 sad_min=MV_MAX_ERROR;
00411 mv_x = mv_y = 2000;
00412
00413 #ifdef _FULL_SEARCH_
00414 for (y=int_mv_y_min; y<=int_mv_y_max; y++)
00415 for (x=int_mv_x_min; x<=int_mv_x_max; x++)
00416 {
00417 if (x==0 && y==0)
00418 sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+rel_ori_x,
00419 y_curr+rel_ori_y), act_block,
00420 (vop_width), MV_MAX_ERROR)
00421 - (128 + 1);
00422 else
00423 sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+x+rel_ori_x,
00424 y_curr+y+rel_ori_y), act_block,
00425 (vop_width), sad_min);
00426
00427 if (sad<sad_min)
00428 {
00429 sad_min=sad;
00430 mv_x=x;
00431 mv_y=y;
00432 }
00433 else if (sad==sad_min)
00434 if((ABS(x)+ABS(y)) < (ABS(mv_x)+ABS(mv_y)))
00435 {
00436 sad_min=sad;
00437 mv_x=x;
00438 mv_y=y;
00439 }
00440 }
00441 #else
00442 sad = SAD_Macroblock(prev+INDEX_BIG(x_curr+rel_ori_x,
00443 y_curr+rel_ori_y), act_block, (vop_width), MV_MAX_ERROR)
00444 - (128 + 1);
00445 if (sad<sad_min)
00446 {
00447 sad_min=sad;
00448 mv_x = mv_y = 0;
00449 }
00450 do
00451 {
00452 check_pts=total_check_pts;
00453
00454 do
00455 {
00456 check_pt_x = diamond[d_type].point[pt_nmbr].x + d_centre_x;
00457 check_pt_y = diamond[d_type].point[pt_nmbr].y + d_centre_y;
00458
00459
00460 if ( check_pt_x < int_mv_x_min || check_pt_x > int_mv_x_max || check_pt_y < int_mv_y_min || check_pt_y > int_mv_y_max)
00461 {
00462 sad = MV_MAX_ERROR;
00463 }
00464 else
00465 {
00466 sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+check_pt_x+rel_ori_x,
00467 y_curr+check_pt_y+rel_ori_y), act_block,
00468 (vop_width), sad_min);
00469 #ifdef _SAD_EXHAUS_
00470 fprintf(stdout,"+o+ [%2d,%2d] sad16(%3d,%3d)=%4d\n",i,j,x,y,sad);
00471 #endif
00472 }
00473 if (sad<sad_min)
00474 {
00475 sad_min=sad;
00476 mv_x=check_pt_x;
00477 mv_y=check_pt_y;
00478 mot_dirn=pt_nmbr;
00479 }
00480 else if (sad==sad_min)
00481 if((ABS(check_pt_x)+ABS(check_pt_y)) < (ABS(mv_x)+ABS(mv_y)))
00482 {
00483 sad_min=sad;
00484 mv_x=check_pt_x;
00485 mv_y=check_pt_y;
00486 mot_dirn=pt_nmbr;
00487 }
00488
00489 pt_nmbr+=1;
00490 if((pt_nmbr)>= 8) pt_nmbr-=8;
00491 check_pts-=1;
00492 }
00493 while(check_pts>0);
00494
00495 if( d_type == 0)
00496 {
00497 stop_flag = 1;
00498
00499 }
00500 else
00501 {
00502 if( (mv_x == d_centre_x) && (mv_y == d_centre_y) )
00503 {
00504 d_type=0;
00505 pt_nmbr=0;
00506 total_check_pts = 4;
00507 }
00508 else
00509 {
00510 if((mv_x==d_centre_x) ||(mv_y==d_centre_y))
00511 total_check_pts=5;
00512 else
00513 total_check_pts=3;
00514 pt_nmbr=diamond[d_type].point[mot_dirn].start_nmbr;
00515 d_centre_x = mv_x;
00516 d_centre_y = mv_y;
00517
00518 }
00519 }
00520 }
00521 while(stop_flag!=1);
00522 #endif
00523
00524 flags[0]=flags[0] && (mv_x==int_mv_x_min);
00525 flags[1]=flags[1] && (mv_x==int_mv_x_max);
00526 flags[2]=flags[2] && (mv_y==int_mv_y_min);
00527 flags[3]=flags[3] && (mv_y==int_mv_y_max);
00528 }
00529 else
00530 {
00531 mv_x=mv_y=0;
00532 sad_min=MV_MAX_ERROR;
00533 }
00534
00535
00536
00537 out |=((mv_x==2000)||(mv_y==2000));
00538 if(out)
00539 {
00540 mv_x=mv_y=0;
00541 sad_min=MV_MAX_ERROR;
00542 }
00543
00544 pos16=2*j*2*mvm_width + 2*i;
00545 mv16_w[pos16]= mv_x; mv16_h[pos16]= mv_y;
00546 mv16_w[pos16+1]= mv_x; mv16_h[pos16+1]= mv_y;
00547 pos16+=2*mvm_width;
00548 mv16_w[pos16]= mv_x; mv16_h[pos16]= mv_y;
00549 mv16_w[pos16+1]= mv_x; mv16_h[pos16+1]= mv_y;
00550 min_error16 = sad_min;
00551
00552 *min_error = min_error16;
00553
00554
00555
00556 if(enable_8x8_mv==1)
00557 {
00558 if(!out)
00559 {
00560 for (block=0;block<4;block++)
00561 {
00562
00563 if(block==0)
00564 {
00565 hb=vb=0;
00566 }
00567 else if (block==1)
00568 {
00569 hb=1;vb=0;
00570 }
00571 else if (block==2)
00572 {
00573 hb=0;vb=1;
00574 }
00575 else
00576 {
00577 hb=vb=1;
00578 }
00579
00580
00581
00582
00583
00584 pmv_x=mv16_w[pos16]; pmv_y=mv16_h[pos16];
00585
00586
00587 Obtain_Range(f_code, sr, MBM_INTER8,
00588 pmv_x, pmv_y, &mv_x_min,
00589
00590 &mv_x_max, &mv_y_min, &mv_y_max, 0 );
00591
00592 RangeInSearchArea(i,j, block+1, prev_x, prev_y,
00593 vop_width, vop_height, br_x, br_y, edge,f_code,
00594
00595 &mv_x_min, &mv_x_max, &mv_y_min,&mv_y_max,&out);
00596
00597 if(!out)
00598 {
00599 int_mv_x_min=(int)ceil((double)mv_x_min);
00600 int_mv_y_min=(int)ceil((double)mv_y_min);
00601 int_mv_x_max=(int)floor((double)mv_x_max);
00602 int_mv_y_max=(int)floor((double)mv_y_max);
00603 flags[4+block*4]=ARE_EQUAL(int_mv_x_min,mv_x_min);
00604 flags[4+block*4+1]=ARE_EQUAL(int_mv_x_max,mv_x_max);
00605 flags[4+block*4+2]=ARE_EQUAL(int_mv_y_min,mv_y_min);
00606 flags[4+block*4+3]=ARE_EQUAL(int_mv_y_max,mv_y_max);
00607
00608 sad_min=MV_MAX_ERROR;
00609 mv_x = mv_y = 2000;
00610
00611 for (y=int_mv_y_min; y<=int_mv_y_max; y++)
00612 for (x=int_mv_x_min; x<=int_mv_x_max; x++)
00613 {
00614 sad=SAD_Block(prev+
00615 INDEX_BIG(x_curr + x + 8*(block==1||block==3)+rel_ori_x,
00616 y_curr + y + 8*(block==2||block==3)+rel_ori_y),
00617 act_block+INDEX_NOR(8*(block==1||block==3),
00618 8*(block==2||block==3)),
00619 (vop_width ), sad_min);
00620
00621 if (sad<sad_min)
00622 {
00623 sad_min=sad;
00624 mv_x=x;
00625 mv_y=y;
00626 }
00627 else if (sad==sad_min)
00628 if((ABS(x)+ABS(y)) < (ABS(mv_x)+ABS(mv_y)))
00629 {
00630 sad_min=sad;
00631 mv_x=x;
00632 mv_y=y;
00633 }
00634 }
00635
00636 flags[4+block*4] = flags[4+block*4] && (mv_x==int_mv_x_min);
00637 flags[4+block*4+1] = flags[4+block*4+1] && (mv_x==int_mv_x_max);
00638 flags[4+block*4+2] = flags[4+block*4+2] && (mv_y==int_mv_y_min);
00639 flags[4+block*4+3] = flags[4+block*4+3] && (mv_y==int_mv_y_max);
00640 }
00641 else
00642 {
00643 mv_x=mv_y=0;
00644 sad_min=MV_MAX_ERROR;
00645
00646
00647 }
00648
00649
00650
00651 if(block==0)
00652 {
00653 pos8=2*j*2*mvm_width + 2*i;
00654 min_error8 += sad_min;
00655 }
00656 else if (block==1)
00657 {
00658 pos8=2*j*2*mvm_width + 2*i+1;
00659 min_error8 += sad_min;
00660 }
00661 else if (block==2)
00662 {
00663 pos8=(2*j+1)*2*mvm_width + 2*i;
00664 min_error8 += sad_min;
00665 }
00666 else
00667 {
00668 pos8=(2*j+1)*2*mvm_width + 2*i+1;
00669 min_error8 += sad_min;
00670 }
00671
00672
00673
00674 mv8_w[pos8]=mv_x;
00675 mv8_h[pos8]=mv_y;
00676 }
00677
00678 if (min_error8 < *min_error)
00679 *min_error = min_error8;
00680 }
00681 else
00682 {
00683 pos8=2*j*2*mvm_width + 2*i; mv8_w[pos8]=mv8_h[pos8]=0.0;
00684 pos8=2*j*2*mvm_width + 2*i+1; mv8_w[pos8]=mv8_h[pos8]=0.0;
00685 pos8=(2*j+1)*2*mvm_width + 2*i; mv8_w[pos8]=mv8_h[pos8]=0.0;
00686 pos8=(2*j+1)*2*mvm_width + 2*i+1;mv8_w[pos8]=mv8_h[pos8]=0.0;
00687 min_error8 = MV_MAX_ERROR;
00688 }
00689 }
00690
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 Void
00709 FindSubPel(
00710 Int x,
00711 Int y,
00712 SInt *prev,
00713 SInt *curr,
00714 Int bs_x,
00715 Int bs_y,
00716 Int comp,
00717 Int rel_x,
00718 Int rel_y,
00719 Int pels,
00720 Int lines,
00721 Int edge,
00722 SInt *flags,
00723 SInt *curr_comp_mb,
00724 Float *mvx,
00725 Float *mvy,
00726 Int *min_error
00727 )
00728 {
00729 static PixPoint search[9] =
00730 {
00731 {0, 0}, {-1, -1}, {0, -1}, {1, -1},
00732 {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}
00733 };
00734
00735
00736
00737
00738
00739
00740 Int i, m, n;
00741 Int new_x, new_y,
00742 lx, size_x;
00743 Int min_pos;
00744 Int AE, AE_min;
00745 Int flag_pos;
00746 SInt *pRef, *pComp;
00747
00748 int flag_search[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
00749
00750 Int SubDimension = 2;
00751
00752 lx = 2*(pels );
00753
00754 new_x = (Int)((x + *mvx + rel_x)*(SubDimension));
00755 new_y = (Int)((y + *mvy + rel_y)*(SubDimension));
00756 new_x += ((comp&1)<<3)*SubDimension;
00757 new_y += ((comp&2)<<2)*SubDimension;
00758
00759 size_x=16;
00760
00765
00766
00767
00768
00769
00770 if (bs_x==8)
00771 flag_pos=4+comp*4;
00772 else
00773 flag_pos=0;
00774
00775 if (((new_x/SubDimension) <= 0) || *(flags+flag_pos)) {
00776 flag_search[1] = flag_search[4] = flag_search[6] = 0;
00777 } else if (((new_x/SubDimension) >= (pels - bs_x )) || *(flags+flag_pos+1)) {
00778 flag_search[3] = flag_search[5] = flag_search[8] = 0;
00779 };
00780
00781 if (((new_y/SubDimension) <= 0) || *(flags+flag_pos+2)) {
00782 flag_search[1] = flag_search[2] = flag_search[3] = 0;
00783 } else if (((new_y/SubDimension) >= (lines- bs_y )) || *(flags+flag_pos+3)) {
00784 flag_search[6] = flag_search[7] = flag_search[8] = 0;
00785 };
00786
00787 AE_min = MV_MAX_ERROR;
00788 min_pos = 0;
00789 for (i = 0; i < 9; i++)
00790 {
00791 if (flag_search[i])
00792 {
00793 AE = 0;
00794
00795 pRef = prev + new_x + search[i].x + (new_y + search[i].y) * lx;
00796 pComp = curr;
00797
00798 n = bs_y;
00799 while (n--) {
00800 m = bs_x;
00801
00802
00803
00804 while (m--) {
00805 AE += abs((Int)*pRef - (Int)*pComp);
00806 pRef += 2;
00807 pComp ++;
00808 }
00809
00810
00811
00812
00813
00814 pRef += 2 * lx - 2 * bs_x;
00815 pComp += size_x - bs_x;
00816 }
00817
00818 if (i==0 && bs_y==16 && *mvx==0 && *mvy==0)
00819 AE -= (128 + 1);
00820
00821 if (AE < AE_min)
00822 {
00823 AE_min = AE;
00824 min_pos = i;
00825 }
00826 }
00827
00828 }
00829
00830
00831 *min_error = AE_min;
00832 *mvx += ((Float)search[min_pos].x)/(Float)(SubDimension);
00833 *mvy += ((Float)search[min_pos].y)/(Float)(SubDimension);
00834
00835
00836 pRef = prev + new_x + search[min_pos].x + (new_y + search[min_pos].y) * lx;
00837 pComp = curr_comp_mb;
00838
00839 n = bs_y;
00840 while (n--) {
00841 m = bs_x;
00842 while (m--) {
00843 *(pComp ++) = *pRef;
00844 pRef += 2;
00845 }
00846 pRef += 2 * lx - 2 * bs_x;
00847 pComp += 16 - bs_x;
00848 }
00849
00850 return;
00851 }
00852
00853