📄 motion_est.c
字号:
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); /*判定整像素搜索是否结束*/
/*-----------------------------------------------DS-b------------------------------*/
/* TYM 2000.04.20 */
/* pos16=j*mvm_width+i;
Prev_Mv[pos16].x=mv_x;
Prev_Mv[pos16].y=mv_y;
Prev_Mv[pos16].sad=sad_min;*/
/*currMV->x=mv_x<<1;
currMV->y=mv_y<<1;*/
/* perform final half-pel step */
Amvfast16_Refine:
currMV->x=mv_x;
currMV->y=mv_y;
if(MotionFlags & HALFPELREFINE16)
sad_min =
Halfpel16_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
sad_min, pmv, min_dx, max_dx, min_dy, max_dy,
iFcode, iQuant, iEdgedWidth);
/* currPMV->x = currMV->x - pmv[0].x;
currPMV->y = currMV->y - pmv[0].y;*/
currPMV->x = currMV->x - pmv_x;
currPMV->y = currMV->y - pmv_y;
return sad_min;
}
/* add MV16X16 point check and early quit */
static int
amvfastSearch8(const uint8_t * const pRef,
const uint8_t * const pRefH,
const uint8_t * const pRefV,
const uint8_t * const pRefHV,
const IMAGE * const pCur,
const int x,
const int y,
const int start_x,
const int start_y,
const uint32_t MotionFlags,
const int32_t iQuant,
const uint32_t iFcode,
const MBParam * const pParam,
const MACROBLOCK * const pMBs,
const MACROBLOCK * const prevMBs,
VECTOR * const currMV,
VECTOR * const currPMV)
{
/*int blocksize=16;*//* block size:16 or 8 */
const uint32_t iWcount = pParam->mb_width;
const int32_t iWidth = pParam->width;
const int32_t iHeight = pParam->height;
const int32_t iEdgedWidth = pParam->edged_width;
const uint8_t *cur = pCur->y + x * 8 + y * 8 * iEdgedWidth;
/*const uint8_t *cur = pCur->y + x * blocksize + y * blocksize * iEdgedWidth;*/
VECTOR pmv[4];/* half pixel offset */
VECTOR mvs[5];
int pmv_x,pmv_y;
int cand_x,cand_y;
int x2=x>>1;
int y2=y>>1;
int iSubBlock = (y & 1) + (y & 1) + (x & 1);
const MACROBLOCK * const pMB = pMBs + x2 + y2 * iWcount;
const MACROBLOCK *const prevMB = prevMBs + x2 + y2 * iWcount;
/* int i,j;*/
int sad, sad_min;
int mv_x;
int mv_y;
int min_dx, max_dx,
min_dy, max_dy;/* half pixel motion vector range */
/* int pos16;*/
/*int mvm_width = iWidth/blocksize;*/
/* int mvm_width = iWidth/16;*/
int pass_flag; /* SAD calculated flag for point in prediction */
int pass_x,pass_y; /* SAD calculated point in prediction*/
/* int SAD_th1=125;
int SAD_th2=185;*/
int SAD_th1;
int SAD_th2;
int V_count;
int ii;
int skip_flag;
int same_mv;
/* float factor1=(float)1.05,factor2=(float)1.5; */
int more_loop=0,new_min,eightORfour=8;
/* ------------------------------DS-----------t-----------------------*/
typedef struct
{
int x;
int y;
int start_nmbr;
} DPoint;
typedef struct
{
DPoint point[8];
} Diamond;
int d_type=1,stop_flag=0,pt_nmbr=0,check_pts,total_check_pts=8,mot_dirn=0;
int d_centre_x,d_centre_y,check_pt_x,check_pt_y;/* integer pixel */
/*Diamond diamond[2]={{{{0,1,3},{1,0,0},{0,-1,1},{-1,0,2}}},{{{0,2,6},{1,1,0},{2,0,0},{1,-1,2},{0,-2,2},{-1,-1,4},{-2,0,4},{-1,1,6}}}};*/
Diamond diamond[2]={{{{0,2,3},{2,0,0},{0,-2,1},{-2,0,2}}},{{{0,4,6},{2,2,0},{4,0,0},{2,-2,2},{0,-4,2},{-2,-2,4},{-4,0,4},{-2,2,6}}}};
/*----------------------------------DS-----------b-------------------------*/
/* fyh add below code(2002.12.22):
Saved vector and sad for the block of the same position
in previous frame.
*/
int prev_sad;
int prev_mvx,prev_mvy;
if(first_P_seq) /* first P frame in sequence */
{
prev_sad=128;
prev_mvx=0;
prev_mvy=0;
}
else if(first_P_gop) /* first P frame in gop */
{
prev_sad=pMB->sad8[iSubBlock];
prev_mvx=pMB->mvs[iSubBlock].x;
prev_mvy=pMB->mvs[iSubBlock].y;
}
else /* other P frame */
{
prev_sad=prevMB->sad8[iSubBlock];
prev_mvx=prevMB->mvs[iSubBlock].x;
prev_mvy=prevMB->mvs[iSubBlock].y;
}
/* Get maximum range */
get_range(&min_dx, &max_dx, &min_dy, &max_dy, x, y, 8, iWidth, iHeight,iFcode);
/* 获得中值法的运动矢量 */
/*pmv=get_pmv(pMBs, x, y, iWcount, 0);*/
same_mv=get_pmvdata_amv(pMBs, x2, y2, iWcount, iSubBlock, pmv);
pmv_x=pmv[0].x;
pmv_y=pmv[0].y;
/* computer (start_x,start_y) */
mv_x=pass_x=start_x;
mv_y=pass_y=start_y;
sad_min =
sad8(cur,
get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, start_x,start_y,
iEdgedWidth), iEdgedWidth);
SAD8_count++;
sad_min +=
calc_delta_8(start_x - pmv_x, start_y - pmv_y,iFcode, iQuant);
/* if ((sad_min < 64) || ((start_x == prevMB->mvs[iSubBlock].x && start_y == prevMB->mvs[iSubBlock].y)
&& ( sad_min <prevMB->sad8[iSubBlock])))*/
if ((sad_min < 64) || ((start_x == prev_mvx && start_y == prev_mvy)
&& ( sad_min <prev_sad)))
{
/* currMV->x=start_x;
currMV->y=start_y;*/
goto Amvfast8_Refine;
}
/*
if(!x && !y)
{
prev_mv_available++;
if(prev_mv_available>1)
{
prev_mv_available=2;
}
}
*/
/* Resize SAD_th */
/*current frame don't first P frame*/
/*if(prev_mv_available>1)
{*/
/* sad=prevMB->sad8[iSubBlock];
if(sad<128)
{
SAD_th1=128;
SAD_th2=192;
}
else
{
SAD_th1=(int) (sad * factor1);
SAD_th2=(int) (sad * factor2);
}*/
/*}*/
if(prev_sad<128)
{
SAD_th1=128;
SAD_th2=192;
}
else
{
SAD_th1=(int) (prev_sad * factor1);
SAD_th2=(int) (prev_sad * factor2);
}
/* save (0,0) point */
mvs[0].x=0;
mvs[0].y=0;
V_count=1;
/* save left block motion vector */
cand_x=pmv[1].x;
cand_y=pmv[1].y;
if(cand_x || cand_y)
{
mvs[1].x=cand_x;
mvs[1].y=cand_y;
V_count=2;
}
if(same_mv)
{
/* left,top,righttop block motion vector equal */
/*current frame don't first P frame*/
/* if(prev_mv_available>1)
{*/
/* cand_x=prevMB->mvs[iSubBlock].x;
cand_y=prevMB->mvs[iSubBlock].y;*/
cand_x=prev_mvx;
cand_y=prev_mvy;
if(cand_x==pmv[1].x && cand_y ==pmv[1].y)
same_mv=1;/* left top righttop previous_frame block motion vector equal */
else
{
/* save previous frame block motion vetor */
same_mv=0;
if(cand_x||cand_y)
{
mvs[V_count].x=cand_x;
mvs[V_count].y=cand_y;
V_count++;
}
}
/*}*/
}
else
{
/* save top block motion vector */
skip_flag=0;
cand_x=pmv[2].x;
cand_y=pmv[2].y;
for(ii=0;ii<V_count;ii++)
if(cand_x==mvs[ii].x && cand_y==mvs[ii].y)
{
skip_flag=1;
break;
}
if(!skip_flag)
{
mvs[V_count].x= cand_x;
mvs[V_count].y= cand_y;
V_count++;
}
/* save righttop block motion vector */
skip_flag=0;
cand_x=pmv[3].x;
cand_y=pmv[3].y;
for(ii=0;ii<V_count;ii++)
if(cand_x==mvs[ii].x && cand_y==mvs[ii].y)
{
skip_flag=1;
break;
}
if(!skip_flag)
{
mvs[V_count].x= cand_x;
mvs[V_count].y= cand_y;
V_count++;
}
/* save previous frame block motion vetor */
skip_flag=0;
/* cand_x=prevMB->mvs[iSubBlock].x;
cand_y=prevMB->mvs[iSubBlock].y;*/
cand_x=prev_mvx;
cand_y=prev_mvy;
for(ii=0;ii<V_count;ii++)
if(cand_x ==mvs[ii].x && cand_y==mvs[ii].y)
{
skip_flag=1;
break;
}
if(!skip_flag)
{
mvs[V_count].x= cand_x;
mvs[V_count].y= cand_y;
V_count++;
}
}/* same_mv */
/* decide initial search mode */
if(same_mv)/*SDS MODE*/
{
d_type=0;
total_check_pts=4;
more_loop=1;
}
/*decide the starting point of searching */
pass_flag=0;
for(ii=0;ii<V_count;ii++)
{
cand_x=mvs[ii].x;
cand_y=mvs[ii].y;
if(!(cand_x==start_x && cand_y==start_y) )
{
if (cand_x < min_dx || cand_x > max_dx || cand_y < min_dy || cand_y > max_dy)
continue;
else
{
pass_flag=1;
pass_x=cand_x;
pass_y=cand_y;
sad =
/* sad16(cur,get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
iEdgedWidth), iEdgedWidth, sad_min);*/
sad8(cur,get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, cand_x,cand_y,
iEdgedWidth), iEdgedWidth);
SAD8_count++;
if(sad<sad_min)
{
sad +=
calc_delta_8(cand_x - pmv_x, cand_y - pmv_y,iFcode, iQuant);
if(sad<sad_min)
{
sad_min=sad;
mv_x=cand_x;
mv_y=cand_y;
}
else if ( sad==sad_min && (abs(cand_x)+abs(cand_y))<(abs(mv_x)+abs(mv_y)) )
{
sad_min=sad;
mv_x=cand_x;
mv_y=cand_y;
}
}
}/* End of else(....) */
}/* End of if(..) */
}/* end of for */
/* convert half pixel to interge pixel */
/*mv_x>>=1;
mv_y>>=1;
pass_x>>=1;
pass_y>>=1;*/
if(mv_x || mv_y)
{
pass_x=0;
pass_y=0;
}
else/* best candidate is (0,0) point */
{
if(sad_min <= iQuant * 96)
sad_min -= MV8_00_BIAS;
}
/* ------------------------------DS t----------------------------------*/
d_centre_x=mv_x;
d_centre_y=mv_y;
do
{
check_pts=total_check_pts;
new_min=0;
do
{
/* TYM add 2000.04.27 half-stop by using SAD threshold */
if(sad_min<SAD_th1)
{
d_type=0;
break;
}
else
{
if(sad_min<SAD_th2 && d_type!=0)/*again sds*/
{
more_loop=1;
d_centre_x=mv_x;
d_centre_y=mv_y;
break;
}
}
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;
/*cand_x=check_pt_x<<1;
cand_y=check_pt_y<<1; */
if( check_pt_x < min_dx || check_pt_x > max_dx || check_pt_y < min_dy || check_pt_y > max_dy)
{
sad = MV_MAX_ERROR;
}
else
if(!(pass_flag && check_pt_x==pass_x && check_pt_y==pass_y ))
{
/*sad = dist1(ref+(i0+check_pt_x)+lx*(j0+check_pt_y),blk,lx,h,sad_min);*/
sad =
sad8(cur,
/* get_ref_mv(pRef, pRefH, pRefV, pRefHV, x, y, 16, currMV,
iEdgedWidth), iEdgedWidth, sad_min);*/
get_ref(pRef, pRefH, pRefV, pRefHV, x, y, 8, check_pt_x,check_pt_y,
iEdgedWidth), iEdgedWidth);
SAD8_count++;
if(sad<sad_min)
{
sad +=
/* calc_delta_16(currMV->x - pmv[0].x, currMV->y - pmv[0].y,
(uint8_t) iFcode, iQuant);*/
calc_delta_8(check_pt_x - pmv_x, check_pt_y - pmv_y,iFcode, iQuant);
if (sad<sad_min)
{
sad_min=sad;
mv_x=check_pt_x;
mv_y=check_pt_y;
mot_dirn=pt_nmbr;
new_min=1;
}
/* fyh comment code by 2002.12.16*/
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)>= eightORfour) pt_nmbr-=eightORfour;
check_pts-=1;
}
while(check_pts>0);/*decide one pass diamond search stop or not*/
/* check one pass search result */
if( d_type == 0)/*sds*/
{
if(more_loop==0 || new_min==0)
stop_flag = 1;
else
{
total_check_pts=3;
eightORfour=4;
pt_nmbr=diamond[d_type].point[mot_dirn].start_nmbr;
d_centre_x = mv_x;
d_centre_y = mv_y;
}
}
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); /*判定整像素搜索是否结束*/
/*-----------------------------------------------DS-b------------------------------*/
/* TYM 2000.04.20 */
/* pos16=j*mvm_width+i;
Prev_Mv[pos16].x=mv_x;
Prev_Mv[pos16].y=mv_y;
Prev_Mv[pos16].sad=sad_min;*/
/*currMV->x=mv_x<<1;
currMV->y=mv_y<<1;*/
/* perform final half-pel step */
Amvfast8_Refine:
currMV->x=mv_x;
currMV->y=mv_y;
if(MotionFlags & HALFPELREFINE8)
sad_min =
Halfpel8_Refine(pRef, pRefH, pRefV, pRefHV, cur, x, y, currMV,
sad_min, pmv, min_dx, max_dx, min_dy, max_dy,
iFcode, iQuant, iEdgedWidth);
/* currPMV->x = currMV->x - pmv[0].x;
currPMV->y = currMV->y - pmv[0].y;*/
currPMV->x = currMV->x - pmv_x;
currPMV->y = currMV->y - pmv_y;
return sad_min;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -