📄 picencoder.cpp
字号:
return Err::m_nOK;
}
// }}
ErrVal
PicEncoder::process( PicBuffer* pcInputPicBuffer,
PicBufferList& rcOutputList,
PicBufferList& rcUnusedList,
ExtBinDataAccessorList& rcExtBinDataAccessorList )
{
ROF( m_bInitParameterSets );
//===== add picture to input picture buffer =====
RNOK( m_pcInputPicBuffer->add( pcInputPicBuffer ) );
//===== encode following access units that are stored in input picture buffer =====
while( true )
{
InputAccessUnit* pcInputAccessUnit = NULL;
//----- get next frame specification and input access unit -----
if( ! m_pcInputPicBuffer->empty() )
{
pcInputAccessUnit = m_pcInputPicBuffer->remove( m_cFrameSpecification.getContFrameNumber() );
}
if( ! pcInputAccessUnit )
{
break;
}
if ( (NAL_UNIT_CODED_SLICE_IDR != m_cFrameSpecification.getNalUnitType())&&
(m_MultiviewRefPicManager.CountNumMultiviewReferenceStreams() > 0) ) {
Double dLambdaForMVC = 0;
SliceHeader* pcSliceHeaderForMVC = 0;
RNOK( xInitSliceHeader( pcSliceHeaderForMVC, m_cFrameSpecification,
dLambdaForMVC, /* fakeHeader = */ true ) );
int poc = pcSliceHeaderForMVC->getPoc();
m_MultiviewRefPicManager.AddMultiviewReferencesPicturesToBuffer
(m_pcRecPicBuffer, pcSliceHeaderForMVC, rcOutputList,
rcUnusedList, *m_pcSPS, poc , this->TimeForVFrameP(poc));
}
//----- 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 ) );
// JVT-V043 encoder
m_pcRecPicBuffer->SetPictureEncoder(this->getpicEncoder()); //JVT-W056
RNOK( xInitReorderingInterView ( pcSliceHeader) );
#if JMVM_ONLY // JVT-W081
if ( m_pcCodingParameter->getMotionSkipMode() ) //
{
char f_char = 'P';
Int f_iPoc = pcSliceHeader->getPoc();
fwrite(&f_char,sizeof(char), 1, fMv);
fwrite(&f_iPoc, sizeof(Int), 1, fMv);
}
#endif // JVT-W081
//JVT-W080
if( getPdsEnable() && m_cFrameSpecification.isAnchor() )
{
setPdsInitialDelayMinus2L0( m_pcCodingParameter->getPdsInitialDelayMinus2L0Anc() );
setPdsInitialDelayMinus2L1( m_pcCodingParameter->getPdsInitialDelayMinus2L1Anc() );
}
else if( getPdsEnable() )
{
setPdsInitialDelayMinus2L0( m_pcCodingParameter->getPdsInitialDelayMinus2L0NonAnc() );
setPdsInitialDelayMinus2L1( m_pcCodingParameter->getPdsInitialDelayMinus2L1NonAnc() );
}
//~JVT-W080
//----- encoding -----
RNOK( xEncodePicture( rcExtBinDataAccessorList, *pcRecPicBufUnit, *pcSliceHeader, dLambda, uiPictureBits ) );
m_uiWrittenBytes += ( uiPictureBits >> 3 );
//SEI {
m_adMVCSeqBits[pcSliceHeader->getTemporalLevel()] += uiPictureBits;
m_auiMVCNumFramesCoded[pcSliceHeader->getTemporalLevel()] ++;
xModifyMaxBitrate( uiPictureBits );
//SEI }
m_MultiviewRefPicManager.RemoveMultiviewReferencesPicturesFromBuffer
(m_pcRecPicBuffer);
//----- store picture -----
RNOK( m_pcRecPicBuffer->store( pcRecPicBufUnit, pcSliceHeader, rcOutputList, rcUnusedList ) );
//----- reset -----
delete pcInputAccessUnit;
delete pcSliceHeader;
xGetNextFrameSpec(); //new configuration file
}
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()
);
//SEI {
UInt ui;
for( ui = 1; ui <= MAX_DSTAGES_MVC; ui++ )
{
m_adMVCSeqBits[ui] += m_adMVCSeqBits[ui-1];
m_auiMVCNumFramesCoded[ui] += m_auiMVCNumFramesCoded[ui-1];
}
for( ui = 0; ui < MAX_DSTAGES_MVC; ui++ )
{
Double dFps = (m_pcCodingParameter->getMaximumFrameRate()) * m_auiMVCNumFramesCoded[ui] / m_uiCodedFrames;
Double dScale = dFps / 1000 / (Double)m_auiMVCNumFramesCoded[ui];
m_dMVCFinalBitrate[ui] = m_adMVCSeqBits[ui] * dScale;
m_dMVCFinalFramerate[ui] = dFps;
}
//SEI }
return Err::m_nOK;
}
//SEI {
ErrVal
PicEncoder::xModifyMaxBitrate( UInt uiBits )
{
uiNumPics++;
if(uiNumPics > (UInt)m_pcCodingParameter->getMaximumFrameRate())
{
uiNumPics--;
for( UInt i = 0; i < uiNumPics - 1; i++ )
m_adMVCPicBits[i] = m_adMVCPicBits[i+1];
m_adMVCPicBits[uiNumPics-1] = uiBits;
}
else
m_adMVCPicBits[uiNumPics-1] = uiBits;
Double TotalBits = 0;
for( UInt i = 0; i < uiNumPics; i++ )
TotalBits += m_adMVCPicBits[i];
TotalBits = TotalBits * 0.001 * (m_pcCodingParameter->getMaximumFrameRate()) / uiNumPics;
if( TotalBits > m_adMaxBitRate )
m_adMaxBitRate = TotalBits;
return Err::m_nOK;
}
//SEI }
// AVC base and multiview SPSs and PPSs {{
ErrVal
PicEncoder::xInitSPS( Bool bAVCSPS )
{
ROF( m_bInit );
// ROT( m_pcSPS );
SequenceParameterSet*& rpcSPS = bAVCSPS ? m_pcSPSBase: m_pcSPS;
ROT( rpcSPS );
//===== determine parameters =====
UInt uiSPSId = bAVCSPS ? 0 : 1 ;
UInt uiMbX = m_pcCodingParameter->getFrameWidth () >> 4;
UInt uiMbY = m_pcCodingParameter->getFrameHeight() >> 4;
UInt uiOutFreq = (UInt)ceil( m_pcCodingParameter->getMaximumFrameRate() );
UInt uiMvRange = m_pcCodingParameter->getMotionVectorSearchParams().getSearchRange();
// UInt uiDPBSize = ( m_pcCodingParameter->getGOPSize() );
//Increase DPB by 4 to allow for interview pictures
UInt uiDPBSize = ( 1 << m_pcCodingParameter->getDecompositionStages());
if (!bAVCSPS) uiDPBSize+= 4;
m_pcCodingParameter->setDPBSize ( uiDPBSize );
//
UInt uiLevelIdc = SequenceParameterSet::getLevelIdc( uiMbY, uiMbX, uiOutFreq, uiMvRange, uiDPBSize );
//===== create parameter sets =====
RNOK( SequenceParameterSet::create( rpcSPS ) );
//===== set SPS parameters =====
rpcSPS->setNalUnitType ( NAL_UNIT_SPS );
rpcSPS->setLayerId ( 0 );
rpcSPS->setProfileIdc ( bAVCSPS ? ( m_pcCodingParameter->get8x8Mode() >0 ? HIGH_PROFILE : MAIN_PROFILE ) : MVC_PROFILE );
rpcSPS->setConstrainedSet0Flag ( false );
rpcSPS->setConstrainedSet1Flag ( false );
rpcSPS->setConstrainedSet2Flag ( false );
rpcSPS->setConstrainedSet3Flag ( false );
rpcSPS->setLevelIdc ( uiLevelIdc );
rpcSPS->setSeqParameterSetId ( uiSPSId );
rpcSPS->setSeqScalingMatrixPresentFlag ( m_pcCodingParameter->get8x8Mode() > 1 );
rpcSPS->setLog2MaxFrameNum ( m_pcCodingParameter->getLog2MaxFrameNum() );
rpcSPS->setLog2MaxPicOrderCntLsb ( m_pcCodingParameter->getLog2MaxPocLsb() );
rpcSPS->setNumRefFrames ( m_pcCodingParameter->getDPBSize ());
rpcSPS->setRequiredFrameNumUpdateBehaviourFlag ( true );
rpcSPS->setFrameWidthInMbs ( uiMbX );
rpcSPS->setFrameHeightInMbs ( uiMbY );
rpcSPS->setDirect8x8InferenceFlag ( true );
rpcSPS->setCurrentViewId(m_pcCodingParameter->getCurentViewId());
if( !bAVCSPS) // AVC base SPS
{
m_pcSPS->SpsMVC = new SpsMvcExtension;
memcpy( m_pcSPS->SpsMVC, &(m_pcCodingParameter->SpsMVC), sizeof ( SpsMvcExtension )) ;
// //m_pcSPS->SpsMVC = &(m_pcCodingParameter->SpsMVC); // need to destroy SpsMVC when m_pcSPS is released
}
else
{
m_pcSPSBase->SpsMVC = NULL;
}
return Err::m_nOK;
}
ErrVal
PicEncoder::xInitPPS( Bool bAVCSPS )
{
ROF( m_bInit );
// ROF( m_pcSPS );
PictureParameterSet *& rpcPPS = bAVCSPS ? m_pcPPSBase: m_pcPPS;
SequenceParameterSet*& rpcSPS = bAVCSPS ? m_pcSPSBase: m_pcSPS;
ROF( rpcSPS );
ROT( rpcPPS );
//===== determine parameters =====
UInt uiPPSId = bAVCSPS ? 0 : 1 ;
//===== create PPS =====
RNOK( PictureParameterSet ::create( rpcPPS ) );
//===== set PPS parameters =====
rpcPPS->setNalUnitType ( NAL_UNIT_PPS );
rpcPPS->setPicParameterSetId ( uiPPSId );
rpcPPS->setSeqParameterSetId ( rpcSPS->getSeqParameterSetId() );
rpcPPS->setEntropyCodingModeFlag ( m_pcCodingParameter->getSymbolMode() != 0 );
rpcPPS->setPicOrderPresentFlag ( true );
rpcPPS->setNumRefIdxActive ( LIST_0, m_pcCodingParameter->getNumRefFrames() );
rpcPPS->setNumRefIdxActive ( LIST_1, m_pcCodingParameter->getNumRefFrames() );
rpcPPS->setPicInitQp ( min( 51, max( 0, (Int)m_pcCodingParameter->getBasisQp() ) ) );
rpcPPS->setChomaQpIndexOffset ( 0 );
rpcPPS->setDeblockingFilterParametersPresentFlag ( ! m_pcCodingParameter->getLoopFilterParams().isDefault() );
rpcPPS->setConstrainedIntraPredFlag ( false );
rpcPPS->setRedundantPicCntPresentFlag ( false ); //JVT-Q054 Red. Picture
rpcPPS->setTransform8x8ModeFlag ( m_pcCodingParameter->get8x8Mode() > 0 );
rpcPPS->setPicScalingMatrixPresentFlag ( false );
rpcPPS->set2ndChromaQpIndexOffset ( 0 );
rpcPPS->setNumSliceGroupsMinus1 ( 0 );
//===== prediction weights =====
// m_pcPPS->setWeightedPredFlag ( WEIGHTED_PRED_FLAG );
// m_pcPPS->setWeightedBiPredIdc ( WEIGHTED_BIPRED_IDC );
//TMM_WP
rpcPPS->setWeightedPredFlag (m_pcCodingParameter->getIPMode()!=0);
rpcPPS->setWeightedBiPredIdc (m_pcCodingParameter->getBMode());
//TMM_WP
rpcPPS->setCurrentViewId(m_pcCodingParameter->getCurentViewId());
return Err::m_nOK;
}
// AVC base and multiview SPSs and PPSs }}
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 ) );
//==== 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;
}
// rplr and mmco: {{
ErrVal
PicEncoder::xSetRplr( RplrBuffer& rcRplrBuffer,
UIntList cFrameNumList,
UInt uiCurrFrameNr )
{
rcRplrBuffer.clear();
if( cFrameNumList.empty() )
{
rcRplrBuffer.setRefPicListReorderingFlag( false );
return Err::m_nOK;
}
UIntList::iterator iter = cFrameNumList.begin();
UInt uiCurrReorderNr = uiCurrFrameNr;
UInt uiCount = 0;
Int iSum = 0;
Bool bNeg = false;
Bool bPos = false;
for( ; iter != cFrameNumList.end(); iter++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -