📄 macroblock.c
字号:
static void SetMotionVectorPredictor (struct img_par *img,
int *pmv_x,
int *pmv_y,
int ref_frame,
int **refFrArr,
int ***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 pic_block_x = img->block_x + block_x;
int pic_block_y = img->block_y + block_y;
int mb_width = img->width/16;
int mb_nr = img->map_mb_nr;
int mb_available_up = (img->mb_y == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width ].slice_nr);
int mb_available_left = (img->mb_x == 0 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-1 ].slice_nr);
int mb_available_upleft = (img->mb_x == 0) ? 0 : ((img->mb_y == 0) ? 0 :
(img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr));
int mb_available_upright = (img->mb_y == 0) ? 0 : ((img->mb_x >= (mb_width-1)) ? 0 :
(img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr));
int block_available_up, block_available_left, block_available_upright, block_available_upleft;
int mv_a, mv_b, mv_c, mv_d, pred_vec=0;
int mvPredType, rFrameL, rFrameU, rFrameUR;
int hv;
if (img->structure==FRAME && img->mb_field)
{
if (img->current_mb_nr%2==0) // top field
{
if (!(img->type==B_SLICE))
tmp_mv = img->mv_top;
pic_block_x = img->block_x + (mb_x>>2);
pic_block_y = img->block_y/2 + (mb_y>>2);
}
else
{
if (!(img->type==B_SLICE))
tmp_mv = img->mv_bot;
pic_block_x = img->block_x + (mb_x>>2);
pic_block_y = (img->block_y-4)/2 + (mb_y>>2);
mb_available_up = (img->mb_y == 1 ) ? 0 : (img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width ].slice_nr);
mb_available_upleft = (img->mb_x == 0) ? 0 : ((img->mb_y == 1) ? 0 :
(img->mb_data[mb_nr].slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr));
mb_available_upright = 0;
}
}
else
{
if(img->mb_frame_field_flag)
mb_available_upright = (img->mb_y%2) ? 0:mb_available_upright; // Not sure if this is right
}
/* D B C */
/* A X */
/* 1 A, B, D are set to 0 if unavailable */
/* 2 If C is not available it is replaced by D */
block_available_up = mb_available_up || (mb_y > 0);
block_available_left = mb_available_left || (mb_x > 0);
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_available_upright = 0;
else block_available_upright = 1;
}
else
{
if (mb_x+blockshape_x != 8) block_available_upright = 1;
else block_available_upright = 0;
}
}
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 : mb_available_up);
}
else if (mb_y > 0)
{
block_available_upleft = mb_available_left;
}
else
{
block_available_upleft = mb_available_upleft;
}
mvPredType = MVPRED_MEDIAN;
rFrameL = block_available_left ? refFrArr[pic_block_y] [pic_block_x-1 ] : -1;
rFrameU = block_available_up ? refFrArr[pic_block_y-1][pic_block_x ] : -1;
rFrameUR = block_available_upright ? refFrArr[pic_block_y-1][pic_block_x+blockshape_x/4] :
block_available_upleft ? refFrArr[pic_block_y-1][pic_block_x-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
else 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++)
{
mv_a = block_available_left ? tmp_mv[4+pic_block_x-1 ][pic_block_y ][hv] : 0;
mv_b = block_available_up ? tmp_mv[4+pic_block_x ][pic_block_y-1][hv] : 0;
mv_d = block_available_upleft ? tmp_mv[4+pic_block_x-1 ][pic_block_y-1][hv] : 0;
mv_c = block_available_upright ? tmp_mv[4+pic_block_x+blockshape_x/4][pic_block_y-1][hv] : mv_d;
switch (mvPredType)
{
case MVPRED_MEDIAN:
if(!(block_available_upleft || block_available_up || block_available_upright))
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;
}
if (img->structure==FRAME && img->mb_field)
tmp_mv = img->mv_frm;
}
/*!
************************************************************************
* \brief
* Set context for reference frames
************************************************************************
*/
int
BType2CtxRef (int btype)
{
if (btype<4) return 0;
else return 1;
}
/*!
************************************************************************
* \brief
* Read motion info
************************************************************************
*/
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
{
int i,j,k,l,m;
int step_h,step_v;
int curr_mvd;
// int mb_nr = img->current_mb_nr; //GB Falsch
Macroblock *currMB = &img->mb_data[img->map_mb_nr];
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[currSlice->dp_mode];
int bframe = (img->type==B_SLICE);
int partmode = (IS_P8x8(currMB)?4:currMB->mb_type);
int step_h0 = BLOCK_STEP [partmode][0];
int step_v0 = BLOCK_STEP [partmode][1];
int mv_mode, i0, j0, refframe;
int pmv[2];
int j4, i4, ii,jj;
int vec;
int iTRb,iTRp;
int mv_scale;
int frame_no_next_P, frame_no_B, delta_P;
int ref;
int img_block_y;
int use_scaled_mv;
int fw_refframe,current_tr;
int **fwRefFrArr = img->fw_refFrArr;
int **bwRefFrArr = img->bw_refFrArr;
int ***fw_mv = img->fw_mv;
int ***bw_mv = img->bw_mv;
int **moving_block_dir = moving_block;
int ***fw_mv_array, ***bw_mv_array;
int j6;
int flag_mode;
if (bframe && IS_P8x8 (currMB))
{
if (img->direct_type && img->mb_frame_field_flag )
{
if (!img->mb_field)
{
fwRefFrArr= img->fw_refFrArr_frm;
bwRefFrArr= img->bw_refFrArr_frm;
fw_mv=img->fw_mv_frm;
bw_mv=img->bw_mv_frm;
fw_mv_array = img->dfMV;
bw_mv_array = img->dbMV;
}
else if (img->current_mb_nr%2 )
{
fwRefFrArr= img->fw_refFrArr_bot;
bwRefFrArr= img->bw_refFrArr_bot;
fw_mv=img->fw_mv_bot;
bw_mv=img->bw_mv_bot;
moving_block_dir = moving_block_bot;
fw_mv_array = img->dfMV_bot;
bw_mv_array = img->dbMV_bot;
}
else
{
fwRefFrArr=img->fw_refFrArr_top ;
bwRefFrArr=img->bw_refFrArr_top ;
fw_mv=img->fw_mv_top;
bw_mv=img->bw_mv_top;
moving_block_dir = moving_block_top;
fw_mv_array = img->dfMV_top;
bw_mv_array = img->dbMV_top;
}
}
if (img->direct_type)
{
int pic_blockx = img->block_x;
int pic_blocky = (img->mb_frame_field_flag && img->mb_field)? ((img->current_mb_nr%2)?img->block_y/2-BLOCK_SIZE / 2:img->block_y/2):img->block_y;
int mb_nr = img->map_mb_nr; //GB current_mb_nr; //HIER
int mb_width = img->width/16;
int mb_available_up = (img->mb_y == 0 || pic_blocky == 0 ) ? 0 : (img->mb_frame_field_flag? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width].slice_nr));
int mb_available_left = (img->mb_x == 0 ) ? 0 : (currMB->slice_nr == img->mb_data[mb_nr-1].slice_nr);
int mb_available_upleft = (img->mb_x == 0 || img->mb_y == 0 || pic_blocky == 0) ? 0 : (img->mb_frame_field_flag)? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width-1].slice_nr);
int mb_available_upright = (img->mb_frame_field_flag && img->current_mb_nr%2)?0:(img->mb_x >= mb_width-1 ||
img->mb_y == 0 || pic_blocky == 0 ) ? 0 : (img->mb_frame_field_flag)? 1 :(currMB->slice_nr == img->mb_data[mb_nr-mb_width+1].slice_nr);
int fw_rFrameL = mb_available_left ? fwRefFrArr[pic_blocky] [pic_blockx-1] : -1;
int fw_rFrameU = mb_available_up ? fwRefFrArr[pic_blocky-1][pic_blockx] : -1;
int fw_rFrameUL = mb_available_upleft ? fwRefFrArr[pic_blocky-1][pic_blockx-1] : -1;
int fw_rFrameUR = mb_available_upright ? fwRefFrArr[pic_blocky-1][pic_blockx+4] : fw_rFrameUL;
int bw_rFrameL = mb_available_left ? bwRefFrArr[pic_blocky] [pic_blockx-1] : -1;
int bw_rFrameU = mb_available_up ? bwRefFrArr[pic_blocky-1][pic_blockx] : -1;
int bw_rFrameUL = mb_available_upleft ? bwRefFrArr[pic_blocky-1][pic_blockx-1] : -1;
int bw_rFrameUR = mb_available_upright ? bwRefFrArr[pic_blocky-1][pic_blockx+4] : bw_rFrameUL;
int fw_rFrame,bw_rFrame;
int pmvfw[2]={0,0},pmvbw[2]={0,0};
int j5=0;
if (!fw_rFrameL || !fw_rFrameU || !fw_rFrameUR)
fw_rFrame=0;
else
fw_rFrame=min(fw_rFrameL&15,min(fw_rFrameU&15,fw_rFrameUR&15));
if(img->num_ref_pic_active_bwd>1 && (bw_rFrameL==1 || bw_rFrameU==1 || bw_rFrameUR==1))
bw_rFrame=1;
else if (!bw_rFrameL || !bw_rFrameU || !bw_rFrameUR)
bw_rFrame=0;
else
bw_rFrame=min(bw_rFrameL&15,min(bw_rFrameU&15,bw_rFrameUR&15));
if (fw_rFrame !=15)
SetMotionVectorPredictor (img, pmvfw, pmvfw+1, fw_rFrame, fwRefFrArr, fw_mv, 0, 0, 16, 16);
if (bw_rFrame !=15)
SetMotionVectorPredictor (img, pmvbw, pmvbw+1, bw_rFrame, bwRefFrArr, bw_mv, 0, 0, 16, 16);
for (i=0;i<4;i++)
{
if (currMB->b8mode[i] == 0)
for(j=2*(i/2);j<2*(i/2)+2;j++)
for(k=2*(i%2);k<2*(i%2)+2;k++)
{
j4 = img->block_y+j;
j6 = pic_blocky+j;
i4 = img->block_x+k;
if (img->mb_frame_field_flag)
{
j5 = img->block_y / 2 + j;
if (img->current_mb_nr%2)
j5 -= BLOCK_SIZE / 2;
}
if (!(img->mb_frame_field_flag && img->mb_field))
{
if (fw_rFrame !=15)
{
if (!fw_rFrame && !moving_block_dir[j6][i4])
{
img->fw_mv[i4+BLOCK_SIZE][j4][0]=img->dfMV[i4+BLOCK_SIZE][j4][0] = 0;
img->fw_mv[i4+BLOCK_SIZE][j4][1]=img->dfMV[i4+BLOCK_SIZE][j4][1] = 0;
if (img->mb_frame_field_flag)
{
if (img->current_mb_nr%2 == 0)
{
img->dfMV_top[i4+BLOCK_SIZE][j5][0]=img->fw_mv_top[i4+BLOCK_SIZE][j5][0]=0;
img->dfMV_top[i4+BLOCK_SIZE][j5][1]=img->fw_mv_top[i4+BLOCK_SIZE][j5][1]=0;
img->fw_refFrArr_top[j5][i4]=0;
}
else
{
img->dfMV_bot[i4+BLOCK_SIZE][j5][0]=img->fw_mv_bot[i4+BLOCK_SIZE][j5][0]=0;
img->dfMV_bot[i4+BLOCK_SIZE][j5][1]=img->fw_mv_bot[i4+BLOCK_SIZE][j5][1]=0;
img->fw_refFrArr_bot[j5][i4]=0;
}
}
if (img->structure == TOP_FIELD) //! Note that this seems to be unecessary for different img->structure.
fwRefFrArr[j4][i4] = 0; //! copied to be consistent with temporal direct, just in case there is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -