📄 sliceencoder.cpp
字号:
Frame* apcBaseLayer [4] = { NULL, NULL, NULL, NULL };
Frame* apcPredSignal[4] = { NULL, NULL, NULL, NULL };
RNOK( gSetFrameFieldArrays( apcOrgFrame, pcOrgFrame ) );
RNOK( gSetFrameFieldArrays( apcFrame, pcFrame ) );
RNOK( gSetFrameFieldArrays( apcRecSubband, pcRecSubband ) );
RNOK( gSetFrameFieldArrays( apcBaseLayer, pcBaseLayer ) );
RNOK( gSetFrameFieldArrays( apcPredSignal, pcPredSignal ) );
YuvMbBuffer acIntYuvMbBufferPredSignal[2];
YuvMbBuffer acIntYuvMbBufferRecSubBand[2];
YuvMbBuffer acIntYuvMbBufferFrame [2];
UInt uiLastQp = rcSliceHeader.getSliceQp();
//===== loop over macroblocks =====
UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice ();
const UInt uiLastMbAddress = rcSliceHeader.getLastMbInSlice ();
for( ; uiMbAddress<= uiLastMbAddress; uiMbAddress+=2 )
{
MbDataBuffer acMbData[2];
Double adCost[2] = {0,0};
YuvMbBuffer cTempBuffer;
UInt auiLastQpTest[2] = {uiLastQp, uiLastQp};
Int eP;
for( eP = 0; eP < 4; eP++ )
{
MbDataAccess* pcMbDataAccess = NULL;
MbDataAccess* pcMbDataAccessBase = NULL;
Double dCost = 0;
UInt uiMbY, uiMbX;
const Bool bField = (eP < 2);
const UInt uiMbAddressMbAff = uiMbAddress+(eP%2);
rcSliceHeader.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddressMbAff );
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
if (eP < 2 && pcBaseLayerCtrlField) // field case
{
RNOK( pcBaseLayerCtrlField ->initMb( pcMbDataAccessBase, uiMbY, uiMbX ) );
}
else if (eP >= 2 && pcBaseLayerCtrl ) //frame case
{
RNOK( pcBaseLayerCtrl ->initMb( pcMbDataAccessBase, uiMbY, uiMbX ) );
}
RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, true, bField ) );
pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
if( ! rcSliceHeader.getNoInterLayerPredFlag() )
{
Int iField = ( bField ? 1 : 0 );
m_pcMbEncoder->setBaseModeAllowedFlag( m_apabBaseModeFlagAllowedArrays[iField][uiMbAddressMbAff] );
}
pcMbDataAccess->setLastQp( auiLastQpTest[bField] );
RNOK( m_pcMbEncoder ->encodeIntra ( *pcMbDataAccess,
pcMbDataAccessBase,
apcOrgFrame [eP],
apcFrame [eP],
apcRecSubband[eP],
apcBaseLayer [eP],
apcPredSignal[eP],
dLambda,
dCost ) );
auiLastQpTest[bField] = pcMbDataAccess->getMbData().getQp();
if( adCost[eP>>1] != DOUBLE_MAX )
{
adCost [eP>>1] += dCost;
}
if( bField )
{
acMbData[eP].copy( pcMbDataAccess->getMbData() );
acIntYuvMbBufferPredSignal[eP].loadBuffer( apcPredSignal[eP]->getFullPelYuvBuffer() );
acIntYuvMbBufferRecSubBand[eP].loadBuffer( apcRecSubband[eP]->getFullPelYuvBuffer() );
acIntYuvMbBufferFrame [eP].loadBuffer( apcFrame [eP]->getFullPelYuvBuffer() );
}
}
const Bool bFieldMode = ( adCost[0] < adCost[1] );
#ifdef RANDOM_MBAFF
bFieldMode = gBoolRandom();
#endif
// coding part
for( eP = 0; eP < 2; eP++ )
{
MbDataAccess* pcMbDataAccess = NULL;
MbDataAccess* pcMbDataAccessBase = NULL;
UInt uiMbY, uiMbX;
const UInt uiMbAddressMbAff = uiMbAddress+eP;
ETRACE_NEWMB( uiMbAddressMbAff );
rcSliceHeader.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddressMbAff );
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
if( bFieldMode && pcBaseLayerCtrlField )
{
RNOK( pcBaseLayerCtrlField ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) );
}
else if( !bFieldMode && pcBaseLayerCtrl )
{
RNOK( pcBaseLayerCtrl ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) );
}
RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, true, bFieldMode ) );
if( bFieldMode )
{
pcMbDataAccess->getMbData().copy( acMbData[eP] );
apcRecSubband [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferRecSubBand[eP] );
apcPredSignal [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferPredSignal[eP] );
apcFrame [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferFrame [eP] );
}
pcMbDataAccess->setLastQp( uiLastQp );
uiLastQp = pcMbDataAccess->getMbData().getQp();
pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
RNOK( m_pcMbCoder ->encode ( *pcMbDataAccess,
pcMbDataAccessBase,
( uiMbAddressMbAff == uiLastMbAddress ),
(eP == 1) ) );
}
}
ruiBits += m_pcMbCoder ->getBitCount() - uiBits;
return Err::m_nOK;
}
// TMM_INTERLACE}
ErrVal SliceEncoder::encodeHighPassPicture( UInt& ruiMbCoded,
UInt& ruiBits,
SliceHeader& rcSH,
Frame* pcOrgFrame,
Frame* pcFrame,
Frame* pcResidual,
Frame* pcPredSignal,
Frame* pcBaseSubband,
Frame* pcBaseLayer,
MbDataCtrl* pcMbDataCtrl,
MbDataCtrl* pcMbDataCtrlBaseMotion,
UInt uiMbInRow,
Double dLambda,
Int iMaxDeltaQp,
PicType ePicType )
{
ROF( m_bInitDone );
RNOK( pcMbDataCtrl ->initSlice ( rcSH, PRE_PROCESS, false, NULL ) );
RNOK( m_pcControlMng->initSliceForCoding( rcSH ) );
//====== initialization ======
UInt uiMbAddress = rcSH.getFirstMbInSlice();
UInt uiLastMbAddress = rcSH.getLastMbInSlice ();
UInt uiBits = m_pcMbCoder->getBitCount();
Int iQPRes = rcSH.getSliceQp();
Int iQPIntra = rcSH.getSliceQp(); //- 2;
YuvMbBuffer cZeroBuffer;
cZeroBuffer.setAllSamplesToZero();
if( ePicType!=FRAME )
{
if( pcOrgFrame ) RNOK( pcOrgFrame ->addFieldBuffer( ePicType ) ); //TMM
if( pcFrame ) RNOK( pcFrame ->addFieldBuffer( ePicType ) );
if( pcResidual ) RNOK( pcResidual ->addFieldBuffer( ePicType ) );
if( pcBaseSubband ) RNOK( pcBaseSubband->addFieldBuffer( ePicType ) );
if( pcBaseLayer ) RNOK( pcBaseLayer ->addFieldBuffer( ePicType ) );
if( pcPredSignal ) RNOK( pcPredSignal ->addFieldBuffer( ePicType ) );
}
//===== loop over macroblocks =====
for( ruiMbCoded = 0; uiMbAddress <= uiLastMbAddress; ) //--ICU/ETRI FMO Implementation
{
// JVT-W043 {
if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId )
{
pcGenericRC->m_pcJSVMParams->number = pcGenericRC->m_pcJSVMParams->current_frame_number;
pcJSVMParams->CurrGopLevel = pcGenericRC->getCurrGopLevel( pcGenericRC->m_pcJSVMParams->number );
pcGenericRC->m_pcJSVMParams->nal_reference_idc = (pcJSVMParams->CurrGopLevel == 0) ? 0 : 1;
pcGenericRC->m_pcJSVMParams->current_mb_nr = uiMbAddress;
if( pcGenericRC->m_pcJSVMParams->basicunit == pcGenericRC->m_pcJSVMParams->FrameSizeInMbs ) {
// qp remains unchanged
}
// basic unit layer rate control
else if ( pcGenericRC->m_pcJSVMParams->type == P_SLICE ) {
if( pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks > 0
&& (pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks % pcGenericRC->m_pcJSVMParams->BasicUnit) == 0 ) {
// frame coding
if( pcGenericRC->m_pcJSVMParams->frame_mbs_only_flag ) {
pcQuadraticRC->updateRCModel();
pcGenericRC->m_pcJSVMParams->qp = pcQuadraticRC->updateQPRC2( pcGenericRC->m_iTopFieldFlag );
iQPRes = pcGenericRC->m_pcJSVMParams->qp;
}
}
}
}
// JVT-W043 }
ETRACE_NEWMB( uiMbAddress );
MbDataAccess* pcMbDataAccess = NULL;
Bool bCoded;
UInt uiMbY, uiMbX;
rcSH.getMbPositionFromAddress ( uiMbY, uiMbX, uiMbAddress );
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
RNOK( m_pcControlMng ->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, false, false ) );
MbDataAccess* pcMbDataAccessBase = 0;
if( pcMbDataCtrlBaseMotion)
{
RNOK( pcMbDataCtrlBaseMotion->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) );
}
pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
pcMbDataAccess->getMbData().setFieldFlag(ePicType!=FRAME);
if( pcMbDataAccess->getMbData().isIntra() )
{
Double dCost = 0;
if( ! rcSH.getNoInterLayerPredFlag() )
{
m_pcMbEncoder->setBaseModeAllowedFlag( m_apabBaseModeFlagAllowedArrays[0][uiMbAddress] );
}
pcMbDataAccess->getMbData().setQp( iQPIntra );
RNOK( m_pcMbEncoder ->encodeIntra ( *pcMbDataAccess,
pcMbDataAccessBase,
pcFrame ->getPic( ePicType ),
pcFrame ->getPic( ePicType ),
pcResidual ->getPic( ePicType ),
pcBaseLayer ? pcBaseLayer->getPic( ePicType ) : NULL,
pcPredSignal ->getPic( ePicType ),
dLambda,
dCost ) );
RNOK( m_pcMbCoder ->encode ( *pcMbDataAccess,
pcMbDataAccessBase,
(uiMbAddress == uiLastMbAddress ),
true ) );
ruiMbCoded++;
}
else
{
pcMbDataAccess->getMbData().setQp( iQPRes );
m_pcTransform->setClipMode( false );
RNOK( m_pcMbEncoder ->encodeResidual ( *pcMbDataAccess,
pcOrgFrame->getPic( ePicType ),
pcFrame ->getPic( ePicType ),
pcResidual->getPic( ePicType ),
pcBaseSubband ? pcBaseSubband->getPic( ePicType ) : NULL,
bCoded,
dLambda,
iMaxDeltaQp ) );
if( ! pcMbDataAccess->getSH().getNoInterLayerPredFlag() && ! pcMbDataAccess->getSH().getAdaptiveBaseModeFlag() && pcMbDataAccessBase->getMbData().getInCropWindowFlag() )
{
ROF( pcMbDataAccess->getMbData().getResidualPredFlag() );
pcMbDataAccess->getMbData().setBLSkipFlag( true );
}
m_pcTransform->setClipMode( true );
RNOK( m_pcMbCoder->encode( *pcMbDataAccess, pcMbDataAccessBase, (uiMbAddress == uiLastMbAddress ), true ) );
if( bCoded )
{
ruiMbCoded++;
}
// JVT-W043 {
if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId )
{
pcGenericRC->m_iNumberofHeaderBits += pcGenericRC->m_iRCHeaderBits;
pcGenericRC->m_iNumberofBasicUnitHeaderBits += pcGenericRC->m_iRCHeaderBits;
pcGenericRC->m_iNumberofTextureBits += pcGenericRC->m_iRCTextureBits;
pcGenericRC->m_iNumberofBasicUnitTextureBits += pcGenericRC->m_iRCTextureBits;
pcGenericRC->m_pcJSVMParams->NumberofCodedMacroBlocks++;
}
// JVT-W043 }
// Update the state of the baselayer residual data -- it may be reused in subsequent layers - ASEGALL@SHARPLABS.COM
if( pcBaseSubband && ( pcMbDataAccess->getMbData().isIntra() || ! pcMbDataAccess->getMbData().getResidualPredFlag() ) )
{
YuvPicBuffer* pcBaseResidual = pcBaseSubband->getPic( ePicType )->getFullPelYuvBuffer();
pcBaseResidual->clearCurrMb();
}
RNOK( pcPredSignal->getFullPelYuvBuffer()->loadBuffer( &cZeroBuffer ) );
}
uiMbAddress = rcSH.getFMO()->getNextMBNr(uiMbAddress);
}
if( ePicType!=FRAME )
{
if( pcFrame ) RNOK( pcFrame ->removeFieldBuffer( ePicType ) );
if( pcResidual ) RNOK( pcResidual ->removeFieldBuffer( ePicType ) );
if( pcBaseSubband ) RNOK( pcBaseSubband->removeFieldBuffer( ePicType ) );
if( pcBaseLayer ) RNOK( pcBaseLayer ->removeFieldBuffer( ePicType ) );
if( pcPredSignal ) RNOK( pcPredSignal ->removeFieldBuffer( ePicType ) );
}
ruiBits += m_pcMbCoder->getBitCount() - uiBits;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -