📄 macroblock.c
字号:
dP->readSyntaxElement(&currSE,img,dP);
currMB->c_ipred_mode = currSE.value1;
if (currMB->c_ipred_mode < DC_PRED_8 || currMB->c_ipred_mode > PLANE_8)
{
error("illegal chroma intra pred mode!\n", 600);
}
}
}
/*!
************************************************************************
* \brief
* Set motion vector predictor
************************************************************************
*/
void SetMotionVectorPredictor (struct img_par *img,
short pmv[2],
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, rFrameU, rFrameUR;
int hv;
PixelPos block_a, block_b, block_c, block_d;
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y, &block_a);
getLuma4x4Neighbour(mb_nr, mb_x, mb_y - 1, &block_b);
getLuma4x4Neighbour(mb_nr, mb_x + blockshape_x, mb_y - 1, &block_c);
getLuma4x4Neighbour(mb_nr, mb_x - 1, mb_y - 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
{
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[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-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;
}
}
/*!
************************************************************************
* \brief
* Set context for reference frames
************************************************************************
*/
int BType2CtxRef (int btype)
{
return (btype < 4 ? 0 : 1);
}
/*!
************************************************************************
* \brief
* Read motion info
************************************************************************
*/
void readMotionInfoFromNAL (struct img_par *img, struct inp_par *inp)
{
int i,j,k;
int step_h,step_v;
int curr_mvd;
int mb_nr = img->current_mb_nr;
Macroblock *currMB = &img->mb_data[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;
char refframe;
short pmv[2];
int j4, i4, ii,jj;
int vec;
int mv_scale = 0;
int flag_mode;
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0;
byte ** moving_block;
short **** co_located_mv;
char *** co_located_ref_idx;
int64 *** co_located_ref_id;
if ((img->MbaffFrameFlag)&&(currMB->mb_field))
{
if(mb_nr&0x01)
{
moving_block = Co_located->bottom_moving_block;
co_located_mv = Co_located->bottom_mv;
co_located_ref_idx = Co_located->bottom_ref_idx;
co_located_ref_id = Co_located->bottom_ref_pic_id;
}
else
{
moving_block = Co_located->top_moving_block;
co_located_mv = Co_located->top_mv;
co_located_ref_idx = Co_located->top_ref_idx;
co_located_ref_id = Co_located->top_ref_pic_id;
}
}
else
{
moving_block = Co_located->moving_block;
co_located_mv = Co_located->mv;
co_located_ref_idx = Co_located->ref_idx;
co_located_ref_id = Co_located->ref_pic_id;
}
if (bframe && IS_P8x8 (currMB))
{
if (img->direct_spatial_mv_pred_flag)
{
char l0_rFrame,l1_rFrame;
short pmvl0[2]={0,0}, pmvl1[2]={0,0};
prepare_direct_params(dec_picture, img, mb_nr, pmvl0, pmvl1, &l0_rFrame, &l1_rFrame);
for (i=0;i<4;i++)
{
if (currMB->b8mode[i] == 0)
{
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
{
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
{
int j6 = img->block_y_aff + j;
j4 = img->block_y+j;
i4 = img->block_x+k;
if (l0_rFrame >= 0)
{
if (!l0_rFrame && ((!moving_block[j6][i4]) && (!listX[LIST_1 + list_offset][0]->is_long_term)))
{
dec_picture->mv [LIST_0][j4][i4][0] = 0;
dec_picture->mv [LIST_0][j4][i4][1] = 0;
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
}
else
{
dec_picture->mv [LIST_0][j4][i4][0] = pmvl0[0];
dec_picture->mv [LIST_0][j4][i4][1] = pmvl0[1];
dec_picture->ref_idx[LIST_0][j4][i4] = l0_rFrame;
}
}
else
{
dec_picture->mv [LIST_0][j4][i4][0] = 0;
dec_picture->mv [LIST_0][j4][i4][1] = 0;
dec_picture->ref_idx[LIST_0][j4][i4] = -1;
}
if (l1_rFrame >= 0)
{
if (l1_rFrame==0 && ((!moving_block[j6][i4])&& (!listX[LIST_1 + list_offset][0]->is_long_term)))
{
dec_picture->mv [LIST_1][j4][i4][0] = 0;
dec_picture->mv [LIST_1][j4][i4][1] = 0;
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
}
else
{
dec_picture->mv [LIST_1][j4][i4][0] = pmvl1[0];
dec_picture->mv [LIST_1][j4][i4][1] = pmvl1[1];
dec_picture->ref_idx[LIST_1][j4][i4] = l1_rFrame;
}
}
else
{
dec_picture->mv [LIST_1][j4][i4][0] = 0;
dec_picture->mv [LIST_1][j4][i4][1] = 0;
dec_picture->ref_idx[LIST_1][j4][i4] = -1;
}
if (l0_rFrame <0 && l1_rFrame <0)
{
dec_picture->ref_idx[LIST_0][j4][i4] = 0;
dec_picture->ref_idx[LIST_1][j4][i4] = 0;
}
}
}
}
}
}
else
{
for (i=0;i<4;i++)
{
if (currMB->b8mode[i] == 0)
{
for(j=2*(i>>1);j<2*(i>>1)+2;j++)
{
for(k=2*(i&0x01);k<2*(i&0x01)+2;k++)
{
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (mb_nr&0x01) ? 4 : 2 : 0;
int refList = co_located_ref_idx[LIST_0 ][img->block_y_aff+j][img->block_x+k]== -1 ? LIST_1 : LIST_0;
int ref_idx = co_located_ref_idx[refList][img->block_y_aff + j][img->block_x + k];
int mapped_idx=-1, iref;
if (ref_idx == -1)
{
dec_picture->ref_idx [LIST_0][img->block_y + j][img->block_x + k] = 0;
dec_picture->ref_idx [LIST_1][img->block_y + j][img->block_x + k] = 0;
}
else
{
for (iref=0;iref<imin(img->num_ref_idx_l0_active,listXsize[LIST_0 + list_offset]);iref++)
{
int curr_mb_field = ((img->MbaffFrameFlag)&&(currMB->mb_field));
if(img->structure==0 && curr_mb_field==0)
{
// If the current MB is a frame MB and the colocated is from a field picture,
// then the co_located_ref_id may have been generated from the wrong value of
// frame_poc if it references it's complementary field, so test both POC values
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -