📄 fast_me.c
字号:
pixel1 = weightSpic * (*ref1_line++);
pixel2 = weightRpic * (*ref2_line++);
#ifdef USE_HP_FILTER//BROUND
if(input->UseHPFilter != 0)
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + (offsetBi<<luma_log_weight_denom) + lround) >> denom));
}
else
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
}
#else
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
#endif
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weightSpic * (*ref1_line++);
pixel2 = weightRpic * (*ref2_line++);
#ifdef USE_HP_FILTER//BROUND
if(input->UseHPFilter != 0)
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + (offsetBi<<luma_log_weight_denom) + lround) >> denom));
}
else
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
}
#else
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
#endif
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weightSpic * (*ref1_line++);
pixel2 = weightRpic * (*ref2_line++);
#ifdef USE_HP_FILTER//BROUND
if(input->UseHPFilter != 0)
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + (offsetBi<<luma_log_weight_denom) + lround) >> denom));
}
else
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
}
#else
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
#endif
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
pixel1 = weightSpic * (*ref1_line++);
pixel2 = weightRpic * (*ref2_line++);
#ifdef USE_HP_FILTER//BROUND
if(input->UseHPFilter != 0)
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + (offsetBi<<luma_log_weight_denom) + lround) >> denom));
}
else
{
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
}
#else
weightedpel = Clip3 (0, img->max_imgpel_value ,((pixel1 + pixel2 + lround) >> denom) + offsetBi);
#endif
bi_diff = (*cur_line++) - weightedpel;
mcost += byte_abs[bi_diff];
if (mcost >= min_mcost) break;
}
if (mcost >= min_mcost) break;
}
return mcost;
}
/*!
************************************************************************
* \brief
* FastIntegerPelBlockMotionSearch: fast pixel block motion search
* this algrithm is called UMHexagonS(see JVT-D016),which includes
* four steps with different kinds of search patterns
* \par Input:
* pel_t** orig_pic, // <-- original picture
* 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 pred_mv_x, // <-- motion vector predictor (x) in sub-pel units
* int pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
* int* mv_x, // --> motion vector (x) - in pel units
* int* mv_y, // --> 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
* \par
* Two macro definitions defined in this program:
* 1. EARLY_TERMINATION: early termination algrithm, refer to JVT-D016.doc
* 2. SEARCH_ONE_PIXEL: search one pixel in search range
* \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
FastIntegerPelBlockMotionSearch (pel_t** orig_pic, // <-- not used
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_x, // <-- motion vector predictor (x) in sub-pel units
short pred_mv_y, // <-- motion vector predictor (y) in sub-pel units
short* mv_x, // --> motion vector (x) - in pel units
short* mv_y, // --> 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 pos, cand_x, cand_y, mcost;
int list_offset = ((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))? img->current_mb_nr%2 ? 4 : 2 : 0;
int mvshift = 2; // motion vector shift for getting sub-pel units
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_x = (pic_pix_x << mvshift) + pred_mv_x; // predicted position x (in sub-pel units)
int pred_y = (pic_pix_y << mvshift) + pred_mv_y; // predicted position y (in sub-pel units)
int center_x = pic_pix_x + *mv_x; // center position x (in pel units)
int center_y = pic_pix_y + *mv_y; // center position y (in pel units)
int best_x = 0, best_y = 0;
int search_step,iYMinNow, iXMinNow;
int i,m,j;
float betaFourth_1,betaFourth_2;
int temp_Big_Hexagon_x[16];// temp for Big_Hexagon_x;
int temp_Big_Hexagon_y[16];// temp for Big_Hexagon_y;
short mb_x = pic_pix_x - img->opix_x;
short mb_y = pic_pix_y - img->opix_y;
short pic_pix_x2 = pic_pix_x >> 2;
short block_x = (mb_x >> 2);
short block_y = (mb_y >> 2);
int ET_Thred = Median_Pred_Thd_MB[blocktype];//ET threshold in use
int *SAD_prediction = fastme_best_cost[blocktype-1];//multi ref SAD prediction
//===== Use weighted Reference for ME ====
int apply_weights = ( (active_pps->weighted_pred_flag && (img->type == P_SLICE || img->type == SP_SLICE)) ||
(active_pps->weighted_bipred_idc && (img->type == B_SLICE)));
height=((img->MbaffFrameFlag)&&(img->mb_data[img->current_mb_nr].mb_field))?img->height/2:img->height;
ref_pic = (apply_weights && input->UseWeightedReferenceME) ? listX[list+list_offset][ref]->imgY_11_w : listX[list+list_offset][ref]->imgY_11;
//===== set function for getting reference picture lines =====
if ((center_x > search_range) && (center_x < img->width -1-search_range-blocksize_x) &&
(center_y > search_range) && (center_y < height-1-search_range-blocksize_y) )
{
get_ref_line = FastLineX;
}
else
{
get_ref_line = UMVLineX;
}
//////allocate memory for search state//////////////////////////
memset(McostState[0],0,(2*input->search_range+1)*(2*input->search_range+1));
//check the center median predictor
cand_x = center_x ;
cand_y = center_y ;
mcost = MV_COST (lambda_factor, mvshift, cand_x, cand_y, pred_x, pred_y);
mcost = PartCalMad(ref_pic, orig_pic, get_ref_line,blocksize_y,blocksize_x,blocksize_x4,mcost,min_mcost,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
}
if(center_x != pic_pix_x || center_y != pic_pix_y)
{
cand_x = pic_pix_x ;
cand_y = pic_pix_y ;
SEARCH_ONE_PIXEL
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
}
}
/***********************************init process*************************/
//for multi ref
if(ref>0 && img->structure == FRAME && min_mcost > ET_Thred && SAD_prediction[pic_pix_x2]<Multi_Ref_Thd_MB[blocktype])
goto terminate_step;
//ET_Thd1: early termination for low motion case
if( min_mcost < ET_Thred)
{
goto terminate_step;
}
else // hybrid search for main search loop
{
/****************************(MV and SAD prediction)********************************/
setup_FME(ref, list, block_y, block_x, blocktype, img->all_mv );
ET_Thred = Big_Hexagon_Thd_MB[blocktype]; // ET_Thd2: early termination Threshold for strong motion
// 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
if(blocktype>1)
{
cand_x = pic_pix_x + (pred_MV_uplayer[0]/4);
cand_y = pic_pix_y + (pred_MV_uplayer[1]/4);
SEARCH_ONE_PIXEL
}
//prediciton using mV of last ref moiton vector
if(pred_MV_ref_flag == 1) //Notes: for interlace case, ref==1 should be added
{
cand_x = pic_pix_x + (pred_MV_ref[0]/4);
cand_y = pic_pix_y + (pred_MV_ref[1]/4);
SEARCH_ONE_PIXEL
}
//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
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION
if(blocktype>6)
goto fourth_1_step;
else
goto sec_step;
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
cand_x = iXMinNow - search_step;
cand_y = iYMinNow ;
SEARCH_ONE_PIXEL
}
for(i = 1; i < (search_range/2);i+=2)
{
search_step = i;
cand_x = iXMinNow ;
cand_y = iYMinNow + search_step;
SEARCH_ONE_PIXEL
cand_x = iXMinNow ;
cand_y = iYMinNow - search_step;
SEARCH_ONE_PIXEL
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION
iXMinNow = best_x;
iYMinNow = best_y;
//third_step: // Uneven Multi-Hexagon-grid Search
//sub step 1: 5x5 squre search
for(pos=1;pos<25;pos++)
{
cand_x = iXMinNow + spiral_search_x[pos];
cand_y = iYMinNow + spiral_search_y[pos];
SEARCH_ONE_PIXEL
}
//early termination alogrithm, refer to JVT-G016
EARLY_TERMINATION
//sub step 2: Multi-Hexagon-grid search
memcpy(temp_Big_Hexagon_x,Big_Hexagon_x,64);
memcpy(temp_Big_Hexagon_y,Big_Hexagon_y,64);
for(i=1;i<=(search_range/4); 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
}
// ET_Thd2: early termination Threshold for strong motion
if(min_mcost < ET_Thred)
{
goto terminate_step;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -