📄 picencoder.cpp
字号:
pcInputAccessUnit = m_pcInputPicBuffer->remove( m_cFrameSpecification.getContFrameNumber() );
}
if( ! pcInputAccessUnit )
{
break;
}
//----- initialize picture -----
Double dLambda = 0;
UInt uiPictureBits = 0;
SliceHeader* pcSliceHeader = 0;
RecPicBufUnit* pcRecPicBufUnit = 0;
PicBuffer* pcOrigPicBuffer = pcInputAccessUnit->getInputPicBuffer();
RNOK( xInitSliceHeader( pcSliceHeader, m_cFrameSpecification, dLambda ) );
RNOK( m_pcRecPicBuffer->initCurrRecPicBufUnit( pcRecPicBufUnit, pcOrigPicBuffer, pcSliceHeader, rcOutputList, rcUnusedList ) );
//----- encoding -----
RNOK( xEncodePicture( rcExtBinDataAccessorList, *pcRecPicBufUnit, *pcSliceHeader, dLambda, uiPictureBits ) );
m_uiWrittenBytes += ( uiPictureBits >> 3 );
//----- store picture -----
RNOK( m_pcRecPicBuffer->store( pcRecPicBufUnit, pcSliceHeader, rcOutputList, rcUnusedList ) );
//----- reset -----
delete pcInputAccessUnit;
delete pcSliceHeader;
m_cFrameSpecification.uninit();
}
return Err::m_nOK;
}
ErrVal
PicEncoder::finish( PicBufferList& rcOutputList,
PicBufferList& rcUnusedList )
{
RNOK( m_pcRecPicBuffer->clear( rcOutputList, rcUnusedList ) );
//===== output summary =====
printf("\n %5d frames encoded: Y %7.4lf dB U %7.4lf dB V %7.4lf dB\n"
"\n average bit rate: %.4lf kbit/s [%d byte for %.3lf sec]\n\n",
m_uiCodedFrames,
m_dSumYPSNR / (Double)m_uiCodedFrames,
m_dSumUPSNR / (Double)m_uiCodedFrames,
m_dSumVPSNR / (Double)m_uiCodedFrames,
0.008*(Double)m_uiWrittenBytes/(Double)m_uiCodedFrames*m_pcCodingParameter->getMaximumFrameRate(),
m_uiWrittenBytes,
(Double)m_uiCodedFrames/m_pcCodingParameter->getMaximumFrameRate()
);
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitSPS()
{
ROF( m_bInit );
ROT( m_pcSPS );
//===== determine parameters =====
UInt uiSPSId = 0;
UInt uiMbX = ( m_pcCodingParameter->getFrameWidth () + 15 ) >> 4;
UInt uiMbY = ( m_pcCodingParameter->getFrameHeight() + 15 ) >> 4;
UInt uiOutFreq = (UInt)ceil( m_pcCodingParameter->getMaximumFrameRate() );
UInt uiMvRange = m_pcCodingParameter->getMotionVectorSearchParams().getSearchRange();
UInt uiDPBSize = m_pcCodingParameter->getDPBSize();
UInt uiLevelIdc = SequenceParameterSet::getLevelIdc( uiMbY, uiMbX, uiOutFreq, uiMvRange, uiDPBSize, 0, 0 );
//===== create parameter sets =====
RNOK( SequenceParameterSet::create( m_pcSPS ) );
//===== set SPS parameters =====
m_pcSPS->setNalUnitType ( NAL_UNIT_SPS );
m_pcSPS->setAVCHeaderRewriteFlag( false );
m_pcSPS->setDependencyId ( 0 );
m_pcSPS->setProfileIdc ( HIGH_PROFILE );
m_pcSPS->setConstrainedSet0Flag ( false );
m_pcSPS->setConstrainedSet1Flag ( false );
m_pcSPS->setConstrainedSet2Flag ( false );
m_pcSPS->setConstrainedSet3Flag ( false );
m_pcSPS->setLevelIdc ( uiLevelIdc );
m_pcSPS->setSeqParameterSetId ( uiSPSId );
m_pcSPS->setSeqScalingMatrixPresentFlag ( m_pcCodingParameter->get8x8Mode() > 1 );
m_pcSPS->setLog2MaxFrameNum ( m_pcCodingParameter->getLog2MaxFrameNum() );
m_pcSPS->setLog2MaxPicOrderCntLsb ( m_pcCodingParameter->getLog2MaxPocLsb() );
m_pcSPS->setNumRefFrames ( m_pcCodingParameter->getNumDPBRefFrames() );
m_pcSPS->setGapsInFrameNumValueAllowedFlag ( true );
m_pcSPS->setFrameWidthInMbs ( uiMbX );
m_pcSPS->setFrameHeightInMbs ( uiMbY );
m_pcSPS->setDirect8x8InferenceFlag ( true );
// JVT-V068 {
m_pcSPS->setVUI (m_pcSPS);
// JVT-V068 }
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitPPS()
{
ROF( m_bInit );
ROF( m_pcSPS );
ROT( m_pcPPS );
//===== determine parameters =====
UInt uiPPSId = 0;
//===== create PPS =====
RNOK( PictureParameterSet ::create( m_pcPPS ) );
//===== set PPS parameters =====
m_pcPPS->setNalUnitType ( NAL_UNIT_PPS );
m_pcPPS->setPicParameterSetId ( uiPPSId );
m_pcPPS->setSeqParameterSetId ( m_pcSPS->getSeqParameterSetId() );
m_pcPPS->setEntropyCodingModeFlag ( m_pcCodingParameter->getSymbolMode() != 0 );
m_pcPPS->setPicOrderPresentFlag ( true );
m_pcPPS->setNumRefIdxActive ( LIST_0, m_pcCodingParameter->getMaxRefIdxActiveBL0() );
m_pcPPS->setNumRefIdxActive ( LIST_1, m_pcCodingParameter->getMaxRefIdxActiveBL1() );
m_pcPPS->setPicInitQp ( min( 51, max( 0, (Int)m_pcCodingParameter->getBasisQp() ) ) );
m_pcPPS->setChomaQpIndexOffset ( 0 );
m_pcPPS->setDeblockingFilterParametersPresentFlag ( ! m_pcCodingParameter->getLoopFilterParams().isDefault() );
m_pcPPS->setConstrainedIntraPredFlag ( false );
m_pcPPS->setRedundantPicCntPresentFlag ( false ); //JVT-Q054 Red. Picture
m_pcPPS->setTransform8x8ModeFlag ( m_pcCodingParameter->get8x8Mode() > 0 );
m_pcPPS->setPicScalingMatrixPresentFlag ( false );
m_pcPPS->set2ndChromaQpIndexOffset ( 0 );
m_pcPPS->setNumSliceGroupsMinus1 ( 0 );
//===== prediction weights =====
// m_pcPPS->setWeightedPredFlag ( WEIGHTED_PRED_FLAG );
// m_pcPPS->setWeightedBiPredIdc ( WEIGHTED_BIPRED_IDC );
//TMM_WP
m_pcPPS->setWeightedPredFlag (m_pcCodingParameter->getIPMode()!=0);
m_pcPPS->setWeightedBiPredIdc (m_pcCodingParameter->getBMode());
//TMM_WP
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitParameterSets()
{
//===== init control manager =====
RNOK( m_pcControlMng->initParameterSets( *m_pcSPS, *m_pcPPS, *m_pcPPS ) );
//===== set fixed parameters =====
m_uiFrameWidthInMb = m_pcSPS->getFrameWidthInMbs ();
m_uiFrameHeightInMb = m_pcSPS->getFrameHeightInMbs ();
m_uiMbNumber = m_uiFrameWidthInMb * m_uiFrameHeightInMb;
//===== re-allocate dynamic memory =====
RNOK( xDeleteData() );
RNOK( xCreateData() );
//===== init objects =====
RNOK( m_pcRecPicBuffer ->initSPS ( *m_pcSPS ) );
RNOK( m_pcSequenceStructure ->init ( m_pcCodingParameter->getSequenceFormatString(),
m_pcCodingParameter->getTotalFrames() ) );
//----- check for encoder/decoder capabilities -----
ROF( m_pcSequenceStructure->getNumberOfIDRFrames() == 1 );
//==== initialize variable parameters =====
m_uiFrameNum = 0;
m_uiIdrPicId = 0;
m_bInitParameterSets = true;
return Err::m_nOK;
}
ErrVal
PicEncoder::xCreateData()
{
//===== write buffer =====
UInt uiNum4x4Blocks = m_uiFrameWidthInMb * m_uiFrameHeightInMb * 4 * 4;
m_uiWriteBufferSize = 3 * ( uiNum4x4Blocks * 4 * 4 );
ROFS( ( m_pucWriteBuffer = new UChar [ m_uiWriteBufferSize ] ) );
return Err::m_nOK;
}
ErrVal
PicEncoder::xDeleteData()
{
//===== write buffer =====
delete [] m_pucWriteBuffer;
m_pucWriteBuffer = 0;
m_uiWriteBufferSize = 0;
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitSliceHeader( SliceHeader*& rpcSliceHeader,
const FrameSpec& rcFrameSpec,
Double& rdLambda )
{
ROF( m_bInitParameterSets );
//===== create new slice header =====
rpcSliceHeader = new SliceHeader( *m_pcSPS, *m_pcPPS );
ROF( rpcSliceHeader );
//===== determine parameters =====
Double dQp = m_pcCodingParameter->getBasisQp() + m_pcCodingParameter->getDeltaQpLayer( rcFrameSpec.getTemporalLayer() );
Int iQp = min( 51, max( 0, (Int)dQp ) );
rdLambda = 0.85 * pow( 2.0, min( 52.0, dQp ) / 3.0 - 4.0 );
UInt uiSizeL0 = ( rcFrameSpec.getSliceType() == I_SLICE ? 0 :
rcFrameSpec.getSliceType() == P_SLICE ? m_pcCodingParameter->getMaxRefIdxActiveP () :
rcFrameSpec.getSliceType() == B_SLICE ? m_pcCodingParameter->getMaxRefIdxActiveBL0() : MSYS_UINT_MAX );
UInt uiSizeL1 = ( rcFrameSpec.getSliceType() == I_SLICE ? 0 :
rcFrameSpec.getSliceType() == P_SLICE ? 0 :
rcFrameSpec.getSliceType() == B_SLICE ? m_pcCodingParameter->getMaxRefIdxActiveBL1() : MSYS_UINT_MAX );
//===== set NAL unit header =====
rpcSliceHeader->setNalRefIdc ( rcFrameSpec.getNalRefIdc () );
rpcSliceHeader->setNalUnitType ( rcFrameSpec.getNalUnitType () );
rpcSliceHeader->setDependencyId ( 0 );
rpcSliceHeader->setTemporalId ( rcFrameSpec.getTemporalLayer() );
rpcSliceHeader->setUseRefBasePicFlag ( false );
rpcSliceHeader->setStoreRefBasePicFlag ( false );
rpcSliceHeader->setPriorityId ( 0 );
rpcSliceHeader->setDiscardableFlag ( false );
rpcSliceHeader->setQualityId ( 0 );
rpcSliceHeader->setIdrFlag ( rcFrameSpec.getNalUnitType () == NAL_UNIT_CODED_SLICE_IDR );
//===== set general parameters =====
rpcSliceHeader->setFirstMbInSlice ( 0 );
rpcSliceHeader->setLastMbInSlice ( m_uiMbNumber - 1 );
rpcSliceHeader->setSliceType ( rcFrameSpec.getSliceType () );
rpcSliceHeader->setFrameNum ( m_uiFrameNum );
rpcSliceHeader->setNumMbsInSlice ( m_uiMbNumber );
rpcSliceHeader->setIdrPicId ( m_uiIdrPicId );
rpcSliceHeader->setDirectSpatialMvPredFlag ( true );
rpcSliceHeader->setRefLayer ( MSYS_UINT_MAX, 15 );
rpcSliceHeader->setNoInterLayerPredFlag ( true );
rpcSliceHeader->setAdaptiveBaseModeFlag ( false );
rpcSliceHeader->setNoOutputOfPriorPicsFlag ( false );
rpcSliceHeader->setCabacInitIdc ( 0 );
rpcSliceHeader->setSliceHeaderQp ( iQp );
//===== reference picture list ===== (init with default data, later updated)
rpcSliceHeader->setNumRefIdxActiveOverrideFlag ( false );
rpcSliceHeader->setNumRefIdxActive ( LIST_0, uiSizeL0 );
rpcSliceHeader->setNumRefIdxActive ( LIST_1, uiSizeL1 );
//===== set deblocking filter parameters =====
if( rpcSliceHeader->getPPS().getDeblockingFilterParametersPresentFlag() )
{
rpcSliceHeader->getDeblockingFilterParameter().setDisableDeblockingFilterIdc( m_pcCodingParameter->getLoopFilterParams().getFilterIdc () );
rpcSliceHeader->getDeblockingFilterParameter().setSliceAlphaC0Offset ( 2*m_pcCodingParameter->getLoopFilterParams().getAlphaOffset () );
rpcSliceHeader->getDeblockingFilterParameter().setSliceBetaOffset ( 2*m_pcCodingParameter->getLoopFilterParams().getBetaOffset () );
}
//===== set picture order count =====
RNOK( m_pcPocCalculator->setPoc( *rpcSliceHeader, rcFrameSpec.getContFrameNumber() ) );
//===== set MMCO commands =====
if( rcFrameSpec.getMmcoBuf() )
{
rpcSliceHeader->getDecRefPicMarking().copy( *rcFrameSpec.getMmcoBuf() );
rpcSliceHeader->getDecRefPicMarking().setAdaptiveRefPicMarkingModeFlag( true );
}
//===== set RPRL commands =====
if( rcFrameSpec.getRplrBuf( LIST_0 ) )
{
rpcSliceHeader->getRefPicListReordering( LIST_0 ).copy( *rcFrameSpec.getRplrBuf( LIST_0 ) );
}
if( rcFrameSpec.getRplrBuf( LIST_1 ) )
{
rpcSliceHeader->getRefPicListReordering( LIST_1 ).copy( *rcFrameSpec.getRplrBuf( LIST_1 ) );
}
#if 0
//===== initialize prediction weights =====
RNOK( xInitPredWeights( *rpcSliceHeader ) );
#endif
//===== flexible macroblock ordering =====
rpcSliceHeader->setSliceGroupChangeCycle( 1 );
rpcSliceHeader->FMOInit();
//===== update parameters =====
if( rpcSliceHeader->getNalRefIdc() )
{
m_uiFrameNum = ( m_uiFrameNum + 1 ) % ( 1 << rpcSliceHeader->getSPS().getLog2MaxFrameNum() );
}
if( rpcSliceHeader->getIdrFlag() )
{
m_uiIdrPicId = ( m_uiIdrPicId + 1 ) % 3;
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitPredWeights( SliceHeader& rcSliceHeader )
{
if( rcSliceHeader.isPSlice() )
{
if( rcSliceHeader.getPPS().getWeightedPredFlag() )
{
rcSliceHeader.setLumaLog2WeightDenom ( 6 );
rcSliceHeader.setChromaLog2WeightDenom( 6 );
RNOK( rcSliceHeader.getPredWeightTableL0().initDefaults( rcSliceHeader.getLumaLog2WeightDenom(), rcSliceHeader.getChromaLog2WeightDenom() ) );
RNOK( rcSliceHeader.getPredWeightTableL0().initRandomly() );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -