📄 umc_h264_core_enc.cpp
字号:
if (m_info.transform_8x8_mode_flag && (m_Analyse & ANALYSE_I_8x8)) {
pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, true);
AdvancedIntraModeSelectOneMacroblock8x8(curr_slice, uMB, best_sad, &uAIMBSAD_8x8);
//Save intra_types
memcpy( intra_types_save, curr_slice->m_cur_mb.intra_types, 16*sizeof(T_AIMode));
if( uAIMBSAD_8x8 < best_sad ){
best_sad = uAIMBSAD_8x8;
uBestIntraMBType = MBTYPE_INTRA;
bIntra8x8 = true;
}
pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, false);
}
if (m_Analyse & ANALYSE_I_4x4) {
AdvancedIntraModeSelectOneMacroblock(curr_slice, uMB, best_sad, &uAIMBSAD_4x4);
cur_mb.mb[MBTYPE_INTRA].cbp = curr_slice->m_uIntraCBP4x4;
cur_mb.mb[MBTYPE_INTRA].sad = uAIMBSAD_4x4;
#ifdef H264_RD_OPT
memcpy(curr_slice->m_cur_mb.mb[MBTYPE_INTRA].intra_types, curr_slice->m_cur_mb.intra_types, 16*sizeof(T_AIMode));
#endif
if (uAIMBSAD_4x4 < best_sad) {
uBestIntraMBType = MBTYPE_INTRA;
best_sad = uAIMBSAD_4x4;
bIntra8x8 = false;
}
}
#ifndef H264_RD_OPT
}
#endif
}
curr_slice->m_uMBIntraSAD = best_sad;
cur_mb.GlobalMacroblockInfo->mbtype = static_cast<MBTypeValue>(uBestIntraMBType);
pSetMB8x8TSPackFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, bIntra8x8);
if (uBestIntraMBType == MBTYPE_INTRA && !bIntra8x8)
cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP4x4;
else if (uBestIntraMBType == MBTYPE_INTRA && bIntra8x8) {
cur_mb.LocalMacroblockInfo->cbp_luma = curr_slice->m_uIntraCBP8x8;
//Restore intra_types
memcpy(curr_slice->m_cur_mb.intra_types, intra_types_save, 16*sizeof(T_AIMode));
} else
cur_mb.LocalMacroblockInfo->cbp_luma = 0xffff;
cur_mb.LocalMacroblockInfo->cbp_chroma = 0xffffffff;
curr_slice->m_uMBInterSAD = MAX_SAD; // very large SAD
}
if (m_PicParamSet.chroma_format_idc == 0) {
// Monochrome
cur_mb.LocalMacroblockInfo->cbp_chroma = 0; // Clear chroma blocks.
}
#ifdef _INTRA_MODE_SWITCH_
curr_slice->m_uMBIntra16x16SAD = uAIMBSAD_16x16; // Save for mode possible switch later
#endif
cur_mb.LocalMacroblockInfo->best_distortion = best_sad;
return best_sad;
}
//////////////////////////////////
// Compress one slice
template <class PixType, class CoeffsType>
Status H264CoreEncoder<PixType,CoeffsType>::Compress_Slice(H264EncoderThreadPrivateSlice<PixType, CoeffsType> *curr_slice,
bool is_first_mb)
{
H264CurrentMacroblockDescriptor<PixType, CoeffsType> &cur_mb = curr_slice->m_cur_mb;
CH264pBs<PixType,CoeffsType> *pBitstream = curr_slice->m_pbitstream;
Ipp32s slice_num = curr_slice->m_slice_number;
EnumSliceType slice_type = curr_slice->m_slice_type;
Ipp8u uUsePCM = 0;
#ifdef H264_RD_OPT
double lambda;
#endif
// Ipp32s mbtype_stat[32];
// memset( mbtype_stat, 0, 32*sizeof(Ipp32s));
Ipp8u *pStartBits;
Ipp32u uStartBitOffset;
Ipp32u uRecompressMB;
Ipp8u iLastQP;
Ipp32u uSaved_Skip_Run;
Ipp8u bSeenFirstMB = false;
Status status = UMC_OK;
Ipp32u uNumMBs = m_HeightInMBs * m_WidthInMBs;
Ipp32u uFirstMB = m_field_index*uNumMBs;
Ipp32s MBYAdjust=0;
if (m_field_index)
{
MBYAdjust = m_HeightInMBs;
}
curr_slice->m_InitialOffset = m_InitialOffsets[m_pCurrentFrame->m_bottom_field_flag[m_field_index]];
curr_slice->m_is_cur_mb_field = m_pCurrentFrame->m_PictureStructureForDec < FRM_STRUCTURE;
curr_slice->m_is_cur_mb_bottom_field = m_pCurrentFrame->m_bottom_field_flag[m_field_index] == 1;
// curr_slice->m_use_transform_for_intra_decision = m_info.use_transform_for_intra_decision ?
// (curr_slice->m_slice_type == INTRASLICE) : false;
curr_slice->m_use_transform_for_intra_decision = 1;
// loop over all MBs in the picture
for (Ipp32u uMB = uFirstMB; uMB < uFirstMB + uNumMBs; uMB++)
{
// Is this MB in the current slice? If not, move on...
if (m_pCurrentFrame->m_mbinfo.mbs[uMB].slice_id != slice_num) {
continue;
} else if (!bSeenFirstMB)
{
// Reset xpos and ypos in framedata struct
// This is necessary because the same slice may be recoded multiple times.
// reset intra MB counter per slice
curr_slice->m_Intra_MB_Counter = 0;
curr_slice->m_MB_Counter = 0;
// Fill in the first mb in slice field in the slice header.
curr_slice->m_first_mb_in_slice = is_first_mb ? 0 : uMB - uFirstMB;
// Fill in the current deblocking filter parameters.
curr_slice->m_slice_alpha_c0_offset = (Ipp8s)m_info.deblocking_filter_alpha;
curr_slice->m_slice_beta_offset = (Ipp8s)m_info.deblocking_filter_beta;
curr_slice->m_disable_deblocking_filter_idc = m_info.deblocking_filter_idc;
curr_slice->m_cabac_init_idc = m_info.cabac_init_idc;
// Write a slice header
pBitstream->PutSliceHeader(m_SliceHeader,
m_PicParamSet,
m_SeqParamSet,
m_PicClass,
curr_slice);
bSeenFirstMB = true;
// Fill in the correct value for m_iLastXmittedQP, used to correctly code
// the per MB QP Delta
curr_slice->m_iLastXmittedQP = m_PicParamSet.pic_init_qp + curr_slice->m_slice_qp_delta;
Ipp32s SliceQPy = curr_slice->m_iLastXmittedQP;
#ifdef H264_RD_OPT
// lambda = pow(2.0,MAX(0,(SliceQPy-12))/3.0);
// lambda = pow(2.0,(SliceQPy-12)/3.0);
/* if( slice_type == INTRASLICE ) lambda *= 0.85;
else
*/ lambda *= 0.85;
//if( slice_type == BPREDSLICE ) lambda *= IPP_MAX(2, IPP_MIN(4,SliceQPy/6)); //B slices
#endif
if (m_info.entropy_coding_mode)
{
if (slice_type==INTRASLICE)
pBitstream->InitializeContextVariablesIntra_CABAC(SliceQPy);
else
pBitstream->InitializeContextVariablesInter_CABAC(SliceQPy, curr_slice->m_cabac_init_idc);
}
// Initialize the MB skip run counter
curr_slice->m_uSkipRun = 0;
}
cur_mb.lambda = int( pow(2.0,MAX(0,(curr_slice->m_iLastXmittedQP-12))/3.0)*0.85 );
cur_mb.uMB = curr_slice->m_CurMBAddr = uMB;
cur_mb.mbPtr = m_pCurrentFrame->m_pYPlane + m_pMBOffsets[uMB].uLumaOffset[m_is_cur_pic_afrm][curr_slice->m_is_cur_mb_field];
cur_mb.mbPitchPixels = m_pCurrentFrame->pitchPixels()<<curr_slice->m_is_cur_mb_field;
curr_slice->m_CurMB_X = (curr_slice->m_CurMBAddr % m_WidthInMBs);
curr_slice->m_CurMB_Y = (curr_slice->m_CurMBAddr / m_WidthInMBs)- MBYAdjust;
UpdateCurrentMBInfo(curr_slice);
pSetMB8x8TSFlag(curr_slice->m_cur_mb.GlobalMacroblockInfo, 0);
curr_slice->m_MB_Counter++;
pBitstream->GetState(&pStartBits, &uStartBitOffset);
iLastQP = curr_slice->m_iLastXmittedQP;
uSaved_Skip_Run = curr_slice->m_uSkipRun; // To restore it if we recompress
uUsePCM = 0; // Don't use the PCM mode initially.
UpdateNeighbouringAddresses(curr_slice);
UpdateNeighbouringBlocks(curr_slice);
cur_mb.mb[MBTYPE_INTRA].sad = cur_mb.mb[MBTYPE_INTRA_16x16].sad = cur_mb.mb[MBTYPE_INTER].sad = 0xffffffff;
cur_mb.mb[MBTYPE_INTRA].ssd = cur_mb.mb[MBTYPE_INTRA_16x16].ssd = cur_mb.mb[MBTYPE_INTER].ssd = 0xffffffff;
cur_mb.mb[MBTYPE_INTRA].bits = cur_mb.mb[MBTYPE_INTRA_16x16].bits = cur_mb.mb[MBTYPE_INTER].bits = 0xffffffff; //(1<<31)-1;
do { // this is to recompress MBs that are too big.
MB_Decision(curr_slice, uMB);
Ipp32s mb_bits;
Ipp32s bit_offset;
if( m_PicParamSet.entropy_coding_mode ){
bit_offset = pBitstream->m_nReadyBits;
if(pBitstream->m_nReadyBits == 9) bit_offset=8;
}
#ifdef H264_RD_OPT
Ipp32s xi = 3;
Ipp8s mbType = cur_mb.GlobalMacroblockInfo->mbtype;
if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
Ipp32u bestSAD = cur_mb.mb[mbType].sad;
H264MotionVector MBmvs[16*4];
T_RefIdx MBridx[16*2];
//Copy INTER state
memcpy(&MBmvs[0],cur_mb.MVs[LIST_0]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&MBmvs[16],cur_mb.MVs[LIST_1]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&MBmvs[32],cur_mb.MVs[LIST_0+2]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&MBmvs[48],cur_mb.MVs[LIST_1+2]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&MBridx[0],cur_mb.RefIdxs[LIST_0]->RefIdxs,sizeof(T_RefIdx)*16);
memcpy(&MBridx[16],cur_mb.RefIdxs[LIST_1]->RefIdxs,sizeof(T_RefIdx)*16);
if( m_PicParamSet.entropy_coding_mode ){
pBitstream->SaveContext_CABAC();
}
do{
#endif
// Code the macroblock, all planes
// coefficients -> pRLEBuffer
cur_mb.LocalMacroblockInfo->cbp_bits = 0;
cur_mb.LocalMacroblockInfo->cbp_bits_chroma = 0;
uSaved_Skip_Run = curr_slice->m_uSkipRun;
CEncAndRecMB(curr_slice) ;
mb_bits = 0;
status = Put_MB(curr_slice);
if (status != UMC_OK) goto done;
if (m_PicParamSet.entropy_coding_mode){
pBitstream->EncodeFinalSingleBin_CABAC( (uMB==uFirstMB + uNumMBs - 1) || (m_pCurrentFrame->m_mbinfo.mbs[uMB + 1].slice_id != slice_num) );
mb_bits = bit_offset - pBitstream->m_nReadyBits;
}
Ipp8u *pEndBits;
Ipp32u uEndBitOffset;
pBitstream->GetState(&pEndBits, &uEndBitOffset);
mb_bits += (Ipp32u) (pEndBits - pStartBits)*8;
if (uEndBitOffset >= uStartBitOffset)
mb_bits += uEndBitOffset - uStartBitOffset;
else
mb_bits -= uStartBitOffset - uEndBitOffset;
#ifdef H264_RD_OPT
// if( slice_type != INTRASLICE ) break;
mbType = cur_mb.GlobalMacroblockInfo->mbtype;
if( !IS_INTRA_MBTYPE(mbType) ) mbType = MBTYPE_INTER;
//if SADs are similar take RD optimized
cur_mb.mb[mbType].bits = mb_bits;
cur_mb.mb[mbType].skip_run = curr_slice->m_uSkipRun;
memcpy( cur_mb.mb[mbType].intra_types, cur_mb.intra_types, 16);
memcpy( cur_mb.mb[mbType].stream, pStartBits, (pEndBits - pStartBits + 1));
cur_mb.mb[mbType].stream_size = (pEndBits - pStartBits + 1);
cur_mb.mb[mbType].stream_offset = uEndBitOffset;
memcpy(&(cur_mb.mb[mbType].locInfo),cur_mb.LocalMacroblockInfo,sizeof(H264MacroblockLocalInfo));
memcpy(&(cur_mb.mb[mbType].globInfo),cur_mb.GlobalMacroblockInfo,sizeof(H264MacroblockGlobalInfo));
memcpy(&(cur_mb.mb[mbType].coeffInfo), cur_mb.MacroblockCoeffsInfo, sizeof(H264MacroblockCoeffsInfo));
memcpy(&cur_mb.mb[mbType].MBmvs[0],cur_mb.MVs[LIST_0]->MotionVectors,sizeof(H264MotionVector)*16);
memcpy(&cur_mb.mb[mbType].MBmvs[16],cur_mb.MVs[LIST_1]->MotionVectors,sizeof(H264MotionVector)*16);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -