📄 me_umhex.c
字号:
//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<=(params->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;
}
}
}
mv1->mv_x = best_x - pic_pix_x;
mv1->mv_y = best_y - pic_pix_y;
return min_mcost;
}
/*!
************************************************************************
* \brief
* Set motion vector predictor
************************************************************************
*/
void UMHEXSetMotionVectorPredictor (Macroblock *currMB,
short pmv[2],
char **refPic,
short ***tmp_mv,
short ref_frame,
int list,
int mb_x,
int mb_y,
int blockshape_x,
int blockshape_y,
int *search_range)
{
int mv_a, mv_b, mv_c, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
PixelPos block_a, block_b, block_c, block_d;
// added for bipred mode
int *** fastme_l0_cost_flag = (bipred_flag ? fastme_l0_cost_bipred:fastme_l0_cost);
int *** fastme_l1_cost_flag = (bipred_flag ? fastme_l1_cost_bipred:fastme_l1_cost);
//Dynamic Search Range
int dsr_temp_search_range[2];
int dsr_mv_avail, dsr_mv_max, dsr_mv_sum, dsr_small_search_range;
int *mb_size = img->mb_size[IS_LUMA];
// neighborhood SAD init
SAD_a=0;
SAD_b=0;
SAD_c=0;
SAD_d=0;
get4x4Neighbour(currMB, mb_x - 1 , mb_y , mb_size, &block_a);
get4x4Neighbour(currMB, mb_x , mb_y - 1, mb_size, &block_b);
get4x4Neighbour(currMB, mb_x + blockshape_x, mb_y - 1, mb_size, &block_c);
get4x4Neighbour(currMB, mb_x - 1 , mb_y - 1, mb_size, &block_d);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_c.available = 0;
}
else
{
if (mb_x+blockshape_x == 8) block_c.available = 0;
}
}
else
{
if (mb_x+blockshape_x == 16) block_c.available = 0;
}
}
if (!block_c.available)
{
block_c=block_d;
}
mvPredType = MVPRED_MEDIAN;
if (!img->MbaffFrameFlag)
{
rFrameL = block_a.available ? refPic[block_a.pos_y][block_a.pos_x] : -1;
rFrameU = block_b.available ? refPic[block_b.pos_y][block_b.pos_x] : -1;
rFrameUR = block_c.available ? refPic[block_c.pos_y][block_c.pos_x] : -1;
}
else
{
if (img->mb_data[img->current_mb_nr].mb_field)
{
rFrameL = block_a.available
? (img->mb_data[block_a.mb_addr].mb_field
? refPic[block_a.pos_y][block_a.pos_x]
: refPic[block_a.pos_y][block_a.pos_x] * 2) : -1;
rFrameU = block_b.available
? (img->mb_data[block_b.mb_addr].mb_field
? refPic[block_b.pos_y][block_b.pos_x]
: refPic[block_b.pos_y][block_b.pos_x] * 2) : -1;
rFrameUR = block_c.available
? (img->mb_data[block_c.mb_addr].mb_field
? refPic[block_c.pos_y][block_c.pos_x]
: refPic[block_c.pos_y][block_c.pos_x] * 2) : -1;
}
else
{
rFrameL = block_a.available
? (img->mb_data[block_a.mb_addr].mb_field
? refPic[block_a.pos_y][block_a.pos_x] >>1
: refPic[block_a.pos_y][block_a.pos_x]) : -1;
rFrameU = block_b.available ?
img->mb_data[block_b.mb_addr].mb_field ?
refPic[block_b.pos_y][block_b.pos_x] >>1:
refPic[block_b.pos_y][block_b.pos_x] :
-1;
rFrameUR = block_c.available ?
img->mb_data[block_c.mb_addr].mb_field ?
refPic[block_c.pos_y][block_c.pos_x] >>1:
refPic[block_c.pos_y][block_c.pos_x] :
-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( 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;
}
}
// neighborhood SAD prediction
if((params->UMHexDSR == 1 || params->BiPredMotionEstimation == 1))
{
SAD_a = block_a.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_a.pos_y][block_a.pos_x])) : 0;
SAD_b = block_b.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_b.pos_y][block_b.pos_x])) : 0;
SAD_d = block_d.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_d.pos_y][block_d.pos_x])) : 0;
SAD_c = block_c.available ? ((list==1) ? (fastme_l1_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x]) : (fastme_l0_cost_flag[UMHEX_blocktype][block_c.pos_y][block_c.pos_x])) : SAD_d;
}
for (hv=0; hv < 2; hv++)
{
if (!img->MbaffFrameFlag || hv==0)
{
mv_a = block_a.available ? tmp_mv[block_a.pos_y][block_a.pos_x][hv] : 0;
mv_b = block_b.available ? tmp_mv[block_b.pos_y][block_b.pos_x][hv] : 0;
mv_c = block_c.available ? tmp_mv[block_c.pos_y][block_c.pos_x][hv] : 0;
}
else
{
if (img->mb_data[img->current_mb_nr].mb_field)
{
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field
? tmp_mv[block_a.pos_y][block_a.pos_x][hv]
: tmp_mv[block_a.pos_y][block_a.pos_x][hv] / 2
: 0;
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field
? tmp_mv[block_b.pos_y][block_b.pos_x][hv]
: tmp_mv[block_b.pos_y][block_b.pos_x][hv] / 2
: 0;
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field
? tmp_mv[block_c.pos_y][block_c.pos_x][hv]
: tmp_mv[block_c.pos_y][block_c.pos_x][hv] / 2
: 0;
}
else
{
mv_a = block_a.available ? img->mb_data[block_a.mb_addr].mb_field
? tmp_mv[block_a.pos_y][block_a.pos_x][hv] * 2
: tmp_mv[block_a.pos_y][block_a.pos_x][hv]
: 0;
mv_b = block_b.available ? img->mb_data[block_b.mb_addr].mb_field
? tmp_mv[block_b.pos_y][block_b.pos_x][hv] * 2
: tmp_mv[block_b.pos_y][block_b.pos_x][hv]
: 0;
mv_c = block_c.available ? img->mb_data[block_c.mb_addr].mb_field
? tmp_mv[block_c.pos_y][block_c.pos_x][hv] * 2
: tmp_mv[block_c.pos_y][block_c.pos_x][hv]
: 0;
}
}
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_b.available || block_c.available))
{
pred_vec = mv_a;
}
else
{
pred_vec = mv_a+mv_b+mv_c-imin(mv_a,imin(mv_b,mv_c))-imax(mv_a,imax(mv_b,mv_c));
}
break;
case MVPRED_L:
pred_vec = mv_a;
break;
case MVPRED_U:
pred_vec = mv_b;
break;
case MVPRED_UR:
pred_vec = mv_c;
break;
default:
break;
}
pmv[hv] = pred_vec;
//Dynamic Search Range
if (params->UMHexDSR)
{
dsr_mv_avail=block_a.available+block_b.available+block_c.available;
if(dsr_mv_avail < 2)
{
dsr_temp_search_range[hv] = params->search_range;
}
else
{
dsr_mv_max = imax(iabs(mv_a),imax(iabs(mv_b),iabs(mv_c)));
dsr_mv_sum = (iabs(mv_a)+iabs(mv_b)+iabs(mv_c));
if(dsr_mv_sum == 0) dsr_small_search_range = (params->search_range + 4) >> 3;
else if(dsr_mv_sum > 3 ) dsr_small_search_range = (params->search_range + 2) >>2;
else dsr_small_search_range = (3*params->search_range + 8) >> 4;
dsr_temp_search_range[hv]=imin(params->search_range,imax(dsr_small_search_range,dsr_mv_max<<1));
if(imax(SAD_a,imax(SAD_b,SAD_c)) > Threshold_DSR_MB[UMHEX_blocktype])
dsr_temp_search_range[hv] = params->search_range;
}
}
}
//Dynamic Search Range
if (params->UMHexDSR)
{
dsr_new_search_range = imax(dsr_temp_search_range[0],dsr_temp_search_range[1]);
if (params->full_search == 2)
*search_range = dsr_new_search_range;
else if (params->full_search == 1)
*search_range = dsr_new_search_range / (imin(ref_frame,1)+1);
else
*search_range = dsr_new_search_range / ((imin(ref_frame,1)+1) * imin(2,BlockType_LUT[(blockshape_y >> 2) - 1][(blockshape_x >> 2) - 1]));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -