📄 macroblock.c
字号:
currMB->mb_type = currSE.value1;
if(!dP->bitstream->ei_flag)
currMB->ei_flag = 0;
}
}
// VLC Non-Intra
else
{
if(img->cod_counter == -1)
{
TRACE_STRING("mb_skip_run");
dP->readSyntaxElement(&currSE,img,dP);
img->cod_counter = currSE.value1;
}
if (img->cod_counter==0)
{
// read MB aff
if ((img->MbaffFrameFlag) && (((mb_nr&0x01)==0) || ((mb_nr&0x01) && prevMbSkipped)))
{
TRACE_STRING("mb_field_decoding_flag");
currSE.len = (int64) 1;
readSyntaxElement_FLC(&currSE, dP->bitstream);
currMB->mb_field = currSE.value1;
}
// read MB type
TRACE_STRING("mb_type");
dP->readSyntaxElement(&currSE,img,dP);
if(img->type == P_SLICE || img->type == SP_SLICE)
currSE.value1++;
currMB->mb_type = currSE.value1;
if(!dP->bitstream->ei_flag)
currMB->ei_flag = 0;
img->cod_counter--;
currMB->skip_flag = 0;
}
else
{
img->cod_counter--;
currMB->mb_type = 0;
currMB->ei_flag = 0;
currMB->skip_flag = 1;
// read field flag of bottom block
if(img->MbaffFrameFlag)
{
if(img->cod_counter == 0 && ((mb_nr&0x01) == 0))
{
TRACE_STRING("mb_field_decoding_flag (of coded bottom mb)");
currSE.len = (int64) 1;
readSyntaxElement_FLC(&currSE, dP->bitstream);
dP->bitstream->frame_bitoffset--;
TRACE_DECBITS(1);
currMB->mb_field = currSE.value1;
}
else if (img->cod_counter > 0 && ((mb_nr & 0x01) == 0))
{
// check left macroblock pair first
if (mb_is_available(mb_nr - 2, currMB) && ((mb_nr % (img->PicWidthInMbs * 2))!=0))
{
currMB->mb_field = img->mb_data[mb_nr-2].mb_field;
}
else
{
// check top macroblock pair
if (mb_is_available(mb_nr - 2*img->PicWidthInMbs, currMB))
{
currMB->mb_field = img->mb_data[mb_nr-2*img->PicWidthInMbs].mb_field;
}
else
currMB->mb_field = 0;
}
}
}
}
}
motion->mb_field[mb_nr] = (byte) currMB->mb_field;
img->block_y_aff = ((img->MbaffFrameFlag) && (currMB->mb_field)) ? (mb_nr&0x01) ? (img->block_y - 4)>>1 : img->block_y >> 1 : img->block_y;
img->siblock[img->mb_y][img->mb_x]=0;
interpret_mb_mode(currMB);
if(img->MbaffFrameFlag)
{
if(currMB->mb_field)
{
img->num_ref_idx_l0_active <<=1;
img->num_ref_idx_l1_active <<=1;
}
}
//init NoMbPartLessThan8x8Flag
currMB->NoMbPartLessThan8x8Flag = (IS_DIRECT(currMB) && !(active_sps->direct_8x8_inference_flag))? 0: 1;
//====== READ 8x8 SUB-PARTITION MODES (modes of 8x8 blocks) and Intra VBST block modes ======
if (currMB->mb_type == P8x8)
{
currSE.type = SE_MBTYPE;
dP = &(currSlice->partArr[partMap[SE_MBTYPE]]);
if (active_pps->entropy_coding_mode_flag ==UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_ue;
else
currSE.reading = readB8_typeInfo_CABAC;
for (i = 0; i < 4; i++)
{
TRACE_STRING("sub_mb_type");
dP->readSyntaxElement (&currSE, img, dP);
SetB8Mode (img, currMB, currSE.value1, i);
//set NoMbPartLessThan8x8Flag for P8x8 mode
currMB->NoMbPartLessThan8x8Flag &= (currMB->b8mode[i]==0 && active_sps->direct_8x8_inference_flag) ||
(currMB->b8mode[i]==4);
}
//--- init macroblock data ---
init_macroblock (img);
readMotionInfoFromNAL (img, currSlice, currMB);
}
//============= Transform Size Flag for INTRA MBs =============
//-------------------------------------------------------------
//transform size flag for INTRA_4x4 and INTRA_8x8 modes
if (currMB->mb_type == I4MB && img->Transform8x8Mode)
{
currSE.type = SE_HEADER;
dP = &(currSlice->partArr[partMap[SE_HEADER]]);
currSE.reading = readMB_transform_size_flag_CABAC;
TRACE_STRING("transform_size_8x8_flag");
// read UVLC transform_size_8x8_flag
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
{
currSE.len = (int64) 1;
readSyntaxElement_FLC(&currSE, dP->bitstream);
}
else
{
dP->readSyntaxElement(&currSE,img,dP);
}
currMB->luma_transform_size_8x8_flag = currSE.value1;
if (currMB->luma_transform_size_8x8_flag)
{
currMB->mb_type = I8MB;
memset(&currMB->b8mode, I8MB, 4 * sizeof(char));
memset(&currMB->b8pdir, -1, 4 * sizeof(char));
}
}
else
{
currMB->luma_transform_size_8x8_flag = 0;
}
if(active_pps->constrained_intra_pred_flag && (img->type == P_SLICE || img->type == B_SLICE)) // inter frame
{
if( !IS_INTRA(currMB) )
{
img->intra_block[mb_nr] = 0;
}
}
//! TO for error concealment
//! If we have an INTRA Macroblock and we lost the partition
//! which contains the intra coefficients Copy MB would be better
//! than just a gray block.
//! Seems to be a bit at the wrong place to do this right here, but for this case
//! up to now there is no other way.
/*
!!!KS
dP = &(currSlice->partArr[partMap[SE_CBP_INTRA]]);
if(IS_INTRA (currMB) && dP->bitstream->ei_flag && img->number)
{
currMB->mb_type = 0;
currMB->ei_flag = 1;
for (i=0;i<4;i++) {currMB->b8mode[i]=currMB->b8pdir[i]=0; }
}
dP = &(currSlice->partArr[partMap[currSE.type]]);
//! End TO
*/
//--- init macroblock data ---
if (currMB->mb_type != P8x8)
init_macroblock(img);
if (IS_DIRECT (currMB) && img->cod_counter >= 0)
{
currMB->cbp = 0;
reset_coeffs();
if (active_pps->entropy_coding_mode_flag ==CABAC)
img->cod_counter=-1;
}
else if (IS_SKIP (currMB)) //keep last macroblock
{
skip_macroblock(img, currMB);
}
else if(currMB->mb_type != IPCM)
{
// intra prediction modes for a macroblock 4x4 **********************************************
if (IS_INTRA(currMB))
read_ipred_modes(img, currSlice, currMB);
// read inter frame vector data *********************************************************
if (IS_INTERMV (currMB) && (currMB->mb_type != P8x8))
{
readMotionInfoFromNAL (img, currSlice, currMB);
}
// read CBP and Coeffs ***************************************************************
readCBPandCoeffsFromNAL (img, currSlice, currMB);
}
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
if ( currSlice->dp_mode && currSlice->dpB_NotPresent )
{
concealIPCMcoeffs(img);
}
else
{
dP = &(currSlice->partArr[partMap[SE_LUM_DC_INTRA]]);
readIPCMcoeffsFromNAL(img, dP);
}
}
return;
}
/*!
************************************************************************
* \brief
* Initialize decoding engine after decoding an IPCM macroblock
* (for IPCM CABAC 28/11/2003)
*
* \author
* Dong Wang <Dong.Wang@bristol.ac.uk>
************************************************************************
*/
static void init_decoding_engine_IPCM(ImageParameters *img)
{
Slice *currSlice = img->currentSlice;
Bitstream *currStream;
int ByteStartPosition;
int PartitionNumber;
int i;
if(currSlice->dp_mode==PAR_DP_1)
PartitionNumber=1;
else if(currSlice->dp_mode==PAR_DP_3)
PartitionNumber=3;
else
{
printf("Partition Mode is not supported\n");
exit(1);
}
for(i=0;i<PartitionNumber;i++)
{
currStream = currSlice->partArr[i].bitstream;
ByteStartPosition = currStream->read_len;
arideco_start_decoding (&currSlice->partArr[i].de_cabac, currStream->streamBuffer, ByteStartPosition, &currStream->read_len);
}
}
/*!
************************************************************************
* \brief
* Read IPCM pcm_alignment_zero_bit and pcm_byte[i] from stream to img->cof
* (for IPCM CABAC and IPCM CAVLC)
*
* \author
* Dong Wang <Dong.Wang@bristol.ac.uk>
************************************************************************
*/
static void readIPCMcoeffsFromNAL(ImageParameters *img, struct datapartition *dP)
{
SyntaxElement currSE;
int i,j;
//For CABAC, we don't need to read bits to let stream byte aligned
// because we have variable for integer bytes position
if(active_pps->entropy_coding_mode_flag == CABAC)
{
readIPCM_CABAC(dP);
init_decoding_engine_IPCM(img);
}
else
{
//read bits to let stream byte aligned
if(((dP->bitstream->frame_bitoffset) & 0x07) != 0)
{
TRACE_STRING("pcm_alignment_zero_bit");
currSE.len = (8 - ((dP->bitstream->frame_bitoffset) & 0x07));
readSyntaxElement_FLC(&currSE, dP->bitstream);
}
//read luma and chroma IPCM coefficients
currSE.len=img->bitdepth_luma;
TRACE_STRING("pcm_sample_luma");
for(i=0;i<MB_BLOCK_SIZE;i++)
{
for(j=0;j<MB_BLOCK_SIZE;j++)
{
readSyntaxElement_FLC(&currSE, dP->bitstream);
img->cof[0][i][j] = currSE.value1;
//img->fcf[0][i][j] = currSE.value1;
}
}
currSE.len=img->bitdepth_chroma;
if ((dec_picture->chroma_format_idc != YUV400) && !IS_INDEPENDENT(img))
{
TRACE_STRING("pcm_sample_chroma (u)");
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[1][i][j] = currSE.value1;
//img->fcf[1][i][j] = currSE.value1;
}
}
TRACE_STRING("pcm_sample_chroma (v)");
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[2][i][j] = currSE.value1;
//img->fcf[2][i][j] = currSE.value1;
}
}
}
}
}
/*!
************************************************************************
* \brief
* If data partition B is lost, conceal PCM sample values with DC.
*
************************************************************************
*/
static void read_ipred_modes(ImageParameters *img, Slice *currSlice, Macroblock *currMB)
{
int b8,i,j,bi,bj,bx,by,dec;
SyntaxElement currSE;
DataPartition *dP;
byte *partMap = assignSE2partition[currSlice->dp_mode];
int ts, ls;
int mostProbableIntraPredMode;
int upIntraPredMode;
int leftIntraPredMode;
char IntraChromaPredModeFlag = IS_INTRA(currMB);
int bs_x, bs_y;
int ii,jj;
PixelPos left_block, top_block;
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
{
by = (b8&2) + j;
bj = img->block_y + by;
for(i=0;i<2;i+=ii)
{
bx = ((b8&1)<<1) + i;
bi = img->block_x + bx;
//get from stream
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
readSyntaxElement_Intra4x4PredictionMode(&currSE,img,dP->bitstream);
else
{
currSE.context=(b8<<2)+(j<<1) +i;
dP->readSyntaxElement(&currSE,img,dP);
}
get4x4Neighbour(currMB, (bx<<2) - 1, (by<<2), img->mb_size[IS_LUMA], &left_block);
get4x4Neighbour(currMB, (bx<<2), (by<<2) - 1, img->mb_size[IS_LUMA], &top_block );
//get from array and decode
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -