📄 fast_me.c
字号:
else
{
pred_SAD = (list==1) ? (fastme_l1_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]) : (fastme_l0_cost[temp_blocktype][(img->pix_y>>2)+block_y][(img->pix_x>>2)+block_x]);
pred_SAD /= 2;
}
}
else pred_SAD = 0 ; // pred_SAD_space
}
/*!
************************************************************************
* \brief
* FastBipredIntegerPelBlockMotionSearch: fast pixel block motion search for bipred mode
* this algrithm is called UMHexagonS(see JVT-D016),which includes
* four steps with different kinds of search patterns
* \author
* Main contributors: (see contributors.h for copyright, address and affiliation details)
* - Zhibo Chen <chenzhibo@tsinghua.org.cn>
* - JianFeng Xu <fenax@video.mdc.tsinghua.edu.cn>
* - Xiaozhong Xu <xxz@video.mdc.tsinghua.edu.cn>
* \date :
* 2006.1
************************************************************************
*/
int // ==> minimum motion cost after search
FastBipredIntegerPelBlockMotionSearch (pel_t** cur_pic, // <-- original pixel values for the AxB block
short ref, // <-- reference frame (0... or -1 (backward))
int list,
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)
short pred_mv_x1, // <-- motion vector predictor (x) in sub-pel units
short pred_mv_y1, // <-- motion vector predictor (y) in sub-pel units
short pred_mv_x2, // <-- motion vector predictor (x) in sub-pel units
short pred_mv_y2, // <-- motion vector predictor (y) in sub-pel units
short* mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
short* mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
short* s_mv_x, // <--> in: search center (x) / out: motion vector (x) - in pel units
short* s_mv_y, // <--> in: search center (y) / out: motion vector (y) - in pel units
int search_range, // <-- 1-d search range in pel units
int min_mcost, // <-- minimum motion cost (cost for center or huge value)
int lambda_factor) // <-- lagrangian parameter for determining motion cost
{
int temp_Big_Hexagon_x[16];// = Big_Hexagon_x;
int temp_Big_Hexagon_y[16];// = Big_Hexagon_y;
int mvshift = 2; // motion vector shift for getting sub-pel units
int search_step,iYMinNow, iXMinNow;
int i,m,j;
float betaFourth_1,betaFourth_2;
int pos, cand_x, cand_y,mcost;
int list_offset = img->mb_data[img->current_mb_nr].list_offset;
int blocksize_y = input->blc_size[blocktype][1]; // vertical block size
int blocksize_x = input->blc_size[blocktype][0]; // horizontal block size
int blocksize_x4 = blocksize_x >> 2; // horizontal block size in 4-pel units
int pred_x1 = (pic_pix_x << 2) + pred_mv_x1; // predicted position x (in sub-pel units)
int pred_y1 = (pic_pix_y << 2) + pred_mv_y1; // predicted position y (in sub-pel units)
int pred_x2 = (pic_pix_x << 2) + pred_mv_x2; // predicted position x (in sub-pel units)
int pred_y2 = (pic_pix_y << 2) + pred_mv_y2; // predicted position y (in sub-pel units)
short center2_x = pic_pix_x + *mv_x; // center position x (in pel units)
short center2_y = pic_pix_y + *mv_y; // center position y (in pel units)
short center1_x = pic_pix_x + *s_mv_x; // mvx of second pred (in pel units)
short center1_y = pic_pix_y + *s_mv_y; // mvy of second pred (in pel units)
short apply_weights = (active_pps->weighted_bipred_idc>0);
short offsetSpic = (apply_weights ? (list == 0? wp_offset[list_offset ][ref] [0]: wp_offset[list_offset + 1][0 ] [0]) : 0);
short offsetRpic = (apply_weights ? (list == 0? wp_offset[list_offset + 1][ref] [0]: wp_offset[list_offset ][0 ] [0]) : 0);
short mb_x = pic_pix_x - img->opix_x;
short mb_y = pic_pix_y - img->opix_y;
short block_x = (mb_x >> 2);
short block_y = (mb_y >> 2);
int best_x = center2_x;
int best_y = center2_y;
int ET_Thred = Median_Pred_Thd_MB[blocktype];
offsetBi = (offsetRpic + offsetSpic + 1)>>1;
weightSpic = (apply_weights ? (list == 0? wbp_weight[list_offset ][ref][0 ][0]: wbp_weight[list_offset + 1][0 ][ref][0]) : 1<<luma_log_weight_denom);
weightRpic = (apply_weights ? (list == 0? wbp_weight[list_offset + 1][ref][0 ][0]: wbp_weight[list_offset ][0 ][ref][0]) : 1<<luma_log_weight_denom);
ref1_pic = listX[list + list_offset ][ref]->imgY_11;
ref2_pic = listX[list == 0 ? 1 + list_offset: list_offset][ 0 ]->imgY_11;
width = listX[list+list_offset ][ref]->size_x;
height = listX[list+list_offset ][ref]->size_y;
PartCalMadBiPred = apply_weights ? PartCalMadBiPred2 : PartCalMadBiPred1;
//===== set function for getting reference picture lines =====
if ((center2_x > search_range) && (center2_x < width -1-search_range-blocksize_x) &&
(center2_y > search_range) && (center2_y < height-1-search_range-blocksize_y) )
{
get_ref_line2 = FastLineX;
}
else
{
get_ref_line2 = UMVLineX2;
}
//===== set function for getting reference picture lines =====
if ((center1_y > search_range) && (center1_y < height-1-search_range-blocksize_y) )
{
get_ref_line1 = FastLineX;
}
else
{
get_ref_line1 = UMVLineX;
}
//////////////////////////////////////////////////////////////////////////
//////allocate memory for search state//////////////////////////
memset(McostState[0],0,(2*search_range+1)*(2*search_range+1));
//check the center median predictor
cand_x = center2_x ;
cand_y = center2_y ;
mcost = MV_COST (lambda_factor, mvshift, center1_x, center1_y, pred_x1, pred_y1);
mcost += MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x2, pred_y2);
mcost = PartCalMadBiPred(cur_pic, blocksize_y, blocksize_x, blocksize_x4, mcost,INT_MAX,center1_x, center1_y, cand_x, cand_y);
McostState[search_range][search_range] = 1;
if (mcost < min_mcost)
{
min_mcost = mcost;
best_x = cand_x;
best_y = cand_y;
}
iXMinNow = best_x;
iYMinNow = best_y;
for (m = 0; m < 4; m++)
{
cand_x = iXMinNow + Diamond_x[m];
cand_y = iYMinNow + Diamond_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
if(center2_x != pic_pix_x || center2_y != pic_pix_y)
{
cand_x = pic_pix_x ;
cand_y = pic_pix_y ;
SEARCH_ONE_PIXEL_BIPRED
iXMinNow = best_x;
iYMinNow = best_y;
for (m = 0; m < 4; m++)
{
cand_x = iXMinNow + Diamond_x[m];
cand_y = iYMinNow + Diamond_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
}
/***********************************init process*************************/
if( min_mcost < ET_Thred)
{
goto terminate_step;
}
else
{
int N_Bframe=0;
int n_Bframe=0;
short****** bipred_mv = list ? img->bipred_mv1 : img->bipred_mv2;
N_Bframe = input->successive_Bframe;
n_Bframe = frame_ctr[B_SLICE]%(N_Bframe+1);
/**************************** MV prediction **********************/
//MV uplayer prediction
// non for bipred mode
//MV ref-frame prediction
if(list==0)
{
if (img->field_picture)
{
pred_MV_ref[0] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
pred_MV_ref[1] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
else //frame case
{
pred_MV_ref[0] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][0]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
pred_MV_ref[1] =(int) (bipred_mv[block_y][block_x][1][0][blocktype][1]*(-n_Bframe)/(N_Bframe-n_Bframe+1.0f));
}
}
/******************************SAD prediction**********************************/
pred_SAD =min(min(SAD_a,SAD_b),SAD_c); // pred_SAD_space
ET_Thred = Big_Hexagon_Thd_MB[blocktype];
///////Threshold defined for early termination///////////////////
if (pred_SAD == 0)
{
betaFourth_1=0;
betaFourth_2=0;
}
else
{
betaFourth_1 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_1[blocktype];
betaFourth_2 = Bsize[blocktype]/(pred_SAD*pred_SAD)-AlphaFourth_2[blocktype];
}
}
/***********************************end of init *************************/
// first_step: initial start point prediction
//prediciton using mV of last ref moiton vector
if(list == 0)
{
cand_x = pic_pix_x + (pred_MV_ref[0]/4);
cand_y = pic_pix_y + (pred_MV_ref[1]/4);
SEARCH_ONE_PIXEL_BIPRED
}
//small local search
iXMinNow = best_x;
iYMinNow = best_y;
for (m = 0; m < 4; m++)
{
cand_x = iXMinNow + Diamond_x[m];
cand_y = iYMinNow + Diamond_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION
//sec_step: //Unsymmetrical-cross search
iXMinNow = best_x;
iYMinNow = best_y;
for(i = 1; i < search_range; i+=2)
{
search_step = i;
cand_x = iXMinNow + search_step;
cand_y = iYMinNow ;
SEARCH_ONE_PIXEL_BIPRED
cand_x = iXMinNow - search_step;
cand_y = iYMinNow ;
SEARCH_ONE_PIXEL_BIPRED
}
for(i = 1; i < (search_range/2);i+=2)
{
search_step = i;
cand_x = iXMinNow ;
cand_y = iYMinNow + search_step;
SEARCH_ONE_PIXEL_BIPRED
cand_x = iXMinNow ;
cand_y = iYMinNow - search_step;
SEARCH_ONE_PIXEL_BIPRED
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION
//third_step: // Uneven Multi-Hexagon-grid Search
iXMinNow = best_x;
iYMinNow = best_y;
//sub step1: 5x5 square search
for(pos=1;pos<25;pos++)
{
cand_x = iXMinNow + spiral_search_x[pos];
cand_y = iYMinNow + spiral_search_y[pos];
SEARCH_ONE_PIXEL_BIPRED
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION //added back by xxz
//sub step2: multi-grid-hexagon-search
memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
for(i=1;i<=(input->search_range>>2); i++)
{
for (m = 0; m < 16; m++)
{
cand_x = iXMinNow + temp_Big_Hexagon_x[m];
cand_y = iYMinNow + temp_Big_Hexagon_y[m];
temp_Big_Hexagon_x[m] += Big_Hexagon_x[m];
temp_Big_Hexagon_y[m] += Big_Hexagon_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
if(min_mcost < ET_Thred)
{
goto terminate_step;
}
}
//fourth step: Local Refinement: Extended Hexagon-based Search
fourth_1_step:
for(i=0; i < search_range; i++)
{
iXMinNow = best_x;
iYMinNow = best_y;
for (m = 0; m < 6; m++)
{
cand_x = iXMinNow + Hexagon_x[m];
cand_y = iYMinNow + Hexagon_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
if(best_x == iXMinNow && best_y == iYMinNow)
break;
}
fourth_2_step:
for(i = 0; i < search_range; i++)
{
iXMinNow = best_x;
iYMinNow = best_y;
for (m = 0; m < 4; m++)
{
cand_x = iXMinNow + Diamond_x[m];
cand_y = iYMinNow + Diamond_y[m];
SEARCH_ONE_PIXEL_BIPRED
}
if(best_x == iXMinNow && best_y == iYMinNow)
break;
}
terminate_step:
for (i=0; i < (blocksize_x>>2); i++)
{
for (j=0; j < (blocksize_y>>2); j++)
{
if(list == 0)
{
fastme_l0_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
}
else
{
fastme_l1_cost_bipred[blocktype][(img->pix_y>>2)+block_y+j][(img->pix_x>>2)+block_x+i] = min_mcost;
}
}
}
*mv_x = best_x - pic_pix_x;
*mv_y = best_y - pic_pix_y;
return min_mcost;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -