📄 macroblock.c
字号:
{
readIPCMBytes_CABAC(&currSE, dP->bitstream);
img->cof[i/4+2][j/4+4][i%4][j%4]=currSE.value1;
}
}
}
//If the decoded MB is IPCM MB, decoding engine is initialized
// here the decoding engine is directly initialized without checking End of Slice
// The reason is that, whether current MB is the last MB in slice or not, there is
// at least one 'end of slice' syntax after this MB. So when fetching bytes in this
// initialisation process, we can guarantee there is bits available in bitstream.
init_decoding_engine_IPCM(img);
}
else
{
//read bits to let stream byte aligned
if((dP->bitstream->frame_bitoffset)%8!=0)
{
TRACE_STRING("pcm_alignment_zero_bit");
currSE.len=8-(dP->bitstream->frame_bitoffset)%8;
readSyntaxElement_FLC(&currSE, dP->bitstream);
}
//read luma and chroma IPCM coefficients
currSE.len=img->bitdepth_luma;
TRACE_STRING("pcm_byte luma");
for(i=0;i<MB_BLOCK_SIZE;i++)
{
for(j=0;j<MB_BLOCK_SIZE;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i/4][j/4][i%4][j%4]=currSE.value1;
}
}
currSE.len=img->bitdepth_chroma;
if (dec_picture->chroma_format_idc != YUV400)
{
TRACE_STRING("pcm_byte chroma");
for(i=0;i<img->mb_cr_size_y;i++)
{
for(j=0;j<img->mb_cr_size_x;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i/4][j/4+4][i%4][j%4]=currSE.value1;
}
}
for(i=0;i<img->mb_cr_size_y;i++)
{
for(j=0;j<img->mb_cr_size_x;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[i/4+2][j/4+4][i%4][j%4]=currSE.value1;
}
}
}
}
}
void read_ipred_modes(struct img_par *img,struct inp_par *inp)
{
int b8,i,j,bi,bj,bx,by,dec;
SyntaxElement currSE;
Slice *currSlice;
DataPartition *dP;
int *partMap;
Macroblock *currMB;
int ts, ls;
int mostProbableIntraPredMode;
int upIntraPredMode;
int leftIntraPredMode;
int IntraChromaPredModeFlag;
int bs_x, bs_y;
int ii,jj;
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;
TRACE_STRING("intra4x4_pred_mode");
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (!(active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag))
currSE.reading = readIntraPredMode_CABAC;
for(b8=0;b8<4;b8++) //loop 8x8 blocks
{
if((currMB->b8mode[b8]==IBLOCK )||(currMB->b8mode[b8]==I8MB))
{
bs_x = bs_y = (currMB->b8mode[b8] == I8MB)?8:4;
IntraChromaPredModeFlag = 1;
ii=(bs_x>>2);
jj=(bs_y>>2);
for(j=0;j<2;j+=jj) //loop subblocks
for(i=0;i<2;i+=ii)
{
//get from stream
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
readSyntaxElement_Intra4x4PredictionMode(&currSE,img,inp,dP);
else
{
currSE.context=(b8<<2)+(j<<1)+i;
dP->readSyntaxElement(&currSE,img,inp,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 (active_pps->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;
}
// !! KS: not sure if the follwing is still correct...
ts=ls=0; // Check to see if the neighboring block is SI
if (IS_OLDINTRA(currMB) && img->type == SI_SLICE) // need support for MBINTLC1
{
if (left_block.available)
if (img->siblock [left_block.pos_x][left_block.pos_y])
ls=1;
if (top_block.available)
if (img->siblock [top_block.pos_x][top_block.pos_y])
ts=1;
}
upIntraPredMode = (top_block.available &&(ts == 0)) ? img->ipredmode[top_block.pos_x ][top_block.pos_y ] : -1;
leftIntraPredMode = (left_block.available &&(ls == 0)) ? 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
for(jj=0;jj<(bs_y>>2);jj++) //loop 4x4s in the subblock for 8x8 prediction setting
for(ii=0;ii<(bs_x>>2);ii++)
img->ipredmode[bi+ii][bj+jj]=dec;
}
}
}
if (IntraChromaPredModeFlag && dec_picture->chroma_format_idc != YUV400)
{
currSE.type = SE_INTRAPREDMODE;
TRACE_STRING("intra_chroma_pred_mode");
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag) currSE.mapping = linfo_ue;
else currSE.reading = readCIPredMode_CABAC;
dP->readSyntaxElement(&currSE,img,inp,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_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, 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
{
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-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
* Set context for reference frames
************************************************************************
*/
int
BType2CtxRef (int btype)
{
if (btype<4) return 0;
else return 1;
}
/*!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -