📄 fast_me.c
字号:
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;
}
//write refFrArr[][] for current subMB partition
// refFrArray[pic_block_y][pic_block_x]= ref; //needed for other subMB partitions in this MB partition
// refFrArray[pic_block_x][pic_block_y]= ref; //needed for other subMB partitions in this MB partition
// if(input->InterlaceCodingOption >= MB_CODING && mb_adaptive)
// block_available_upright = 0; // temp fix for MB level field/frame coding
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? refFrArray[pic_block_x-1] [pic_block_y]: -1;
rFrameU = block_available_up ? refFrArray[pic_block_x] [pic_block_y-1]: -1;
rFrameUR = block_available_upright ? refFrArray[pic_block_x+blockshape_x/4][pic_block_y-1] :
block_available_upleft ? refFrArray[pic_block_x-1][pic_block_y-1] : -1;
/* Prediction if only one of the neighbors uses the reference frame
* we are checking
*/
if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_L;
else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
mvPredType = MVPRED_U;
else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
mvPredType = MVPRED_UR;
// Directional predictions
if(blockshape_x == 8 && blockshape_y == 16)
{
if(mb_x == 0)
{
if(rFrameL == ref_frame)
mvPredType = MVPRED_L;
}
else
{
//if( block_available_upright && refFrArray[pic_block_y-1][pic_block_x+blockshape_x/4] == ref_frame)
if(rFrameUR == ref_frame)
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)
for (hv=0; hv < 2; hv++)
{
mv_a = block_available_left ? tmp_mv[pic_block_x-1][pic_block_y ][hv] : 0;
mv_b = block_available_up ? tmp_mv[pic_block_x][pic_block_y-1][hv] : 0;
mv_d = block_available_upleft ? tmp_mv[pic_block_x-1][pic_block_y-1][hv] : 0;
mv_c = block_available_upright ? tmp_mv[pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d;
SAD_a = block_available_left ? ((list==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 ? ((list==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 ? ((list==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 ? ((list==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(!(block_available_upleft || block_available_up || block_available_upright))
{
pred_vec = mv_a;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
temp_pred_SAD[hv] = SAD_a;
}
else
pred_vec = MEDIAN (mv_a, mv_b, mv_c);
if (pred_vec == mv_a && SAD_a != 0) temp_pred_SAD[hv] = SAD_a;
else if (pred_vec == mv_b && SAD_b!=0) temp_pred_SAD[hv] = SAD_b;
else temp_pred_SAD[hv] = SAD_c;
break;
case MVPRED_L:
pred_vec = mv_a;
temp_pred_SAD[hv] = SAD_a;
break;
case MVPRED_U:
pred_vec = mv_b;
temp_pred_SAD[hv] = SAD_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
temp_pred_SAD[hv] = SAD_c;
break;
default:
break;
}
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
}
int //!< minimum motion cost after search
FME_BlockMotionSearch (int ref, //!< reference frame (0... )
int list, //!< reference picture list
int mb_x, //!< x-coordinate inside 8x8 block
int mb_y, //!< y-coordinate inside 8x8 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 block_x = (mb_x>>2);
int block_y = (mb_y>>2);
int bsx = input->blc_size[blocktype][0];
int bsy = input->blc_size[blocktype][1];
int* pred_mv;
int** refFrArray = enc_picture->ref_idx[list];
int*** tmp_mv_array = enc_picture->mv[list];
int****** all_mv = img->all_mv;
//modified 2004.3.3
int pic_pix_x = img->opix_x + mb_x;
int pic_pix_y = img->opix_y + mb_y;
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
int N_Bframe = input->successive_Bframe, n_Bframe =(N_Bframe) ? ((Bframe_ctr%N_Bframe)+1) : 0 ;
pred_mv = img->pred_mv[mb_x>>2][mb_y>>2][list][ref][blocktype]; //NB pred_mv is only 2D here
//==================================
//===== GET ORIGINAL BLOCK =====
//==================================
for (j = 0; j < bsy; j++)
{
for (i = 0; i < bsx; i++)
{
//modified 2004.3.3
// orig_pic[j][i] = imgY_org[img->opix_y+j][img->opix_c_x+i];
orig_pic[j][i] = imgY_org[pic_pix_y+j][pic_pix_x+i];
}
}
//FAST MOTION ESTIMATION. ZHIBO CHEN 2003.3
if(blocktype>6)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][5][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][5][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][5][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype>4)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][4][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][4][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][4][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype == 4)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][2][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][2][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][2][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype > 1)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][1][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][1][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][1][0]);
pred_SAD_uplayer /= 2;
}
if ((img->type==B_SLICE)&& (img->nal_reference_idc>0))
{
if(blocktype>6)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][5][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][5][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][5][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][5][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype>4)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][4][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][4][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][4][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][4][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype == 4)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][2][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][2][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][2][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][2][0]);
pred_SAD_uplayer /= 2;
}
else if(blocktype > 1)
{
pred_MV_uplayer[0] = all_mv[block_x][block_y][list][ref][1][0];
pred_MV_uplayer[1] = all_mv[block_x][block_y][list][ref][1][1];
pred_SAD_uplayer = (list==1) ? (all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][0][1][0]) : (all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][1][0]);
pred_SAD_uplayer /= 2;
}
}
pred_SAD_uplayer = flag_intra_SAD ? 0 : pred_SAD_uplayer;// for irregular motion
//Coordinate prediction
if (img->number > ref+1)
{
pred_SAD_time = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][0];
pred_MV_time[0] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][1];
pred_MV_time[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][2];
}
if(list==1 && (Bframe_ctr%N_Bframe) > 1)
{
pred_SAD_time = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][0];
pred_MV_time[0] = (int)(all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_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)+block_x][(img->pix_y>>2)+block_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 (input->PicInterlace == FIELD_CODING)
{
if (img->type == P_SLICE && ref > 1)
{
pred_SAD_ref = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(ref-2)][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)+block_x][(img->pix_y>>2)+block_y][(ref-2)][blocktype][1];
pred_MV_ref[0] = (int)(pred_MV_ref[0]*((ref>>1)+1)/(float)((ref>>1)));
pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(ref-2)][blocktype][2];
pred_MV_ref[1] = (int)(pred_MV_ref[1]*((ref>>1)+1)/(float)((ref>>1)));
}
if (img->type == B_SLICE && list==0 && (ref==0 || ref==1) )
{
pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_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)+block_x][(img->pix_y>>2)+block_y][ref][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)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
}
else //frame case
{
if (ref > 0)
{//field_mode top_field
pred_SAD_ref = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(ref-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)+block_x][(img->pix_y>>2)+block_y][(ref-1)][blocktype][1];
pred_MV_ref[0] = (int)(pred_MV_ref[0]*(ref+1)/(float)(ref));
pred_MV_ref[1] = all_mincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_y][(ref-1)][blocktype][2];
pred_MV_ref[1] = (int)(pred_MV_ref[1]*(ref+1)/(float)(ref));
}
if (img->type == B_SLICE && (list==0 && ref==0)) //B frame forward prediction, first ref
{
pred_SAD_ref = all_bwmincost[(img->pix_x>>2)+block_x][(img->pix_y>>2)+block_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)+block_x][(img->pix_y>>2)+block_y][ref][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)+block_x][(img->pix_y>>2)+block_y][ref][blocktype][2]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
}
//===========================================
//===== GET MOTION VECTOR PREDICTOR =====
//===========================================
//NB pred_mv is only 2D here
FME_SetMotionVectorPredictor (pred_mv, refFrArray, tmp_mv_array, ref, list, mb_x, mb_y, bsx, bsy, blocktype, ref);
pred_mv_x = pred_mv[0];
pred_mv_y = pred_mv[1];
//==================================
//===== 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, list, 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(list == 0)
all_mincost[(img->pix_x>>2)+block_x+i][(img->pix_y>>2)+block_y+j][ref][blocktype][0] = min_mcost;
else
all_bwmincost[(img->pix_x>>2)+block_x+i][(img->pix_y>>2)+block_y+j][ref][blocktype][0] = min_mcost;
}
}
//==============================
//===== SUB-PEL SEARCH =====
//==============================
if (input->hadamard)
{
min_mcost = max_value;
}
if(blocktype >3)
{
min_mcost = FastSubPelBlockMotionSearch (orig_pic, ref, list, pic_pix_x, pic_pix_y, blocktype,
pred_mv_x, pred_mv_y, &mv_x, &mv_y, 9, 9,
min_mcost, lambda, /*useABT*/0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -