📄 fast_me.c
字号:
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_available_upright = 0;
else block_available_upright = 1;
}
else
{
if (mb_x+blockshape_x != 8) block_available_upright = 1;
else block_available_upright = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_available_upright = 1;
else block_available_upright = 0;
}
}
else if (mb_x+blockshape_x != MB_BLOCK_SIZE)
{
block_available_upright = block_available_up;
}
else
{
block_available_upright = mb_available_upright;
}
if (mb_x > 0)
{
block_available_upleft = (mb_y > 0 ? 1 : block_available_up);
}
else if (mb_y > 0)
{
block_available_upleft = block_available_left;
}
else
{
block_available_upleft = mb_available_upleft;
}
smbtypecurr = -2;
smbtypeL = -2;
smbtypeU = -2;
smbtypeUL = -2;
smbtypeUR = -2;
/*Lou 1016 Start*/
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? refFrArr[pic_block_y -off_y] [pic_block_x-1] : -1;
rFrameU = block_available_up ? refFrArr[pic_block_y-y_up][pic_block_x] : -1;
rFrameUR = block_available_upright ? refFrArr[pic_block_y-y_upright][pic_block_x+blockshape_x/8] :
block_available_upleft ? refFrArr[pic_block_y-y_upleft][pic_block_x-1] : -1;
rFrameUL = block_available_upleft ? refFrArr[pic_block_y-y_upleft][pic_block_x-1] : -1;
if((rFrameL != -1)&&(rFrameU == -1)&&(rFrameUR == -1))
mvPredType = MVPRED_L;
else if((rFrameL == -1)&&(rFrameU != -1)&&(rFrameUR == -1))
mvPredType = MVPRED_U;
else if((rFrameL == -1)&&(rFrameU == -1)&&(rFrameUR != -1))
mvPredType = MVPRED_UR;
/*Lou 1016 End*/
// Directional predictions
else if(blockshape_x == 8 && blockshape_y == 16)
{
if(mb_x == 0)
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
else
{
//if( block_available_upright && refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] == ref_frame)
if(rFrameUR == ref_frame) // not correct
mvPredType = MVPRED_UR;
}
}
else if(blockshape_x == 16 && blockshape_y == 8)
{
if(mb_y == 0)
{
if(rFrameU == ref_frame)
mvPredType = MVPRED_U;
}
else
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
}
//#define MEDIAN(a,b,c) (a>b?a>c?b>c?b:c:a:b>c?a>c?a:c:b)
#define MEDIAN(a,b,c) (a + b + c - min(a, min(b, c)) - max(a, max(b, c)));
for (hv=0; hv < 2; hv++)
{
mva[hv] = mv_a = block_available_left ? tmp_mv[hv][pic_block_y - off_y/*lgp*/][4+pic_block_x-1] : 0;
mvb[hv] = mv_b = block_available_up ? tmp_mv[hv][pic_block_y-/*1*/y_up/*lgp*/][4+pic_block_x] : 0;
mv_d = block_available_upleft ? tmp_mv[hv][pic_block_y-y_upleft][4+pic_block_x-1]: 0;
mvc[hv] = mv_c = block_available_upright ? tmp_mv[hv][pic_block_y-/*1*/y_upright/*lgp*/][4+pic_block_x+blockshape_x/8] : mv_d;
//--- Yulj 2004.07.04
// mv_a, mv_b... are not scaled.
mva[hv] = scale_motion_vector(mva[hv], ref_frame, rFrameL, smbtypecurr, smbtypeL, pic_block_y-off_y, pic_block_y, ref, 0);
mvb[hv] = scale_motion_vector(mvb[hv], ref_frame, rFrameU, smbtypecurr, smbtypeU, pic_block_y-y_up, pic_block_y, ref, 0);
mv_d = scale_motion_vector(mv_d, ref_frame, rFrameUL, smbtypecurr, smbtypeUL, pic_block_y-y_upleft, pic_block_y, ref, 0);
mvc[hv] = block_available_upright ? scale_motion_vector(mvc[hv], ref_frame, rFrameUR, smbtypecurr, smbtypeUR, pic_block_y-y_upright, pic_block_y, ref, 0): mv_d;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
SAD_a = block_available_left ? ((ref == -1) ? all_bwmincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2)][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2)][ref_frame][blocktype][0]) : 0;
SAD_b = block_available_up ? ((ref == -1) ? all_bwmincost[((img->pix_x+mb_x)>>2)][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2)][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : 0;
SAD_d = block_available_upleft ? ((ref == -1) ? all_bwmincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) -1][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : 0;
SAD_c = block_available_upright ? ((ref == -1) ? all_bwmincost[((img->pix_x+mb_x)>>2) +1][((img->pix_y+mb_y)>>2) -1][0][blocktype][0] : all_mincost[((img->pix_x+mb_x)>>2) +1][((img->pix_y+mb_y)>>2) -1][ref_frame][blocktype][0]) : SAD_d;
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(hv == 1){
// jlzheng 7.2
// !! for A
mva[2] = abs(mva[0] - mvb[0]) + abs(mva[1] - mvb[1]);
// !! for B
mvb[2] = abs(mvb[0] - mvc[0]) + abs(mvb[1] - mvc[1]);
// !! for C
mvc[2] = abs(mvc[0] - mva[0]) + abs(mvc[1] - mva[1]) ;
pred_vec = MEDIAN(mva[2],mvb[2],mvc[2]);
if(pred_vec == mva[2]){
pmv[0] = mvc[0];
pmv[1] = mvc[1];
temp_pred_SAD[1] = temp_pred_SAD[0] = SAD_a;
}
else if(pred_vec == mvb[2]){
pmv[0] = mva[0];
pmv[1] = mva[1];
temp_pred_SAD[1] = temp_pred_SAD[0] = SAD_b;
}
else{
pmv[0] = mvb[0];
pmv[1] = mvb[1];
temp_pred_SAD[1] = temp_pred_SAD[0] = SAD_c;
} //END
}
break;
case MVPRED_L:
pred_vec = mv_a;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
temp_pred_SAD[hv] = SAD_a;
break;
case MVPRED_U:
pred_vec = mv_b;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
temp_pred_SAD[hv] = SAD_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
temp_pred_SAD[hv] = SAD_c;
break;
default:
break;
}
if(mvPredType != MVPRED_MEDIAN)
pmv[hv] = pred_vec;
}
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
pred_SAD_space = temp_pred_SAD[0]>temp_pred_SAD[1]?temp_pred_SAD[1]:temp_pred_SAD[0];
#undef MEDIAN
}
FME_BlockMotionSearch (int ref, // <-- reference frame (0... or -1 (backward))
int pic_pix_x, // <-- absolute x-coordinate of regarded AxB block
int pic_pix_y, // <-- absolute y-coordinate of regarded AxB block
int blocktype, // <-- block type (1-16x16 ... 7-4x4)
int search_range, // <-- 1-d search range for integer-position search
double lambda // <-- lagrangian parameter for determining motion cost
)
{
static pel_t orig_val [256];
static pel_t *orig_pic [16] = {orig_val, orig_val+ 16, orig_val+ 32, orig_val+ 48,
orig_val+ 64, orig_val+ 80, orig_val+ 96, orig_val+112,
orig_val+128, orig_val+144, orig_val+160, orig_val+176,
orig_val+192, orig_val+208, orig_val+224, orig_val+240};
int pred_mv_x, pred_mv_y, mv_x, mv_y, i, j;
int max_value = (1<<20);
int min_mcost = max_value;
int mb_x = pic_pix_x-img->pix_x;
int mb_y = pic_pix_y-img->pix_y;
int bsx = input->blc_size[blocktype][0];
int bsy = input->blc_size[blocktype][1];
int refframe = (ref==-1 ? 0 : ref);
int* pred_mv;
int** ref_array = ((img->type!=B_IMG /*&& img->type!=BS_IMG*/) ? refFrArr : ref>=0 ? fw_refFrArr : bw_refFrArr);
int*** mv_array = ((img->type!=B_IMG /*&& img->type!=BS_IMG*/) ? tmp_mv : ref>=0 ? tmp_fwMV : tmp_bwMV);
int***** all_bmv = img->all_bmv;
int***** all_mv = (ref<0 ? img->all_bmv : img->all_mv);/*lgp*dct*modify*/
byte** imgY_org_pic = imgY_org;
int temp_x,temp_y;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
int N_Bframe = input->successive_Bframe, n_Bframe =(N_Bframe) ? ((Bframe_ctr%N_Bframe) ? Bframe_ctr%N_Bframe : N_Bframe) : 0 ;
int incr_y=1,off_y=0;/*lgp*/
int b8_x = (mb_x>>3);/*lgp*/
int b8_y = (mb_y>>3);/*lgp*/
int center_x = pic_pix_x;/*lgp*/
int center_y = pic_pix_y;/*lgp*/
int MaxMVHRange,MaxMVVRange;
int blocksize_y = input->blc_size[blocktype][1]; // vertical block size
int blocksize_x = input->blc_size[blocktype][0];
#ifdef TimerCal
LARGE_INTEGER litmp;
LONGLONG QPart1,QPart2;
double dfMinus, dfFreq, dfTim;
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
#endif
if (!img->picture_structure) // field coding
{
if (img->type==B_IMG)
refframe = ref<0 ? ref+2 : ref; // <--forward backward-->
// 1 | 0 | -2 | -1 Yulj 2004.07.15
}
pred_mv = ((img->type!=B_IMG /*&& img->type!=BS_IMG*/) ? img->mv : ref>=0 ? img->p_fwMV : img->p_bwMV)[mb_x>>3][mb_y>>3][refframe][blocktype];
//==================================
//===== GET ORIGINAL BLOCK =====
//==================================
for (j = 0; j < bsy; j++)
{
for (i = 0; i < bsx; i++)
{
orig_pic[j][i] = imgY_org_pic[pic_pix_y+/*j*/incr_y*j+off_y/*lgp*/][pic_pix_x+i];
}
}
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
if(blocktype>6)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][5][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][5][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][5][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype>4)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][4][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][4][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][4][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype == 4)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][2][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][2][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][2][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype > 1)
{
pred_MV_uplayer[0] = all_mv[b8_x][b8_y][refframe][1][0];
pred_MV_uplayer[1] = all_mv[b8_x][b8_y][refframe][1][1];
pred_SAD_uplayer = (ref == -1) ? (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][1][0]);
pred_SAD_uplayer /= 2;
}
pred_SAD_uplayer = flag_intra_SAD ? 0 : pred_SAD_uplayer;// for irregular motion
//coordinate prediction
if (img->number > refframe+1)
{
pred_SAD_time = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][0];
pred_MV_time[0] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][1];
pred_MV_time[1] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][2];
}
if (ref == -1 && Bframe_ctr > 1)
{
pred_SAD_time = all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][refframe][blocktype][0];
pred_MV_time[0] = (int)(all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][1] * ((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
pred_MV_time[1] = (int)(all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][2] *((n_Bframe==1) ? (N_Bframe) : (N_Bframe-n_Bframe+1.0)/(N_Bframe-n_Bframe+2.0)) );//should add a factor
}
{
if (refframe > 0)
{//field_mode top_field
pred_SAD_ref = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][0];
pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
pred_MV_ref[0] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][1];
pred_MV_ref[0] = (int)(pred_MV_ref[0]*(refframe+1)/(float)(refframe));
pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][(refframe-1)][blocktype][2];
pred_MV_ref[1] = (int)(pred_MV_ref[1]*(refframe+1)/(float)(refframe));
}
if (img->type == B_IMG && ref == 0)
{
pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][0];
pred_SAD_ref = flag_intra_SAD ? 0 : pred_SAD_ref;//add this for irregular motion
pred_MV_ref[0] =(int) (all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f)); //should add a factor
pred_MV_ref[1] =(int) ( all_bwmincost[(img->pix_x>>2)+b8_x][(img->pix_y>>2)+b8_y][0][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
}
//===========================================
//===== GET MOTION VECTOR PREDICTOR =====
//===========================================
FME_SetMotionVectorPredictor (pred_mv, ref_array, mv_array, refframe, mb_x, mb_y, bsx, bsy, blocktype, ref);
pred_mv_x = pred_mv[0];
pred_mv_y = pred_mv[1];
#ifdef TimerCal
QueryPerformanceCounter(&litmp);
QPart1 = litmp.QuadPart;
#endif
//==================================
//===== INTEGER-PEL SEARCH =====
//==================================
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
mv_x = pred_mv_x / 4;
mv_y = pred_mv_y / 4;
if (!input->rdopt)
{
//--- adjust search center so that the (0,0)-vector is inside ---
mv_x = max (-search_range, min (search_range, mv_x));
mv_y = max (-search_range, min (search_range, mv_y));
}
min_mcost = FastIntegerPelBlockMotionSearch(orig_pic, ref, center_x/*lgp*/, center_y/*lgp*/,/*pic_pix_x, pic_pix_y,*/ blocktype,
pred_mv_x, pred_mv_y, &mv_x, &mv_y, search_range,
min_mcost, lambda);
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
for (i=0; i < (bsx>>2); i++)
{
for (j=0; j < (bsy>>2); j++)
{
if (ref > -1)
all_mincost[(img->pix_x>>2)+b8_x+i][(img->pix_y>>2)+b8_y+j][refframe][blocktype][0] = min_mcost;
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -