📄 macroblock.c
字号:
*/
static void interpret_mb_mode_SI(Macroblock *currMB)
{
const int ICBPTAB[6] = {0,16,32,15,31,47};
int mbmode = currMB->mb_type;
if (mbmode==0)
{
currMB->mb_type = SI4MB;
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
img->siblock[img->mb_y][img->mb_x]=1;
}
else if (mbmode==1)
{
currMB->mb_type = I4MB;
memset(&currMB->b8mode[0],IBLOCK,4 * sizeof(char));
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
}
else if(mbmode==26)
{
currMB->mb_type=IPCM;
currMB->cbp= -1;
currMB->i16mode = 0;
memset(&currMB->b8mode[0],0,4 * sizeof(char));
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
}
else
{
currMB->mb_type = I16MB;
currMB->cbp= ICBPTAB[(mbmode-1)>>2];
currMB->i16mode = (mbmode-2) & 0x03;
memset(&currMB->b8mode[0],0,4 * sizeof(char));
memset(&currMB->b8pdir[0],-1,4 * sizeof(char));
}
}
/*!
************************************************************************
* \brief
* Set mode interpretation based on slice type
************************************************************************
*/
void set_interpret_mb_mode(int slice_type)
{
switch (slice_type)
{
case P_SLICE: case SP_SLICE:
interpret_mb_mode = interpret_mb_mode_P;
break;
case B_SLICE:
interpret_mb_mode = interpret_mb_mode_B;
break;
case I_SLICE:
interpret_mb_mode = interpret_mb_mode_I;
break;
case SI_SLICE:
interpret_mb_mode = interpret_mb_mode_SI;
break;
default:
printf("Unsupported slice type\n");
break;
}
}
/*!
************************************************************************
* \brief
* init macroblock I and P frames
************************************************************************
*/
static void init_macroblock(ImageParameters *img)
{
int i, j, k;
for (k = LIST_0; k <= LIST_1; k++)
{
for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++)
memset(&img->ipredmode[j][img->block_x], DC_PRED, BLOCK_SIZE * sizeof(char));
for(j = img->block_y; j < img->block_y + BLOCK_SIZE; j++)
{ // reset vectors and pred. modes
memset(&dec_picture->motion.mv[k][j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
memset(&dec_picture->motion.ref_idx[k][j][img->block_x], -1, BLOCK_SIZE * sizeof(char));
for (i = img->block_x; i < img->block_x + BLOCK_SIZE;i++)
{
dec_picture->motion.ref_pic_id[k][j][i] = INT64_MIN;
}
}
}
}
/*!
************************************************************************
* \brief
* Sets mode for 8x8 block
************************************************************************
*/
void SetB8Mode (ImageParameters* img, Macroblock* currMB, int value, int i)
{
static const int p_v2b8 [ 5] = {4, 5, 6, 7, IBLOCK};
static const int p_v2pd [ 5] = {0, 0, 0, 0, -1};
static const int b_v2b8 [14] = {0, 4, 4, 4, 5, 6, 5, 6, 5, 6, 7, 7, 7, IBLOCK};
static const int b_v2pd [14] = {2, 0, 1, 2, 0, 0, 1, 1, 2, 2, 0, 1, 2, -1};
if (img->type==B_SLICE)
{
currMB->b8mode[i] = (char) b_v2b8[value];
currMB->b8pdir[i] = (char) b_v2pd[value];
}
else
{
currMB->b8mode[i] = (char) p_v2b8[value];
currMB->b8pdir[i] = (char) p_v2pd[value];
}
}
void reset_coeffs(void)
{
// reset all coeffs
memset(&img->fcf[0][0][0], 0, 3 * MB_PIXELS * sizeof(int));
memset(&img->cof[0][0][0], 0, 3 * MB_PIXELS * sizeof(int));
// CAVLC
if (active_pps->entropy_coding_mode_flag == UVLC)
memset(&img->nz_coeff[img->current_mb_nr][0][0][0], 0, 3 * BLOCK_SIZE * BLOCK_SIZE * sizeof(int));
}
void field_flag_inference(Macroblock *currMB)
{
if (currMB->mbAvailA)
{
currMB->mb_field = img->mb_data[currMB->mbAddrA].mb_field;
}
else
{
// check top macroblock pair
currMB->mb_field = currMB->mbAvailB ? img->mb_data[currMB->mbAddrB].mb_field : 0;
}
}
void copy_macroblock(ImageParameters *img, Macroblock *currMB)
{
short pred_mv[2];
int zeroMotionAbove;
int zeroMotionLeft;
PixelPos mb_a, mb_b;
int i, j;
int a_mv_y = 0;
int a_ref_idx = 0;
int b_mv_y = 0;
int b_ref_idx = 0;
int img_block_y = img->block_y;
int list_offset = ((img->MbaffFrameFlag)&&(currMB->mb_field))? (img->current_mb_nr & 0x01) ? 4 : 2 : 0;
short ***cur_mv = dec_picture->motion.mv[LIST_0];
get4x4Neighbour(currMB,-1, 0, img->mb_size[IS_LUMA], &mb_a);
get4x4Neighbour(currMB, 0,-1, img->mb_size[IS_LUMA], &mb_b);
if (mb_a.available)
{
a_mv_y = cur_mv[mb_a.pos_y][mb_a.pos_x][1];
a_ref_idx = dec_picture->motion.ref_idx[LIST_0][mb_a.pos_y][mb_a.pos_x];
if (currMB->mb_field && !img->mb_data[mb_a.mb_addr].mb_field)
{
a_mv_y /=2;
a_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[mb_a.mb_addr].mb_field)
{
a_mv_y *=2;
a_ref_idx >>=1;
}
}
if (mb_b.available)
{
b_mv_y = cur_mv[mb_b.pos_y][mb_b.pos_x][1];
b_ref_idx = dec_picture->motion.ref_idx[LIST_0][mb_b.pos_y][mb_b.pos_x];
if (currMB->mb_field && !img->mb_data[mb_b.mb_addr].mb_field)
{
b_mv_y /=2;
b_ref_idx *=2;
}
if (!currMB->mb_field && img->mb_data[mb_b.mb_addr].mb_field)
{
b_mv_y *=2;
b_ref_idx >>=1;
}
}
zeroMotionLeft = !mb_a.available ? 1 : a_ref_idx==0 && cur_mv[mb_a.pos_y][mb_a.pos_x][0]==0 && a_mv_y==0 ? 1 : 0;
zeroMotionAbove = !mb_b.available ? 1 : b_ref_idx==0 && cur_mv[mb_b.pos_y][mb_b.pos_x][0]==0 && b_mv_y==0 ? 1 : 0;
currMB->cbp = 0;
reset_coeffs();
if (zeroMotionAbove || zeroMotionLeft)
{
for(j = img_block_y; j < img_block_y + BLOCK_SIZE;j++)
{
memset(&cur_mv[j][img->block_x][0], 0, 2 * BLOCK_SIZE * sizeof(short));
}
}
else
{
SetMotionVectorPredictor (img, currMB, pred_mv, 0, LIST_0, dec_picture->motion.ref_idx, dec_picture->motion.mv, 0, 0, 16, 16);
for(j=img_block_y;j<img_block_y + BLOCK_SIZE;j++)
{
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
memcpy(&cur_mv[j][i][0], &pred_mv[0], 2 * sizeof(short));
}
}
for(j=img_block_y;j< img_block_y + BLOCK_SIZE;j++)
{
memset(&dec_picture->motion.ref_idx[LIST_0][j][img->block_x], 0, BLOCK_SIZE * sizeof(char));
for(i=img->block_x;i<img->block_x + BLOCK_SIZE;i++)
{
dec_picture->motion.ref_pic_id[LIST_0][j][i] =
dec_picture->ref_pic_num[img->current_slice_nr][LIST_0 + list_offset][(short)dec_picture->motion.ref_idx[LIST_0][j][i]];
}
}
}
/*!
************************************************************************
* \brief
* Get the syntax elements from the NAL
************************************************************************
*/
void read_one_macroblock(ImageParameters *img, Macroblock *currMB)
{
int i;
SyntaxElement currSE;
int mb_nr = img->current_mb_nr;
Slice *currSlice = img->currentSlice;
DataPartition *dP;
int *partMap = assignSE2partition[currSlice->dp_mode];
Macroblock *topMB = NULL;
int prevMbSkipped = 0;
int check_bottom, read_bottom, read_top;
if (img->MbaffFrameFlag)
{
if (mb_nr&0x01)
{
topMB= &img->mb_data[mb_nr-1];
if(!(img->type == B_SLICE))
prevMbSkipped = (topMB->mb_type == 0);
else
prevMbSkipped = topMB->skip_flag;
}
else
prevMbSkipped = 0;
}
currMB->mb_field = ((mb_nr&0x01) == 0)? 0 : img->mb_data[mb_nr-1].mb_field;
update_qp(img, currMB, img->qp);
currSE.type = SE_MBTYPE;
// read MB mode *****************************************************************
dP = &(currSlice->partArr[partMap[currSE.type]]);
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
currSE.mapping = linfo_ue;
if(img->type == I_SLICE || img->type == SI_SLICE)
{
// read MB aff
if (img->MbaffFrameFlag && (mb_nr&0x01)==0)
{
TRACE_STRING("mb_field_decoding_flag");
if (active_pps->entropy_coding_mode_flag == UVLC || dP->bitstream->ei_flag)
{
currSE.len = (int64) 1;
readSyntaxElement_FLC(&currSE, dP->bitstream);
}
else
{
currSE.reading = readFieldModeInfo_CABAC;
dP->readSyntaxElement(&currSE,img,dP);
}
currMB->mb_field = currSE.value1;
}
if(active_pps->entropy_coding_mode_flag == CABAC)
CheckAvailabilityOfNeighborsCABAC(currMB);
// read MB type
TRACE_STRING("mb_type");
currSE.reading = readMB_typeInfo_CABAC;
dP->readSyntaxElement(&currSE,img,dP);
currMB->mb_type = currSE.value1;
if(!dP->bitstream->ei_flag)
currMB->ei_flag = 0;
}
// non I/SI-slice CABAC
else if (active_pps->entropy_coding_mode_flag == CABAC)
{
// read MB skip_flag
if (img->MbaffFrameFlag && ((mb_nr&0x01) == 0||prevMbSkipped))
field_flag_inference(currMB);
CheckAvailabilityOfNeighborsCABAC(currMB);
TRACE_STRING("mb_skip_flag");
currSE.reading = readMB_skip_flagInfo_CABAC;
dP->readSyntaxElement(&currSE,img,dP);
currMB->mb_type = currSE.value1;
currMB->skip_flag = !(currSE.value1);
if (img->type==B_SLICE)
currMB->cbp = currSE.value2;
if (!dP->bitstream->ei_flag)
currMB->ei_flag = 0;
if ((img->type==B_SLICE) && currSE.value1==0 && currSE.value2==0)
img->cod_counter=0;
// read MB AFF
if (img->MbaffFrameFlag)
{
check_bottom=read_bottom=read_top=0;
if ((mb_nr&0x01)==0)
{
check_bottom = currMB->skip_flag;
read_top = !check_bottom;
}
else
{
read_bottom = (topMB->skip_flag && (!currMB->skip_flag));
}
if (read_bottom || read_top)
{
TRACE_STRING("mb_field_decoding_flag");
currSE.reading = readFieldModeInfo_CABAC;
dP->readSyntaxElement(&currSE,img,dP);
currMB->mb_field = currSE.value1;
}
if (check_bottom)
check_next_mb_and_get_field_mode_CABAC(&currSE,img,dP);
}
CheckAvailabilityOfNeighborsCABAC(currMB);
// read MB type
if (currMB->mb_type != 0 )
{
currSE.reading = readMB_typeInfo_CABAC;
TRACE_STRING("mb_type");
dP->readSyntaxElement(&currSE,img,dP);
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -