📄 macroblock.c
字号:
currMB->prev_qp = curr_slice->qp;
currMB->prev_delta_qp = 0;
}
// frame layer rate control
if (input->basicunit == img->FrameSizeInMbs)
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
// basic unit layer rate control
else
{
// each I or B frame has only one QP
if( ((img->type == I_SLICE || img->type == B_SLICE) && input->RCUpdateMode != RC_MODE_1 ) || !(img->number) )
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
else if( img->type == P_SLICE || input->RCUpdateMode == RC_MODE_1 )
{
if (!img->write_macroblock) //write macroblock
{
if (prev_mb < 0) //first macroblock (of slice)
{
// Initialize delta qp change from last macroblock. Feature may be used for future rate control
currMB->delta_qp = 0;
currMB->qp = img->qp;
delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp;
}
else
{
if (!((input->MbInterlace) && img->bot_MB)) //top macroblock
{
if (img->mb_data[prev_mb].prev_cbp == 1)
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
else
{
currMB->qp = img->mb_data[prev_mb].prev_qp;
currMB->delta_qp = currMB->qp - img->mb_data[prev_mb].qp;
img->qp = currMB->qp;
}
delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp;
}
else //bottom macroblock
{
// Initialize delta qp change from last macroblock. Feature may be used for future rate control
currMB->delta_qp = 0;
currMB->qp = img->qp; // needed in loop filter (even if constant QP is used)
}
}
}
else
{
if (!img->bot_MB) //write top macroblock
{
if (img->write_mbaff_frame)
{
currMB->delta_qp = delta_qp_mbaff[0][img->bot_MB];
img->qp = currMB->qp = qp_mbaff[0][img->bot_MB];
//set_chroma_qp(currMB);
}
else
{
if (prev_mb < 0) //first macroblock (of slice)
{
// Initialize delta qp change from last macroblock. Feature may be used for future rate control
currMB->delta_qp = 0;
currMB->qp = img->qp;
delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp;
}
else
{
currMB->delta_qp = delta_qp_mbaff[1][img->bot_MB];
img->qp = currMB->qp = qp_mbaff[1][img->bot_MB];
//set_chroma_qp(currMB);
}
}
}
else //write bottom macroblock
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
set_chroma_qp(currMB);
}
}
// compute the quantization parameter for each basic unit of P frame
if (!img->write_macroblock)
{
if(!((input->MbInterlace) && img->bot_MB))
{
if((img->NumberofCodedMacroBlocks > 0) && (img->NumberofCodedMacroBlocks % img->BasicUnit == 0))
{
// frame coding
if(active_sps->frame_mbs_only_flag)
{
updateRCModel(quadratic_RC);
img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
}
// picture adaptive field/frame coding
else if((input->PicInterlace!=FRAME_CODING)&&(!input->MbInterlace)&&(generic_RC->NoGranularFieldRC==0))
{
updateRCModel(quadratic_RC);
img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
}
// mb adaptive f/f coding, field coding
else if((input->MbInterlace))
{
updateRCModel(quadratic_RC);
img->BasicUnitQP=updateQP(quadratic_RC, generic_RC->TopFieldFlag);
}
}
if(img->current_mb_nr==0)
img->BasicUnitQP=img->qp;
currMB->predict_qp = iClip3(currMB->qp - img->min_qp_delta, currMB->qp + img->max_qp_delta, img->BasicUnitQP);
dq = currMB->delta_qp + currMB->predict_qp - currMB->qp;
if(dq < -img->min_qp_delta)
{
dq = -img->min_qp_delta;
predict_error = dq-currMB->delta_qp;
img->qp = img->qp+predict_error;
currMB->delta_qp = -img->min_qp_delta;
}
else if(dq > img->max_qp_delta)
{
dq = img->max_qp_delta;
predict_error = dq - currMB->delta_qp;
img->qp = img->qp + predict_error;
currMB->delta_qp = img->max_qp_delta;
}
else
{
currMB->delta_qp = dq;
predict_error=currMB->predict_qp-currMB->qp;
img->qp = currMB->predict_qp;
}
currMB->qp = img->qp;
if (input->MbInterlace)
{
delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp;
}
currMB->predict_error=predict_error;
}
else
currMB->prev_qp=img->qp;
}
}
}
}
else
{
Slice* currSlice = img->currentSlice;
int new_qp = img->qp;
if (prev_mb>-1)
{
currMB->prev_qp = img->mb_data[prev_mb].qp;
currMB->prev_delta_qp = (img->mb_data[prev_mb].slice_nr == img->current_slice_nr) ? img->mb_data[prev_mb].delta_qp : 0;
}
else
{
currMB->prev_qp = currSlice->qp;
currMB->prev_delta_qp = 0;
}
if (prev_mb < 0) //first macroblock (of slice)
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
else
{
if (!((input->MbInterlace) && img->bot_MB)) //top macroblock
{
if (img->mb_data[prev_mb].prev_cbp == 1)
{
currMB->delta_qp = 0;
currMB->qp = img->qp;
}
else
{
currMB->qp = img->mb_data[prev_mb].prev_qp;
currMB->delta_qp = currMB->qp - img->mb_data[prev_mb].qp;
img->qp = currMB->qp;
}
}
else //bottom macroblock
{
currMB->delta_qp = 0;
currMB->qp = img->qp; // needed in loop filter (even if constant QP is used)
}
}
currMB->delta_qp = new_qp - currMB->qp + currMB->delta_qp;
img->qp = currMB->qp = new_qp;
//currMB->delta_qp = currMB->qp - currMB->prev_qp;
delta_qp_mbaff[currMB->mb_field][img->bot_MB] = currMB->delta_qp;
qp_mbaff [currMB->mb_field][img->bot_MB] = currMB->qp;
}
img->qp_scaled = img->qp + img->bitdepth_luma_qp_scale;
set_chroma_qp (currMB);
// loop filter parameter
if (active_pps->deblocking_filter_control_present_flag)
{
currMB->LFDisableIdc = img->LFDisableIdc;
currMB->LFAlphaC0Offset = img->LFAlphaC0Offset;
currMB->LFBetaOffset = img->LFBetaOffset;
}
else
{
currMB->LFDisableIdc = 0;
currMB->LFAlphaC0Offset = 0;
currMB->LFBetaOffset = 0;
}
// If MB is next to a slice boundary, mark neighboring blocks unavailable for prediction
CheckAvailabilityOfNeighbors();
if (input->symbol_mode == CABAC)
CheckAvailabilityOfNeighborsCABAC();
// Reset vectors and reference indices
for (l=0; l<2; l++)
{
for (j=img->block_y; j < img->block_y + BLOCK_MULTIPLE; j++)
{
memset(&enc_picture->ref_idx[l][j][img->block_x], -1, BLOCK_MULTIPLE * sizeof(char));
memset(enc_picture->mv [l][j][img->block_x], 0, 2 * BLOCK_MULTIPLE * sizeof(short));
for (i=img->block_x; i < img->block_x + BLOCK_MULTIPLE; i++)
enc_picture->ref_pic_id[l][j][i]= -1;
}
}
// Reset syntax element entries in MB struct
currMB->mb_type = 0;
currMB->cbp_blk = 0;
currMB->cbp = 0;
currMB->cbp_bits = 0;
currMB->c_ipred_mode = DC_PRED_8;
memset (currMB->mvd, 0, BLOCK_CONTEXT * sizeof(int));
memset (currMB->intra_pred_modes, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char)); // changing this to char would allow us to use memset
memset (currMB->intra_pred_modes8x8, DC_PRED, MB_BLOCK_PARTITIONS * sizeof(char));
//initialize the whole MB as INTRA coded
//Blocks are set to notINTRA in write_one_macroblock
if (input->UseConstrainedIntraPred)
{
img->intra_block[img->current_mb_nr] = 1;
}
// Initialize bitcounters for this macroblock
if(prev_mb < 0) // No slice header to account for
{
currMB->bitcounter[BITS_HEADER] = 0;
}
else if (currMB->slice_nr == img->mb_data[prev_mb].slice_nr) // current MB belongs to the
// same slice as the last MB
{
currMB->bitcounter[BITS_HEADER] = 0;
}
currMB->bitcounter[BITS_MB_MODE ] = 0;
currMB->bitcounter[BITS_COEFF_Y_MB ] = 0;
currMB->bitcounter[BITS_INTER_MB ] = 0;
currMB->bitcounter[BITS_CBP_MB ] = 0;
currMB->bitcounter[BITS_DELTA_QUANT_MB] = 0;
currMB->bitcounter[BITS_COEFF_UV_MB ] = 0;
if(input->SearchMode == FAST_FULL_SEARCH)
ResetFastFullIntegerSearch ();
// disable writing of trace file
#if TRACE
curr_slice->partArr[0].bitstream->trace_enabled = FALSE;
if (input->partition_mode)
{
curr_slice->partArr[1].bitstream->trace_enabled = FALSE;
curr_slice->partArr[2].bitstream->trace_enabled = FALSE;
}
#endif
}
/*!
************************************************************************
* \brief
* terminates processing of the current macroblock depending
* on the chosen slice mode
************************************************************************
*/
void terminate_macroblock( Boolean *end_of_slice, //!< returns true for last macroblock of a slice, otherwise false
Boolean *recode_macroblock //!< returns true if max. slice size is exceeded an macroblock must be recoded in next slice
)
{
int i;
Slice *currSlice = img->currentSlice;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement se;
int *partMap = assignSE2partition[input->partition_mode];
DataPartition *dataPart;
Bitstream *currStream;
int rlc_bits=0;
int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALL_BACK);
int new_slice;
static int skip = FALSE;
// if previous mb in the same slice group has different slice number as the current, it's the
// the start of new slice
new_slice=0;
if ( (img->current_mb_nr==0) || (FmoGetPreviousMBNr(img->current_mb_nr)<0) )
new_slice=1;
else if( img->mb_data[FmoGetPreviousMBNr(img->current_mb_nr)].slice_nr != img->current_slice_nr )
new_slice=1;
*recode_macroblock=FALSE;
switch(input->slice_mode)
{
case NO_SLICES:
currSlice->num_mb++;
*recode_macroblock = FALSE;
if ((currSlice->num_mb) == (int)img->PicSizeInMbs) // maximum number of MBs reached
*end_of_slice = TRUE;
// if it's end of current slice group, slice ends too
*end_of_slice = (Boolean) (*end_of_slice | (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr))));
break;
case FIXED_MB:
// For slice mode one, check if a new slice boundary follows
currSlice->num_mb++;
*recode_macroblock = FALSE;
//! Check end-of-slice group condition first
*end_of_slice = (Boolean) (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
//! Now check maximum # of MBs in slice
*end_of_slice = (Boolean) (*end_of_slice | (currSlice->num_mb >= input->slice_argument));
break;
// For slice modes two and three, check if coding of this macroblock
// resulted in too many bits for this slice. If so, indicate slice
// boundary before this macroblock and code the macroblock again
case FIXED_RATE:
// in case of skip MBs check if there is a slice boundary
// only for UVLC (img->cod_counter is always 0 in case of CABAC)
if(img->cod_counter)
{
// write out the skip MBs to know how many bits we need for the RLC
se.value1 = img->cod_counter;
se.value2 = 0;
se.type = SE_MBTYPE;
dataPart = &(currSlice->partArr[partMap[se.type]]);
TRACE_SE (se.tracestring, "mb_skip_run");
writeSE_UVLC(&se, dataPart);
rlc_bits=se.len;
currStream = dataPart->bitstream;
// save the bitstream as it would be if we write the skip MBs
currStream->bits_to_go_skip = currStream->bits_to_go;
currStream->byte_pos_skip = currStream->byte_pos;
currStream->byte_buf_skip = currStream->byte_buf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -