📄 mot_est_mb.c
字号:
#else /* PIH (NTU) Fast ME 08/08/99 */
sad = SAD_Macroblock(prev+INDEX_BIG(x_curr+rel_ori_x,
y_curr+rel_ori_y), act_block, (vop_width/*+2*edge*/), 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;
/* Restrict the search to the searching window ; Note: This constraint can be removed */
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/*+2*edge*/), sad_min);
#ifdef _SAD_EXHAUS_
fprintf(stdout,"+o+ [%2d,%2d] sad16(%3d,%3d)=%4d\n",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;
}
/* Store result */
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;
/* Compute 8x8 MVs */
if(enable_8x8_mv==1)
{
if(!out)
{
for (block=0;block<4;block++)
{
/* Obtain range */
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;
}
/* VM 2.*: restrict the search range based on the current 16x16 MV
* inside a window around it
*/
pmv_x=mv16_w[pos16]; pmv_y=mv16_h[pos16];
/* UB 990215 added search range */
Obtain_Range(f_code, sr, MBM_INTER8,
pmv_x, pmv_y, &mv_x_min,
/*UB 990215 added quarter pel support */
&mv_x_max, &mv_y_min, &mv_y_max, 0 /*GetVopQuarterPel(curr_vop)*/);
RangeInSearchArea(i,j, block+1, prev_x, prev_y,
vop_width, vop_height, br_x, br_y, edge,f_code,
/*UB 990215 added quarter pel support */
&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; /* A very large MV */
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 /*+2*edge*/), 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;
}
} /*for*/
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;
/* punish the OUTER blocks with MV_MAX_ERROR in order to
be INTRA CODED */
}
/* Store result */
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;
}
/* Store result: absolute coordinates (note that in restricted mode
pmv is (0,0)) */
mv8_w[pos8]=mv_x;
mv8_h[pos8]=mv_y;
} /*for block*/
if (min_error8 < *min_error)
*min_error = min_error8;
}
else
{ /* all the four blocks are out */
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;
}
} /* enable_8x8_mv*/
}
/***********************************************************CommentBegin******
*
* -- FindSubPel -- Computes MV with half-pixel accurary
*
* Purpose :
* Computes MV with sub-pixel accurary for a 16x16 or 8x8 block
*
* Description :
* 1) The preference for the 16x16 null motion vector must be applied
* again (now, the SAD is recomputed for the recontructed interpolated
* reference)
*
***********************************************************CommentEnd********/
Void
FindSubPel(
Int x, /* <-- horizontal block coordinate in pixels */
Int y, /* <-- vertical blocl coordinate in pixels */
SInt *prev, /* <-- interpolated reference vop */
SInt *curr, /* <-- current block */
Int bs_x, /* <-- hor. block size (8/16) */
Int bs_y, /* <-- vert. block size (8/16) */
Int comp, /* <-- block position in MB (0,1,2,3) */
Int rel_x, /* <-- relative horiz. position between curr & prev vops*/
Int rel_y, /* <-- relative verti. position between curr & prev vops*/
Int pels, /* <-- vop width */
Int lines, /* <-- vop height */
Int edge, /* <-- edge */
SInt *flags, /* <-- flags */
SInt *curr_comp_mb, /* <-> motion compensated current mb */
Float *mvx, /* <-> horizontal motion vector */
Float *mvy, /* <-> vertical motion vector */
Int *min_error /* --> prediction error */
)
{
static PixPoint search[9] =
{
{0, 0}, {-1, -1}, {0, -1}, {1, -1},
{-1, 0}, {1, 0}, {-1, 1}, {0, 1}, {1, 1}
};
/* searching map
1 2 3
4 0 5
6 7 8
*/
Int i, m, n;
Int new_x, new_y,
lx, size_x; /* MW QPEL 07-JUL-1998 */
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 /*+ 2*edge*/);
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;
/** in 1-pixel search we check if we are inside the range; so don't check
it again
**/
/* avoids trying outside the reference image */
/* we also check with flags if we are inside */
/* search range (1==don't make 1/x search by */
/* this side */
if (bs_x==8)
flag_pos=4+comp*4;
else /* ==16*/
flag_pos=0;
if (((new_x/SubDimension) <= 0/*-edge*/) || *(flags+flag_pos)) {
flag_search[1] = flag_search[4] = flag_search[6] = 0;
} else if (((new_x/SubDimension) >= (pels - bs_x /*+ edge*/)) || *(flags+flag_pos+1)) {
flag_search[3] = flag_search[5] = flag_search[8] = 0;
};
if (((new_y/SubDimension) <= 0/*-edge*/) || *(flags+flag_pos+2)) {
flag_search[1] = flag_search[2] = flag_search[3] = 0;
} else if (((new_y/SubDimension) >= (lines- bs_y /*+ edge*/)) || *(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;
/* estimate on the already interpolated half-pel image */
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;
}
}
/* else don't look outside the reference */
}
/* Store optimal values */
*min_error = AE_min;
*mvx += ((Float)search[min_pos].x)/(Float)(SubDimension);
*mvy += ((Float)search[min_pos].y)/(Float)(SubDimension);
// generate comp mb data for the minimum point
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -