mot_est_mb.c
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:15k
- #include "mot_util.h"
- #define ABSDOUBLE(x) (((x) > 0.0001) ? (x) : (((x) < -0.0001) ? -(x): 0.0 ))
- #define ARE_EQUAL(x,y) ( (ABSDOUBLE((Float)(x)-(y))>0.1)?(0):(1) )
- #define INDEX_BIG(x,y) ((x)+(y)*(vop_width))
- #define INDEX_NOR(x,y) ((x)+(y)*(MB_SIZE))
- static Void
- RangeInSearchArea(
- Int i,
- Int j,
- Int block,
- Int prev_x,
- Int prev_y,
- Int vop_width,
- Int vop_height,
- Int br_x,
- Int br_y,
- Int edge,
- Int f_code,
- Float *mv_x_min,
- Float *mv_x_max,
- Float *mv_y_min,
- Float *mv_y_max,
- Int *out
- )
- {
- Int dim_curr_x_max,
- dim_curr_y_max,
- dim_curr_x_min,
- dim_curr_y_min;
- Int dim_prev_x_max,
- dim_prev_y_max,
- dim_prev_x_min,
- dim_prev_y_min;
- Int mb_b_size,
- block_x,
- block_y;
- *out=0;
- switch (block)
- {
- case 0:
- block_x=0;
- block_y=0;
- mb_b_size=MB_SIZE;
- break;
- case 1:
- block_x=0;
- block_y=0;
- mb_b_size=B_SIZE;
- break;
- case 2:
- block_x=B_SIZE;
- block_y=0;
- mb_b_size=B_SIZE;
- break;
- case 3:
- block_x=0;
- block_y=B_SIZE;
- mb_b_size=B_SIZE;
- break;
- case 4:
- block_x=B_SIZE;
- block_y=B_SIZE;
- mb_b_size=B_SIZE;
- break;
- default:
- return;
- }
-
- dim_curr_x_min=(Int)(br_x+i*MB_SIZE+*mv_x_min+block_x);
- dim_curr_y_min=(Int)(br_y+j*MB_SIZE+*mv_y_min+block_y);
- dim_prev_x_min=prev_x;
- dim_prev_y_min=prev_y;
-
-
- dim_curr_x_max=(Int)(br_x+i*MB_SIZE+*mv_x_max+mb_b_size+block_x);
-
- dim_curr_y_max=(Int)(br_y+j*MB_SIZE+*mv_y_max+mb_b_size+block_y);
- dim_prev_x_max=prev_x+vop_width ;
- dim_prev_y_max=prev_y+vop_height;
-
- if (dim_curr_x_min > dim_prev_x_max)
- {
- *out=1;
- }
- else if(dim_curr_x_min < dim_prev_x_min)
- {
- *mv_x_min = *mv_x_min + ( dim_prev_x_min - dim_curr_x_min ) ;
- }
- if(!(*out))
- {
- if (dim_curr_y_min > dim_prev_y_max)
- {
- *out=1;
- }
- else if(dim_curr_y_min < dim_prev_y_min)
- {
- *mv_y_min = *mv_y_min + ( dim_prev_y_min - dim_curr_y_min ) ;
- }
- }
-
- if(!(*out))
- {
- if(dim_curr_x_max < dim_prev_x_min)
- {
- *out=1;
- }
- if ((!(*out))&&(dim_curr_x_max > dim_prev_x_max))
- {
- *mv_x_max = *mv_x_max - ( dim_curr_x_max - dim_prev_x_max) ;
- }
- }
- if(!(*out))
- {
- if(dim_curr_y_max < dim_prev_y_min)
- {
- *out=1;
- }
- if ((!(*out))&&(dim_curr_y_max > dim_prev_y_max))
- {
- *mv_y_max = *mv_y_max - ( dim_curr_y_max - dim_prev_y_max) ;
- }
- }
- if(*mv_x_min>*mv_x_max)
- {
- *out=1;
- }
- if ( (!(*out)) && (*mv_y_min>*mv_y_max))
- {
- *out=1;
- }
- return;
- }
- static Int
- Obtain_Range(
- Int f_code,
- Int sr,
- Int type,
- Float pmv_x,
- Float pmv_y,
- Float *mv_x_min,
- Float *mv_x_max,
- Float *mv_y_min,
- Float *mv_y_max,
- Int quarter_pel
- )
- {
- Int error;
- Float aux_x_min, aux_y_min,
- aux_x_max, aux_y_max;
- Float range;
- error=0;
- if ((f_code==0) && (!quarter_pel))
- {
- *mv_x_min=0;
- *mv_x_max=0;
- *mv_y_min=0;
- *mv_y_max=0;
- }
- else
- {
- range = sr;
- *mv_x_min=-range; *mv_x_max= range - 0.5f;
- *mv_y_min=-range; *mv_y_max= range - 0.5f;
- }
- if (type==MBM_INTER8)
- {
- aux_x_min=pmv_x - DEFAULT_8_WIN;
- aux_y_min=pmv_y - DEFAULT_8_WIN;
- aux_x_max=pmv_x + DEFAULT_8_WIN;
- aux_y_max=pmv_y + DEFAULT_8_WIN;
- if(*mv_x_min < aux_x_min)
- *mv_x_min = aux_x_min;
- if(*mv_y_min < aux_y_min)
- *mv_y_min = aux_y_min;
- if(*mv_x_max > aux_x_max)
- *mv_x_max = aux_x_max;
- if(*mv_y_max > aux_y_max)
- *mv_y_max = aux_y_max;
- }
- if (error==1)
- return(0);
- else
- return(1);
- }
- Void
- MBMotionEstimation(
- SInt *curr,
- SInt *prev,
- Int br_x,
- Int br_y,
- Int br_width,
- Int i,
- Int j,
- Int prev_x,
- Int prev_y,
- Int vop_width,
- Int vop_height,
- Int enable_8x8_mv,
- Int edge,
- Int f_code,
- Int sr,
- Float hint_mv_w,
- Float hint_mv_h,
- Float *mv16_w,
- Float *mv16_h,
- Float *mv8_w,
- Float *mv8_h,
- Int *min_error,
- SInt *flags
- )
- {
- Int x, y;
- Int sad, sad_min=MV_MAX_ERROR;
- Int mv_x, mv_y;
- Int block;
- Float pmv_x, pmv_y;
- SInt act_block[MB_SIZE*MB_SIZE];
- Float mv_x_min, mv_x_max,
- mv_y_min, mv_y_max;
- Int int_mv_x_min=0, int_mv_x_max=0,
- int_mv_y_min=0, int_mv_y_max=0;
- Int pos16, pos8;
- Int mvm_width = br_width/MB_SIZE;
- Int x_curr = i*MB_SIZE,
- y_curr = j*MB_SIZE;
- Int hb,vb;
- Int out;
- Int rel_ori_x;
- Int rel_ori_y;
- Int min_error16, min_error8 = 0;
- #ifndef _FULL_SEARCH_
- typedef struct
- {
- Int x;
- Int y;
- SInt start_nmbr;
- } DPoint;
- typedef struct
- {
- DPoint point[8];
- } Diamond;
- SInt d_type=1,stop_flag=0,pt_nmbr=0,check_pts,total_check_pts=8,mot_dirn=0;
- Int d_centre_x=0,d_centre_y=0,check_pt_x,check_pt_y;
- Diamond diamond[2]=
- {
- {
- { {0,1,0}, {1,0,0}, {0,-1,0}, {-1,0,0} }
- }
- ,
- {
- { {0,2,6}, {1,1,0}, {2,0,0}, {1,-1,2},
- {0,-2,2}, {-1,-1,4}, {-2,0,4}, {-1,1,6} }
- }
- };
- #endif
- d_centre_x = (int)hint_mv_w;
- d_centre_y = (int)hint_mv_h;
- rel_ori_x=br_x-prev_x;
- rel_ori_y=br_y-prev_y;
-
-
- LoadArea(curr, x_curr,y_curr,MB_SIZE,MB_SIZE,br_width, act_block);
-
-
- Obtain_Range (f_code, sr, MBM_INTER16,
- 0.0, 0.0, &mv_x_min, &mv_x_max,
-
- &mv_y_min, &mv_y_max, 0);
- RangeInSearchArea (i,j,0, prev_x, prev_y, vop_width, vop_height,
- br_x, br_y, edge,f_code, &mv_x_min, &mv_x_max,
-
- &mv_y_min, &mv_y_max,&out);
-
- if(!out)
- {
- int_mv_x_min=(int)ceil((double)mv_x_min);
- int_mv_y_min=(int)ceil((double)mv_y_min);
- int_mv_x_max=(int)floor((double)mv_x_max);
- int_mv_y_max=(int)floor((double)mv_y_max);
- flags[0]=ARE_EQUAL(int_mv_x_min,mv_x_min);
- flags[1]=ARE_EQUAL(int_mv_x_max,mv_x_max);
- flags[2]=ARE_EQUAL(int_mv_y_min,mv_y_min);
- flags[3]=ARE_EQUAL(int_mv_y_max,mv_y_max);
- sad_min=MV_MAX_ERROR;
- mv_x = mv_y = 2000;
- #ifdef _FULL_SEARCH_
- for (y=int_mv_y_min; y<=int_mv_y_max; y++)
- for (x=int_mv_x_min; x<=int_mv_x_max; x++)
- {
- if (x==0 && y==0)
- sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+rel_ori_x,
- y_curr+rel_ori_y), act_block,
- (vop_width), MV_MAX_ERROR)
- - (128 + 1);
- else
- sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+x+rel_ori_x,
- y_curr+y+rel_ori_y), act_block,
- (vop_width), sad_min);
- if (sad<sad_min)
- {
- sad_min=sad;
- mv_x=x;
- mv_y=y;
- }
- else if (sad==sad_min)
- if((ABS(x)+ABS(y)) < (ABS(mv_x)+ABS(mv_y)))
- {
- sad_min=sad;
- mv_x=x;
- mv_y=y;
- }
- }
- #else
- sad = SAD_Macroblock(prev+INDEX_BIG(x_curr+rel_ori_x,
- y_curr+rel_ori_y), act_block, (vop_width), MV_MAX_ERROR)
- - (128 + 1);
- if (sad<sad_min)
- {
- sad_min=sad;
- mv_x = mv_y = 0;
- }
- do
- {
- check_pts=total_check_pts;
- do
- {
- check_pt_x = diamond[d_type].point[pt_nmbr].x + d_centre_x;
- check_pt_y = diamond[d_type].point[pt_nmbr].y + d_centre_y;
-
- 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)
- {
- sad = MV_MAX_ERROR;
- }
- else
- {
- sad=SAD_Macroblock(prev+INDEX_BIG(x_curr+check_pt_x+rel_ori_x,
- y_curr+check_pt_y+rel_ori_y), act_block,
- (vop_width), sad_min);
- #ifdef _SAD_EXHAUS_
- fprintf(stdout,"+o+ [%2d,%2d] sad16(%3d,%3d)=%4dn",i,j,x,y,sad);
- #endif
- }
- if (sad<sad_min)
- {
- sad_min=sad;
- mv_x=check_pt_x;
- mv_y=check_pt_y;
- mot_dirn=pt_nmbr;
- }
- else if (sad==sad_min)
- if((ABS(check_pt_x)+ABS(check_pt_y)) < (ABS(mv_x)+ABS(mv_y)))
- {
- sad_min=sad;
- mv_x=check_pt_x;
- mv_y=check_pt_y;
- mot_dirn=pt_nmbr;
- }
- pt_nmbr+=1;
- if((pt_nmbr)>= 8) pt_nmbr-=8;
- check_pts-=1;
- }
- while(check_pts>0);
- if( d_type == 0)
- {
- stop_flag = 1;
- }
- else
- {
- if( (mv_x == d_centre_x) && (mv_y == d_centre_y) )
- {
- d_type=0;
- pt_nmbr=0;
- total_check_pts = 4;
- }
- else
- {
- if((mv_x==d_centre_x) ||(mv_y==d_centre_y))
- total_check_pts=5;
- else
- total_check_pts=3;
- pt_nmbr=diamond[d_type].point[mot_dirn].start_nmbr;
- d_centre_x = mv_x;
- d_centre_y = mv_y;
- }
- }
- }
- while(stop_flag!=1);
- #endif
- flags[0]=flags[0] && (mv_x==int_mv_x_min);
- flags[1]=flags[1] && (mv_x==int_mv_x_max);
- flags[2]=flags[2] && (mv_y==int_mv_y_min);
- flags[3]=flags[3] && (mv_y==int_mv_y_max);
- }
- else
- {
- mv_x=mv_y=0;
- sad_min=MV_MAX_ERROR;
- }
-
- out |=((mv_x==2000)||(mv_y==2000));
- if(out)
- {
- mv_x=mv_y=0;
- sad_min=MV_MAX_ERROR;
- }
- pos16=2*j*2*mvm_width + 2*i;
- mv16_w[pos16]= mv_x; mv16_h[pos16]= mv_y;
- mv16_w[pos16+1]= mv_x; mv16_h[pos16+1]= mv_y;
- pos16+=2*mvm_width;
- mv16_w[pos16]= mv_x; mv16_h[pos16]= mv_y;
- mv16_w[pos16+1]= mv_x; mv16_h[pos16+1]= mv_y;
- min_error16 = sad_min;
- *min_error = min_error16;
-
- if(enable_8x8_mv==1)
- {
- if(!out)
- {
- for (block=0;block<4;block++)
- {
-
- if(block==0)
- {
- hb=vb=0;
- }
- else if (block==1)
- {
- hb=1;vb=0;
- }
- else if (block==2)
- {
- hb=0;vb=1;
- }
- else
- {
- hb=vb=1;
- }
-
- pmv_x=mv16_w[pos16]; pmv_y=mv16_h[pos16];
-
- Obtain_Range(f_code, sr, MBM_INTER8,
- pmv_x, pmv_y, &mv_x_min,
-
- &mv_x_max, &mv_y_min, &mv_y_max, 0 );
- RangeInSearchArea(i,j, block+1, prev_x, prev_y,
- vop_width, vop_height, br_x, br_y, edge,f_code,
-
- &mv_x_min, &mv_x_max, &mv_y_min,&mv_y_max,&out);
- if(!out)
- {
- int_mv_x_min=(int)ceil((double)mv_x_min);
- int_mv_y_min=(int)ceil((double)mv_y_min);
- int_mv_x_max=(int)floor((double)mv_x_max);
- int_mv_y_max=(int)floor((double)mv_y_max);
- flags[4+block*4]=ARE_EQUAL(int_mv_x_min,mv_x_min);
- flags[4+block*4+1]=ARE_EQUAL(int_mv_x_max,mv_x_max);
- flags[4+block*4+2]=ARE_EQUAL(int_mv_y_min,mv_y_min);
- flags[4+block*4+3]=ARE_EQUAL(int_mv_y_max,mv_y_max);
- sad_min=MV_MAX_ERROR;
- mv_x = mv_y = 2000;
- for (y=int_mv_y_min; y<=int_mv_y_max; y++)
- for (x=int_mv_x_min; x<=int_mv_x_max; x++)
- {
- sad=SAD_Block(prev+
- INDEX_BIG(x_curr + x + 8*(block==1||block==3)+rel_ori_x,
- y_curr + y + 8*(block==2||block==3)+rel_ori_y),
- act_block+INDEX_NOR(8*(block==1||block==3),
- 8*(block==2||block==3)),
- (vop_width ), sad_min);
- if (sad<sad_min)
- {
- sad_min=sad;
- mv_x=x;
- mv_y=y;
- }
- else if (sad==sad_min)
- if((ABS(x)+ABS(y)) < (ABS(mv_x)+ABS(mv_y)))
- {
- sad_min=sad;
- mv_x=x;
- mv_y=y;
- }
- }
- flags[4+block*4] = flags[4+block*4] && (mv_x==int_mv_x_min);
- flags[4+block*4+1] = flags[4+block*4+1] && (mv_x==int_mv_x_max);
- flags[4+block*4+2] = flags[4+block*4+2] && (mv_y==int_mv_y_min);
- flags[4+block*4+3] = flags[4+block*4+3] && (mv_y==int_mv_y_max);
- }
- else
- {
- mv_x=mv_y=0;
- sad_min=MV_MAX_ERROR;
-
- }
-
- if(block==0)
- {
- pos8=2*j*2*mvm_width + 2*i;
- min_error8 += sad_min;
- }
- else if (block==1)
- {
- pos8=2*j*2*mvm_width + 2*i+1;
- min_error8 += sad_min;
- }
- else if (block==2)
- {
- pos8=(2*j+1)*2*mvm_width + 2*i;
- min_error8 += sad_min;
- }
- else
- {
- pos8=(2*j+1)*2*mvm_width + 2*i+1;
- min_error8 += sad_min;
- }
-
- mv8_w[pos8]=mv_x;
- mv8_h[pos8]=mv_y;
- }
- if (min_error8 < *min_error)
- *min_error = min_error8;
- }
- else
- {
- pos8=2*j*2*mvm_width + 2*i; mv8_w[pos8]=mv8_h[pos8]=0.0;
- pos8=2*j*2*mvm_width + 2*i+1; mv8_w[pos8]=mv8_h[pos8]=0.0;
- pos8=(2*j+1)*2*mvm_width + 2*i; mv8_w[pos8]=mv8_h[pos8]=0.0;
- pos8=(2*j+1)*2*mvm_width + 2*i+1;mv8_w[pos8]=mv8_h[pos8]=0.0;
- min_error8 = MV_MAX_ERROR;
- }
- }
- }
- Void
- FindSubPel(
- Int x,
- Int y,
- SInt *prev,
- SInt *curr,
- Int bs_x,
- Int bs_y,
- Int comp,
- Int rel_x,
- Int rel_y,
- Int pels,
- Int lines,
- Int edge,
- SInt *flags,
- SInt *curr_comp_mb,
- Float *mvx,
- Float *mvy,
- Int *min_error
- )
- {
- static PixPoint search[9] =
- {
- {0, 0}, {-1, -1}, {0, -1}, {1, -1},
- {-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}
- };
-
- Int i, m, n;
- Int new_x, new_y,
- lx, size_x;
- Int min_pos;
- Int AE, AE_min;
- Int flag_pos;
- SInt *pRef, *pComp;
- int flag_search[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1};
- Int SubDimension = 2;
- lx = 2*(pels );
- new_x = (Int)((x + *mvx + rel_x)*(SubDimension));
- new_y = (Int)((y + *mvy + rel_y)*(SubDimension));
- new_x += ((comp&1)<<3)*SubDimension;
- new_y += ((comp&2)<<2)*SubDimension;
- size_x=16;
-
-
-
-
-
- if (bs_x==8)
- flag_pos=4+comp*4;
- else
- flag_pos=0;
- if (((new_x/SubDimension) <= 0) || *(flags+flag_pos)) {
- flag_search[1] = flag_search[4] = flag_search[6] = 0;
- } else if (((new_x/SubDimension) >= (pels - bs_x )) || *(flags+flag_pos+1)) {
- flag_search[3] = flag_search[5] = flag_search[8] = 0;
- };
- if (((new_y/SubDimension) <= 0) || *(flags+flag_pos+2)) {
- flag_search[1] = flag_search[2] = flag_search[3] = 0;
- } else if (((new_y/SubDimension) >= (lines- bs_y )) || *(flags+flag_pos+3)) {
- flag_search[6] = flag_search[7] = flag_search[8] = 0;
- };
- AE_min = MV_MAX_ERROR;
- min_pos = 0;
- for (i = 0; i < 9; i++)
- {
- if (flag_search[i])
- {
- AE = 0;
-
- pRef = prev + new_x + search[i].x + (new_y + search[i].y) * lx;
- pComp = curr;
- n = bs_y;
- while (n--) {
- m = bs_x;
- while (m--) {
- AE += abs((Int)*pRef - (Int)*pComp);
- pRef += 2;
- pComp ++;
- }
- pRef += 2 * lx - 2 * bs_x;
- pComp += size_x - bs_x;
- }
- if (i==0 && bs_y==16 && *mvx==0 && *mvy==0)
- AE -= (128 + 1);
- if (AE < AE_min)
- {
- AE_min = AE;
- min_pos = i;
- }
- }
-
- }
-
- *min_error = AE_min;
- *mvx += ((Float)search[min_pos].x)/(Float)(SubDimension);
- *mvy += ((Float)search[min_pos].y)/(Float)(SubDimension);
-
- pRef = prev + new_x + search[min_pos].x + (new_y + search[min_pos].y) * lx;
- pComp = curr_comp_mb;
- n = bs_y;
- while (n--) {
- m = bs_x;
- while (m--) {
- *(pComp ++) = *pRef;
- pRef += 2;
- }
- pRef += 2 * lx - 2 * bs_x;
- pComp += 16 - bs_x;
- }
- return;
- }