📄 macroblock.c
字号:
}
/*adaptive field/frame coding*/
else if((input->PicInterlace==ADAPTIVE_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*field coding*/
else if((input->PicInterlace==FIELD_CODING)&&(!input->MbInterlace)&&(img->IFLAG==0))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*mb adaptive f/f coding, field coding*/
else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==1))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
/*mb adaptive f/f coding, frame coding*/
else if((input->MbInterlace)&&(img->IFLAG==0)&&(img->FieldControl==0))
{
updateRCModel();
img->BasicUnitQP=updateQuantizationParameter(img->TopFieldFlag);
}
}
if(img->current_mb_nr==0)
img->BasicUnitQP=img->qp;
currMB->predict_qp=img->BasicUnitQP;
if(currMB->predict_qp>currMB->qp + max_qp_delta)
currMB->predict_qp=currMB->qp + max_qp_delta;
else if(currMB->predict_qp<currMB->qp - min_qp_delta)
currMB->predict_qp=currMB->qp - min_qp_delta;
currMB->prev_qp = currMB->predict_qp;
dq = currMB->delta_qp + currMB->predict_qp-currMB->qp;
if(dq < -min_qp_delta)
{
dq = -min_qp_delta;
predict_error = dq-currMB->delta_qp;
img->qp = img->qp+predict_error;
currMB->delta_qp = -min_qp_delta;
}
else if(dq > max_qp_delta)
{
dq = max_qp_delta;
predict_error = dq - currMB->delta_qp;
img->qp = img->qp + predict_error;
currMB->delta_qp = 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 = DELTA_QP2 = currMB->delta_qp;
QP = QP2 = currMB->qp;
DELTA_QP2 = currMB->delta_qp;
}
currMB->predict_error=predict_error;
}
else
predict_error=currMB->predict_error;
}
else
currMB->prev_qp=img->qp;
}
}
}
else
{
Slice* currSlice = img->currentSlice;
int prev_mb = FmoGetPreviousMBNr(img->current_mb_nr);
if (prev_mb>-1)
{
currMB->prev_qp = img->mb_data[prev_mb].qp;
currMB->prev_delta_qp = img->mb_data[prev_mb].delta_qp;
}
else
{
currMB->prev_qp = currSlice->qp;
currMB->prev_delta_qp = 0;
}
currMB->qp = currSlice->qp ;
currMB->delta_qp = currMB->qp - currMB->prev_qp;
DELTA_QP = DELTA_QP2 = currMB->delta_qp;
QP = QP2 = currMB->qp;
}
// Initialize counter for MB symbols
currMB->currSEnr=0;
// 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 before doing motion search in motion_search().
for (l=0; l<2; l++)
{
for (j=0; j < BLOCK_MULTIPLE; j++)
for (i=0; i < BLOCK_MULTIPLE; i++)
for (k=0; k < 2; k++)
enc_picture->mv[l][img->block_x+i][img->block_y+j][k]=0;
}
//initialize reference index
for (j=0; j < BLOCK_MULTIPLE; j++)
{
for (i=0; i < BLOCK_MULTIPLE; i++)
for (l=0; l<2; l++)
{
enc_picture->ref_idx[l][img->block_x+i][img->block_y + j] =-1;
enc_picture->ref_pic_id[l][img->block_x+i][img->block_y+j] = -1;
}
}
// Reset syntax element entries in MB struct
currMB->mb_type = 0;
currMB->cbp_blk = 0;
currMB->cbp = 0;
for (l=0; l < 2; l++)
for (j=0; j < BLOCK_MULTIPLE; j++)
for (i=0; i < BLOCK_MULTIPLE; i++)
for (k=0; k < 2; k++)
currMB->mvd[l][j][i][k] = 0;
currMB->cbp_bits = 0;
currMB->c_ipred_mode = DC_PRED_8; //GB
for (i=0; i < (BLOCK_MULTIPLE*BLOCK_MULTIPLE); i++)
currMB->intra_pred_modes[i] = DC_PRED;
for (i=0; i < 16; i++)
currMB->intra_pred_modes8x8[i] = DC_PRED;
//initialize the whole MB as INTRA coded
//Blocks ar set to notINTRA in write_one_macroblock
if (input->UseConstrainedIntraPred)
{
img->intra_block[img->current_mb_nr] = 1;
}
// store filtering parameters for this MB; For now, we are using the
// same offset throughout the sequence
currMB->lf_disable = img->LFDisableIdc;
currMB->lf_alpha_c0_offset = img->LFAlphaC0Offset;
currMB->lf_beta_offset = img->LFBetaOffset;
// Initialize bitcounters for this macroblock
if(img->current_mb_nr == 0) // No slice header to account for
{
currMB->bitcounter[BITS_HEADER] = 0;
}
else if (currMB->slice_nr == img->mb_data[img->current_mb_nr-1].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;
#ifdef _FAST_FULL_ME_
if(!input->FMEnable)
ResetFastFullIntegerSearch ();
#endif
}
/*!
************************************************************************
* \brief
* terminates processing of the current macroblock depending
* on the chosen slice mode
************************************************************************
*/
void terminate_macroblock(Boolean *end_of_slice, Boolean *recode_macroblock)
{
int i;
Slice *currSlice = img->currentSlice;
Macroblock *currMB = &img->mb_data[img->current_mb_nr];
SyntaxElement *currSE = &img->MB_SyntaxElements[currMB->currSEnr];
int *partMap = assignSE2partition[input->partition_mode];
DataPartition *dataPart;
Bitstream *currStream;
int rlc_bits=0;
EncodingEnvironmentPtr eep;
int use_bitstream_backing = (input->slice_mode == FIXED_RATE || input->slice_mode == CALLBACK);
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) == img->total_number_mb) // maximum number of MBs reached
*end_of_slice = TRUE;
// if it's end of current slice group, slice ends too
*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 = (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr)));
//! Now check maximum # of MBs in slice
*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
currSE->value1 = img->cod_counter;
currSE->value2 = 0;
currSE->mapping = ue_linfo;
currSE->type = SE_MBTYPE;
dataPart = &(currSlice->partArr[partMap[currSE->type]]);
dataPart->writeSyntaxElement( currSE, dataPart);
rlc_bits=currSE->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;
// restore the bitstream
currStream->bits_to_go = currStream->stored_bits_to_go;
currStream->byte_pos = currStream->stored_byte_pos;
currStream->byte_buf = currStream->stored_byte_buf;
skip = TRUE;
}
//! Check if the last coded macroblock fits into the size of the slice
//! But only if this is not the first macroblock of this slice
if (!new_slice)
{
if(slice_too_big(rlc_bits))
{
*recode_macroblock = TRUE;
*end_of_slice = TRUE;
}
else if(!img->cod_counter)
skip = FALSE;
}
// maximum number of MBs
// check if current slice group is finished
if ((*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr))))
{
*end_of_slice = TRUE;
if(!img->cod_counter)
skip = FALSE;
}
//! (first MB OR first MB in a slice) AND bigger that maximum size of slice
if (new_slice && slice_too_big(rlc_bits))
{
*end_of_slice = TRUE;
if(!img->cod_counter)
skip = FALSE;
}
if (!*recode_macroblock)
currSlice->num_mb++;
break;
case CALLBACK:
if (img->current_mb_nr > 0 && !new_slice)
{
if (currSlice->slice_too_big(rlc_bits))
{
*recode_macroblock = TRUE;
*end_of_slice = TRUE;
}
}
if ( (*recode_macroblock == FALSE) && (img->current_mb_nr == FmoGetLastCodedMBOfSliceGroup (FmoMB2SliceGroup (img->current_mb_nr))))
*end_of_slice = TRUE;
break;
default:
snprintf(errortext, ET_SIZE, "Slice Mode %d not supported", input->slice_mode);
error(errortext, 600);
}
if(*recode_macroblock == TRUE)
{
// Restore everything
for (i=0; i<currSlice->max_part_nr; i++)
{
dataPart = &(currSlice->partArr[i]);
currStream = dataPart->bitstream;
currStream->bits_to_go = currStream->stored_bits_to_go;
currStream->byte_pos = currStream->stored_byte_pos;
currStream->byte_buf = currStream->stored_byte_buf;
if (input->symbol_mode == CABAC)
{
eep = &(dataPart->ee_cabac);
eep->Elow = eep->ElowS;
eep->Erange = eep->ErangeS;
eep->Ebuffer = eep->EbufferS;
eep->Ebits_to_go = eep->Ebits_to_goS;
eep->Ebits_to_follow = eep->Ebits_to_followS;
eep->Ecodestrm = eep->EcodestrmS;
eep->Ecodestrm_len = eep->Ecodestrm_lenS;
eep->C = eep->CS;
eep->B = eep->BS;
eep->E = eep->ES;
}
}
}
if(*end_of_slice == TRUE && skip == TRUE) //! TO 4.11.2001 Skip MBs at the end of this slice
{
//! only for Slice Mode 2 or 3
// If we still have to write the skip, let's do it!
if(img->cod_counter && *recode_macroblock == TRUE) //! MB that did not fit in this slice
{
// If recoding is true and we have had skip,
// we have to reduce the counter in case of recoding
img->cod_counter--;
if(img->cod_counter)
{
currSE->value1 = img->cod_counter;
currSE->value2 = 0;
currSE->mapping = ue_linfo;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -