📄 macroblock.cpp
字号:
}
}
return;
}
if(currMB->mb_type!=IPCM)
{
// intra prediction modes for a macroblock 4x4 **********************************************
read_ipred_modes(img);
// read inter frame vector data *********************************************************
readMotionInfoFromNAL (img);
// read CBP and Coeffs ***************************************************************
readCBPandCoeffsFromNAL (img);
return;
}
else
{
//read pcm_alignment_zero_bit and pcm_byte[i]
// here dP is assigned with the same dP as SE_MBTYPE, because IPCM syntax is in the
// same category as MBTYPE
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
readIPCMcoeffsFromNAL(img,dP);
}
}
/*!
************************************************************************
* \brief
* Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
* (for IPCM CABAC and IPCM CAVLC 28/11/2003)
*
* \author
* Dong Wang <Dong.Wang@bristol.ac.uk>
************************************************************************
*/
void readIPCMcoeffsFromNAL(struct img_par *img, struct datapartition *dP)
{
SyntaxElement currSE;
unsigned int i,j;
//read bits to let stream byte aligned
i=(dP->bitstream->frame_bitoffset)&0x0111;
if(i!=0)
{
currSE.len=8-i;
readSyntaxElement_FLC(&currSE, dP->bitstream);
}
//read luma and chroma IPCM coefficients
currSE.len=8;
for(i=0;i<16;i++)
for(j=0;j<16;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i>>2][j>>2][i&0x0003][j&0x0003]=currSE.value1;
}
for(i=0;i<8;i++)
for(j=0;j<8;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i>>2][j>>2+4][i&0x0003][j&0x0003]=currSE.value1;
}
for(i=0;i<8;i++)
for(j=0;j<8;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i>>2+2][j>>2+4][i&0x0003][j&0x0003]=currSE.value1;
}
}
void read_ipred_modes(struct img_par *img)
{
int b8,i,j,bi,bj,bx,by,dec;
SyntaxElement currSE;
Slice *currSlice;
DataPartition *dP;
int *partMap;
Macroblock *currMB;
int mostProbableIntraPredMode;
int upIntraPredMode;
int leftIntraPredMode;
int IntraChromaPredModeFlag;
PixelPos left_block;
PixelPos top_block;
currMB = &img->mb_data[img->current_mb_nr];
IntraChromaPredModeFlag = IS_INTRA(currMB);
currSlice = img->currentSlice;
partMap = assignSE2partition[currSlice->dp_mode];
currSE.type = SE_INTRAPREDMODE;
//intra4x4_pred_mode
dP = &(currSlice->partArr[partMap[currSE.type]]);
if(currMB->mb_type == I4MB)
{
for(b8=0;b8<4;b8++) //loop 8x8 blocks
{
// IntraChromaPredModeFlag = 1;
for(j=0;j<2;j++) //loop subblocks
for(i=0;i<2;i++)
{
//get from stream
readSyntaxElement_Intra4x4PredictionMode(&currSE,dP);
bx = ((b8&1)<<1) + i;
by = (b8&2) + j;
getLuma4x4Neighbour(img->current_mb_nr, bx, by, -1, 0, &left_block);
getLuma4x4Neighbour(img->current_mb_nr, bx, by, 0, -1, &top_block);
//get from array and decode
bi = img->block_x + bx;
bj = img->block_y + by;
if (img->constrained_intra_pred_flag)
{
left_block.available = left_block.available ? img->intra_block[left_block.mb_addr] : 0;
top_block.available = top_block.available ? img->intra_block[top_block.mb_addr] : 0;
}
upIntraPredMode = (top_block.available) ? img->ipredmode[top_block.pos_x ][top_block.pos_y ] : -1;
leftIntraPredMode = (left_block.available) ? img->ipredmode[left_block.pos_x][left_block.pos_y] : -1;
mostProbableIntraPredMode = (upIntraPredMode < 0 || leftIntraPredMode < 0) ? DC_PRED : upIntraPredMode < leftIntraPredMode ? upIntraPredMode : leftIntraPredMode;
dec = (currSE.value1 == -1) ? mostProbableIntraPredMode : currSE.value1 + (currSE.value1 >= mostProbableIntraPredMode);
//set
img->ipredmode[bi][bj]=dec;
}
}
}
if (IntraChromaPredModeFlag)
{
currSE.type = SE_INTRAPREDMODE;
//intra_chroma_pred_mode
dP = &(currSlice->partArr[partMap[currSE.type]]);
currSE.mapping = linfo_ue;
dP->readSyntaxElement(&currSE,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
************************************************************************
*/
static void SetMotionVectorPredictor (struct img_par *img,
int *pmv_x,
int *pmv_y,
int ref_frame,
int list,
int ***refPic,
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 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, 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;
rFrameL = block_a.available ? refPic[list][block_a.pos_x][block_a.pos_y] : -1;
rFrameU = block_b.available ? refPic[list][block_b.pos_x][block_b.pos_y] : -1;
rFrameUR = block_c.available ? refPic[list][block_c.pos_x][block_c.pos_y] : -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) && (rFrameL == ref_frame))
mvPredType = MVPRED_L;
else if((mb_x != 0) && (rFrameUR == ref_frame))
mvPredType = MVPRED_UR;
}
else if(blockshape_x == 16 && blockshape_y == 8)
{
if((mb_y == 0)&& (rFrameU == ref_frame))
mvPredType = MVPRED_U;
else if((mb_y != 0)&& (rFrameL == ref_frame))
mvPredType = MVPRED_L;
}
for (hv=0; hv < 2; hv++)
{
mv_a = block_a.available ? tmp_mv[list][block_a.pos_x][block_a.pos_y][hv] : 0;
mv_b = block_b.available ? tmp_mv[list][block_b.pos_x][block_b.pos_y][hv] : 0;
mv_c = block_c.available ? tmp_mv[list][block_c.pos_x][block_c.pos_y][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;
}
}
/*!
************************************************************************
* \brief
* Read motion info
************************************************************************
*/
void readMotionInfoFromNAL (struct img_par *img)
{
int i,j,k;
int step_h,step_v;
int curr_mvd;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement currSE;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[currSlice->dp_mode];
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 flag_mode;
// If multiple ref. frames, read reference frame for the MB *********************************
if(img->num_ref_idx_l0_active>1)
{
flag_mode = ( img->num_ref_idx_l0_active == 2 ? 1 : 0);
currSE.type = SE_REFFRAME;
dP = &(currSlice->partArr[partMap[SE_REFFRAME]]);
currSE.mapping = linfo_ue;
for (j0=0; j0<4; j0+=step_v0)
{
for (i0=0; i0<4; i0+=step_h0)
{
k=2*(j0/2)+(i0/2);
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
{
//ref_idx_l0
if (!IS_P8x8 (currMB) || (!img->allrefzero))
{
if( (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) && flag_mode )
{
currSE.len = 1;
readSyntaxElement_FLC(&currSE, dP->bitstream);
currSE.value1 = 1 - currSE.value1;
}
else
{
currSE.value2 = LIST_0;
dP->readSyntaxElement (&currSE,dP);
}
refframe = currSE.value1;
}
else
{
refframe = 0;
}
for (j=j0; j<j0+step_v0;j++)
for (i=i0; i<i0+step_h0;i++)
{
dec_picture->ref_idx[LIST_0][img->block_x + i][img->block_y + j] = refframe;
}
}
}
}
}
else
{
for (j0=0; j0<4; j0+=step_v0)
{
for (i0=0; i0<4; i0+=step_h0)
{
k=2*(j0/2)+(i0/2);
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && currMB->b8mode[k]!=0)
{
for (i=i0; i<i0+step_h0;i++)
for (j=j0; j<j0+step_v0;j++)
dec_picture->ref_idx[LIST_0][img->block_x + i][img->block_y + j] = 0;
}
}
}
}
//===== READ FORWARD MOTION VECTORS =====
currSE.type = SE_MVD;
dP = &(currSlice->partArr[partMap[SE_MVD]]);
currSE.mapping = linfo_se;
for (j0=0; j0<4; j0+=step_v0)
for (i0=0; i0<4; i0+=step_h0)
{
k=2*(j0/2)+(i0/2);
if ((currMB->b8pdir[k]==0 || currMB->b8pdir[k]==2) && (currMB->b8mode[k] !=0))//has forward vector
{
mv_mode = currMB->b8mode[k];
step_h = BLOCK_STEP [mv_mode][0];
step_v = BLOCK_STEP [mv_mode][1];
refframe = dec_picture->ref_idx[LIST_0][img->block_x+i0][img->block_y+j0];
for (j=j0; j<j0+step_v0; j+=step_v)
{
for (i=i0; i<i0+step_h0; i+=step_h)
{
j4 = img->block_y+j;
i4 = img->block_x+i;
// first make mv-prediction
SetMotionVectorPredictor (img, pmv, pmv+1, refframe, LIST_0, dec_picture->ref_idx, dec_picture->mv, i, j, 4*step_h, 4*step_v);
for (k=0; k < 2; k++)
{
//mvd_l0
currSE.value2 = k<<1; // identifies the component; only used for context determination
dP->readSyntaxElement(&currSE,dP);
curr_mvd = currSE.value1;
vec=curr_mvd+pmv[k]; /* find motion vector */
for(ii=0;ii<step_h;ii++)
{
for(jj=0;jj<step_v;jj++)
{
dec_picture->mv [LIST_0][i4+ii][j4+jj][k] = vec;
currMB->mvd [LIST_0][j+jj] [i+ii] [k] = curr_mvd;
}
}
}
}
}
}
}
// record reference picture Ids for deblocking decisions
for(i4=img->block_x;i4<(img->block_x+4);i4++)
for(j4=img->block_y;j4<(img->block_y+4);j4++)
{
if(dec_picture->ref_idx[LIST_0][i4][j4]>=0)
dec_picture->ref_pic_id[LIST_0][i4][j4] = dec_picture->ref_pic_num[LIST_0][dec_picture->ref_idx[LIST_0][i4][j4]];
else
dec_picture->ref_pic_id[LIST_0][i4][j4] = INT64_MIN;
}
}
/*!
************************************************************************
* \brief
* Get the Prediction from the Neighboring Blocks for Number of Nonzero Coefficients
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -