📄 mv_competition.c
字号:
char ***refPic,
short ****tmp_mv,
int block_x,
int block_y,
int blockshape_x,
int blockshape_y)
{
int mb_x = 4*block_x;
int mb_y = 4*block_y;
int mb_nr = img->current_mb_nr;
// int pred_vec=0;
short pmv2[2] = {0,0};
short predictor;
int maxmode=0;
int *predictors=NULL;
int modeblock;
int prediction_mode;
if (img->type == I_SLICE)
maxmode = 1;
else if (img->type == P_SLICE)
{
maxmode = mv_comp.nb_mode_for_mvp;
predictors = mv_comp.predictor_for_mvp;
}
else if (img->type == B_SLICE)
{
maxmode = mv_comp.nb_mode_for_mvb;
predictors = mv_comp.predictor_for_mvb;
}
modeblock= determine_mode_block(blockshape_x,blockshape_y);
predictor =0;
for (prediction_mode = 0; prediction_mode<maxmode; prediction_mode++)
{
if (predictors[prediction_mode] == PRED_H264_MEDIAN)
{
SetMotionVectorPredictorMedian(img,pmv_x, pmv_y, ref_frame, list, refPic, tmp_mv, block_x, block_y, blockshape_x, blockshape_y);
pmv2[0] = *pmv_x;
pmv2[1] = *pmv_y;
}
else if (predictors[prediction_mode] == PRED_ZERO)
{
pmv2[0] = 0;
pmv2[1] = 0;
}
else if (predictors[prediction_mode] == PRED_A)
{
PixelPos block_a;
getLuma4x4Neighbour(img->current_mb_nr, block_x, block_y, -1, 0, &block_a);
pmv2[0] = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][0] : 0;
pmv2[1] = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_B)
{
PixelPos block_b;
getLuma4x4Neighbour(mb_nr, block_x, block_y, 0, -1, &block_b);
pmv2[0] = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][0] : 0;
pmv2[1] = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_C)
{
PixelPos block_c, block_d;
getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, -1, &block_d);
if (mb_y > 0)
{
if (mb_x < 8)
{
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;
pmv2[0] = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][0] : 0;
pmv2[1] = block_c.available ? tmp_mv[list][block_c.pos_y][block_c.pos_x][1] : 0;
}
else if (predictors[prediction_mode] == PRED_COLOCATED)
{
int y=(int)img->current_mb_nr/(img->width/16);
int x=(int)img->current_mb_nr%(img->width/16);
if (img->type == P_SLICE)
{
if (collocated_mv_available(y, x, LIST_0) == TRUE)
{
pmv2[0] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
pmv2[1] = listX[0][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[0][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
}
else
{
pmv2[0] = 0;
pmv2[1] = 0;
}
}
else if (img->type == B_SLICE)
{
// <FTRD : Compatibility with hierarchical B frames
//SetMotionVectorPredictor_collocated_B_SLICE(pmv_x, pmv_y, y, x, list, ref_frame, block_y, block_x);
SetMotionVectorPredictor_collocated_HB_SLICE(pmv_x, pmv_y, y, x, list, ref_frame, block_y, block_x);
// FTRD>
pmv2[0] = *pmv_x;
pmv2[1] = *pmv_y;
}
}
mv_predictors[block_x][block_y][modeblock][prediction_mode][0]=pmv2[0];
mv_predictors[block_x][block_y][modeblock][prediction_mode][1]=pmv2[1];
}
{
short tab_for_skip_mode = 0;
short current_predictor_index;
int pred0_x, pred0_y, current_pred_x, current_pred_y;
pred0_x = mv_predictors[block_x][block_y][modeblock][0][0];
pred0_y = mv_predictors[block_x][block_y][modeblock][0][1];
for(current_predictor_index=1;current_predictor_index<maxmode ;current_predictor_index++)
{
current_pred_x = mv_predictors[block_x][block_y][modeblock][current_predictor_index][0];
current_pred_y = mv_predictors[block_x][block_y][modeblock][current_predictor_index][1];
if ((current_pred_x == pred0_x) && (current_pred_y == pred0_y))
tab_for_skip_mode++;
}
if(tab_for_skip_mode == maxmode-1)
predictor = 0;
else
predictor = readPredictorMV(img,inp);
}
*pmv_x = mv_predictors[block_x][block_y][modeblock][predictor][0];
*pmv_y = mv_predictors[block_x][block_y][modeblock][predictor][1];
}
void SetMotionVectorPredictorMedian (struct img_par *img,
short *pmv_x,
short *pmv_y,
char ref_frame,
byte list,
char ***refPic,
short ****tmp_mv,
int block_x,
int block_y,
int blockshape_x,
int blockshape_y)
{
int mb_x = BLOCK_SIZE*block_x;
int mb_y = BLOCK_SIZE*block_y;
int mb_nr = img->current_mb_nr;
int mv_a, mv_b, mv_c, pred_vec=0;
int mvPredType, rFrameL=0, rFrameU=0, rFrameUR=0;
int hv;
PixelPos block_a, block_b, block_c, block_d;
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, 0, &block_a);
getLuma4x4Neighbour(mb_nr, block_x, block_y, 0, -1, &block_b);
getLuma4x4Neighbour(mb_nr, block_x, block_y, blockshape_x, -1, &block_c);
getLuma4x4Neighbour(mb_nr, block_x, block_y, -1, -1, &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 block_c.available &= 1;
}
else
{
if (mb_x+blockshape_x != 8) block_c.available &= 1;
else block_c.available = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_c.available &= 1;
else block_c.available = 0;
}
}
if (!block_c.available)
{
block_c=block_d;
}
mvPredType = MVPRED_MEDIAN;
if (!img->MbaffFrameFlag)
{
rFrameL = block_a.available ? refPic[list][block_a.pos_y][block_a.pos_x] : -1;
rFrameU = block_b.available ? refPic[list][block_b.pos_y][block_b.pos_x] : -1;
rFrameUR = block_c.available ? refPic[list][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[list][block_a.pos_y][block_a.pos_x]:
refPic[list][block_a.pos_y][block_a.pos_x] * 2:
-1;
rFrameU = block_b.available ?
img->mb_data[block_b.mb_addr].mb_field ?
refPic[list][block_b.pos_y][block_b.pos_x]:
refPic[list][block_b.pos_y][block_b.pos_x] * 2:
-1;
rFrameUR = block_c.available ?
img->mb_data[block_c.mb_addr].mb_field ?
refPic[list][block_c.pos_y][block_c.pos_x]:
refPic[list][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[list][block_a.pos_y][block_a.pos_x] >>1:
refPic[list][block_a.pos_y][block_a.pos_x] :
-1;
rFrameU = block_b.available ?
img->mb_data[block_b.mb_addr].mb_field ?
refPic[list][block_b.pos_y][block_b.pos_x] >>1:
refPic[list][block_b.pos_y][block_b.pos_x] :
-1;
rFrameUR = block_c.available ?
img->mb_data[block_c.mb_addr].mb_field ?
refPic[list][block_c.pos_y][block_c.pos_x] >>1:
refPic[list][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;
}
}
for (hv=0; hv < 2; hv++)
{
if (!img->MbaffFrameFlag || hv==0)
{
mv_a = block_a.available ? tmp_mv[list][block_a.pos_y][block_a.pos_x][hv] : 0;
mv_b = block_b.available ? tmp_mv[list][block_b.pos_y][block_b.pos_x][hv] : 0;
mv_c = block_c.available ? tmp_mv[list][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[list][block_a.pos_y][block_a.pos_x][hv]:
tmp_mv[list][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[list][block_b.pos_y][block_b.pos_x][hv]:
tmp_mv[list][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[list][block_c.pos_y][block_c.pos_x][hv]:
tmp_mv[list][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[list][block_a.pos_y][block_a.pos_x][hv] * 2:
tmp_mv[list][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[list][block_b.pos_y][block_b.pos_x][hv] * 2:
tmp_mv[list][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[list][block_c.pos_y][block_c.pos_x][hv] * 2:
tmp_mv[list][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-min(mv_a,min(mv_b,mv_c))-max(mv_a,max(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;
}
if (hv==0) *pmv_x = pred_vec;
else *pmv_y = pred_vec;
}
}
int determine_mode_block(int blockshape_x,int blockshape_y)
{
if((blockshape_x==16) && ( blockshape_y==16))
return 1;
if((blockshape_x==16) && ( blockshape_y==8))
return 2;
if((blockshape_x==8) && ( blockshape_y==16))
return 3;
if((blockshape_x==8) && ( blockshape_y==8))
return 4;
if((blockshape_x==8) && ( blockshape_y==4))
return 5;
if((blockshape_x==4) && ( blockshape_y==8))
return 6;
if((blockshape_x==4) && ( blockshape_y==4))
return 7;
return 0;
}
void SetMotionVectorPredictor_collocated_B_SLICE (short *pmv_x,
short *pmv_y,
int y,
int x,
int list,
int ref_frame,
int block_y,
int block_x)
{
int colocated_MV_x, colocated_MV_y;
int b_frame_to_code = Bframe_ctr%successive_Bframe;
*pmv_x = 0;
*pmv_y = 0;
if(list==LIST_0)
{
if((b_frame_to_code)==0)//if this B_frame is the first B_frame of the GOP
{
if (collocated_mv_available(y, x, LIST_1) == TRUE)
{
colocated_MV_x = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][0] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
colocated_MV_y = listX[LIST_1][0]->mv[LIST_0][y*4+block_y][x*4+block_x][1] * (ref_frame+1) / (listX[LIST_1][0]->ref_idx[0][y*4+block_y][x*4+block_x] + 1);
*pmv_x = colocated_MV_x/(successive_Bframe+1)+(ref_frame)*colocated_MV_x;
*pmv_y = colocated_MV_y/(successive_Bframe+1)+(ref_frame)*colocated_MV_y;
}
else
{
*pmv_x = 0;
*pmv_y = 0;
}
}
else
{
if (collocated_mv_available_previous_B_frame(y, x, LIST_1) == TRUE)
{
colocated_MV_x = mv_previous_B_frame[LIST_1][y*4+block_y][x*4+block_x][0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -