📄 sliceencoder.cpp
字号:
ErrVal
SliceEncoder::encodeInterPicturePMbAff( UInt& ruiBits,
IntFrame* pcOrgFrame,
IntFrame* pcFrame,
IntFrame* pcRecSubband,
IntFrame* pcPredSignal,
ControlData& rcControlData,
UInt uiMbInRow,
RefFrameList& rcRefFrameList,
RefFrameList& rcRefFrameListBase )
{
ROF( m_bInitDone );
SliceHeader& rcSliceHeader = *rcControlData.getSliceHeader ( FRAME );
MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl ();
IntFrame* pcBaseLayerFrame = rcControlData.getBaseLayerRec ();
IntFrame* pcBaseLayerResidual = rcControlData.getBaseLayerSbb ();
MbDataCtrl* pcBaseLayerCtrl = rcControlData.getBaseLayerCtrl ();
MbDataCtrl* pcBaseLayerCtrlField = rcControlData.getBaseLayerCtrlField ();
Double dLambda = rcControlData.getLambda ();
Int iSpatialScalabilityType = rcControlData.getSpatialScalabilityType(); // TMM_ESS
UInt uiBits = m_pcMbCoder ->getBitCount ();
//====== initialization ======
RNOK( pcMbDataCtrl ->initSlice ( rcSliceHeader, ENCODE_PROCESS, false, NULL ) );
if( pcBaseLayerCtrl )
{
RNOK( pcBaseLayerCtrl ->initSlice ( rcSliceHeader, PRE_PROCESS, false, NULL ) );
}
if( pcBaseLayerCtrlField )
{
RNOK( pcBaseLayerCtrlField ->initSlice ( rcSliceHeader, PRE_PROCESS, false, NULL ) );
}
RNOK( m_pcControlMng ->initSliceForCoding( rcSliceHeader ) );
RefFrameList acRefFrameList [2];
RefFrameList acRefFrameListBase[2];
IntYuvMbBuffer acIntYuvMbBufferPredSignal[2];
IntYuvMbBuffer acIntYuvMbBufferRecSubBand[2];
IntYuvMbBuffer acIntYuvMbBufferFrame [2];
RNOK( gSetFrameFieldLists( acRefFrameList [0], acRefFrameList [1], rcRefFrameList ) );
RNOK( gSetFrameFieldLists( acRefFrameListBase[0], acRefFrameListBase[1], rcRefFrameListBase ) );
IntFrame* apcOrgFrame [4] = { NULL, NULL, NULL, NULL };
IntFrame* apcFrame [4] = { NULL, NULL, NULL, NULL };
IntFrame* apcRecSubband[4] = { NULL, NULL, NULL, NULL };
IntFrame* apcPredSignal[4] = { NULL, NULL, NULL, NULL };
IntFrame* apcBaseLayerF[4] = { NULL, NULL, NULL, NULL };
IntFrame* apcBaseLayerR[4] = { NULL, NULL, NULL, NULL };
RNOK( gSetFrameFieldArrays( apcFrame, pcFrame ) );
RNOK( gSetFrameFieldArrays( apcOrgFrame, pcOrgFrame ) );
RNOK( gSetFrameFieldArrays( apcRecSubband, pcRecSubband ) );
RNOK( gSetFrameFieldArrays( apcPredSignal, pcPredSignal ) );
RNOK( gSetFrameFieldArrays( apcBaseLayerF, pcBaseLayerFrame ) );
RNOK( gSetFrameFieldArrays( apcBaseLayerR, pcBaseLayerResidual ) );
// const Bool bInheritFieldMode = ! rcSliceHeader.getSPS().getFieldFlagCoded() && (SCALABLE_PROFILE == rcSliceHeader.getSPS().getProfileIdc());
MbDataBuffer acMbData[2];
Bool abSkipModeAllowed[4] = {true,true,true,true};
UInt uiLastQp = rcSliceHeader.getPicQp();
//===== loop over macroblocks =====
UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice();
const UInt uiLastMbAddress = rcSliceHeader.getLastMbInSlice ();
for( ; uiMbAddress <= uiLastMbAddress; uiMbAddress+=2 )
{
UInt auiLastQpTest[2] = {uiLastQp, uiLastQp};
Double adCost[2] = {0,0};
Int eP;
for( eP = 0; eP < 4; eP++ )
{
RefFrameList* pcRefFrameList;
RefFrameList* pcRefFrameListBase;
MbDataAccess* pcMbDataAccess = NULL;
MbDataAccess* pcMbDataAccessBase = NULL;
Double dCost = 0;
UInt uiMbY, uiMbX;
const Bool bField = (eP < 2);
const UInt uiMbAddressMbAff = uiMbAddress+(eP%2);
if( bField )
{
pcRefFrameList = acRefFrameList + eP;
pcRefFrameListBase = acRefFrameListBase + eP;
}
else
{
pcRefFrameList = &rcRefFrameList;
pcRefFrameListBase = &rcRefFrameListBase;
}
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->getMbData().deactivateMotionRefinement();
pcMbDataAccess->setLastQp( auiLastQpTest[bField] );
if( 0 == eP )
{
abSkipModeAllowed[1] = pcMbDataAccess->getDefaultFieldFlag(); // do not move
abSkipModeAllowed[3] = ! abSkipModeAllowed[1];
}
pcRefFrameListBase = pcRefFrameListBase->getSize()? pcRefFrameListBase : NULL;
RNOK( m_pcMbEncoder ->encodeInterP ( *pcMbDataAccess,
pcMbDataAccessBase,
iSpatialScalabilityType,
apcOrgFrame [eP],
apcFrame [eP],
apcRecSubband[eP],
apcPredSignal[eP],
apcBaseLayerF[eP],
apcBaseLayerR[eP],
*pcRefFrameList,
pcRefFrameListBase,
dLambda,
dCost,
abSkipModeAllowed[eP] ) );
if( ! pcMbDataAccess->getMbData().isIntra() && pcMbDataAccess->getMbData().getResidualPredFlag( PART_16x16 ) )
{
pcMbDataAccess->getMbData().setMbExtCbp( pcMbDataAccess->getMbData().getMbExtCbp() | pcMbDataAccessBase->getMbData().getMbExtCbp() );
}
auiLastQpTest[bField] = pcMbDataAccess->getMbData().getQp();
adCost [eP>>1] += dCost;
if( bField )
{
acMbData[eP].copy( pcMbDataAccess->getMbData() );
if( apcPredSignal [eP] ) acIntYuvMbBufferPredSignal[eP].loadBuffer( apcPredSignal [eP]->getFullPelYuvBuffer() );
if( apcRecSubband [eP] ) acIntYuvMbBufferRecSubBand[eP].loadBuffer( apcRecSubband [eP]->getFullPelYuvBuffer() );
if( apcFrame [eP] ) acIntYuvMbBufferFrame [eP].loadBuffer( apcFrame [eP]->getFullPelYuvBuffer() );
}
}
const Bool bFieldMode = ( adCost[0] < adCost[1] );
#ifdef RANDOM_MBAFF
bFieldMode = gBoolRandom();
#endif
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 ) );
pcMbDataAccess->getMbData().deactivateMotionRefinement();
if( bFieldMode )
{
pcMbDataAccess->getMbData().copy( acMbData[eP] );
if( apcRecSubband [eP] ) apcRecSubband [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferRecSubBand[eP] );
if( apcPredSignal [eP] ) apcPredSignal [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferPredSignal[eP] );
if( apcFrame [eP] ) apcFrame [eP]->getFullPelYuvBuffer()->loadBuffer( &acIntYuvMbBufferFrame [eP] );
}
pcMbDataAccess->setLastQp( uiLastQp );
uiLastQp = pcMbDataAccess->getMbData().getQp();
pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
RNOK( m_pcMbCoder ->encode ( *pcMbDataAccess,
pcMbDataAccessBase,
iSpatialScalabilityType,
(uiMbAddressMbAff == uiLastMbAddress), (eP == 1) ) );
}
}
ruiBits += m_pcMbCoder ->getBitCount() - uiBits;
return Err::m_nOK;
}
// TMM_INTERLACE}
ErrVal
SliceEncoder::encodeSlice( SliceHeader& rcSliceHeader,
IntFrame* pcFrame,
MbDataCtrl* pcMbDataCtrl,
RefFrameList& rcList0,
RefFrameList& rcList1,
UInt uiMbInRow,
Double dlambda )
{
ROF( pcFrame );
ROF( pcMbDataCtrl );
//===== get co-located picture =====
MbDataCtrl* pcMbDataCtrlL1 = NULL;
if( rcList1.getActive() && rcList1.getEntry( 0 )->getRecPicBufUnit() )
{
pcMbDataCtrlL1 = rcList1.getEntry( 0 )->getRecPicBufUnit()->getMbDataCtrl();
}
ROT( rcSliceHeader.isInterB() && ! pcMbDataCtrlL1 );
//===== initialization =====
RNOK( pcMbDataCtrl ->initSlice ( rcSliceHeader, ENCODE_PROCESS, false, pcMbDataCtrlL1 ) );
RNOK( m_pcControlMng->initSliceForCoding( rcSliceHeader ) );
//===== loop over macroblocks =====
for( UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice(); uiMbAddress <= rcSliceHeader.getLastMbInSlice(); uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr( uiMbAddress ) )
{
ETRACE_NEWMB( uiMbAddress );
UInt uiMbY = uiMbAddress / uiMbInRow;
UInt uiMbX = uiMbAddress % uiMbInRow;
MbDataAccess* pcMbDataAccess = 0;
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
RNOK( m_pcControlMng->initMbForCoding ( *pcMbDataAccess, uiMbY, uiMbX, false, false ) );
pcMbDataAccess->setMbDataAccessBase ( NULL );
RNOK( m_pcMbEncoder ->encodeMacroblock( *pcMbDataAccess,
pcFrame,
rcList0,
rcList1,
m_pcCodingParameter->getMotionVectorSearchParams().getNumMaxIter(),
m_pcCodingParameter->getMotionVectorSearchParams().getIterSearchRange(),
dlambda ) );
RNOK( m_pcMbCoder ->encode ( *pcMbDataAccess,
NULL,
SST_RATIO_1,
( uiMbAddress == rcSliceHeader.getLastMbInSlice() )
,true ) );
}
return Err::m_nOK;
}
//TMM_WP
ErrVal SliceEncoder::xInitDefaultWeights(Double *pdWeights, UInt uiLumaWeightDenom,
UInt uiChromaWeightDenom)
{
const Int iLumaWeight = 1 << uiLumaWeightDenom;
const Int iChromaWeight = 1 << uiChromaWeightDenom;
pdWeights[0] = iLumaWeight;
pdWeights[1] = pdWeights[2] = iChromaWeight;
return Err::m_nOK;
}
ErrVal SliceEncoder::xSetPredWeights( SliceHeader& rcSH,
IntFrame* pOrgFrame,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1)
{
RNOK( rcSH.getPredWeightTable(LIST_0).uninit() );
RNOK( rcSH.getPredWeightTable(LIST_1).uninit() );
RNOK( rcSH.getPredWeightTable(LIST_0).init( rcSH.getNumRefIdxActive( LIST_0) ) );
RNOK( rcSH.getPredWeightTable(LIST_1).init( rcSH.getNumRefIdxActive( LIST_1) ) );
ROTRS( rcSH.isIntra(), Err::m_nOK );
const SampleWeightingParams& rcSWP = m_pcCodingParameter->getSampleWeightingParams(rcSH.getLayerId());
{ // determine denoms
const UInt uiLumaDenom = rcSWP.getLumaDenom();
rcSH.setLumaLog2WeightDenom ( ( uiLumaDenom == MSYS_UINT_MAX ) ? gIntRandom(0,7) : uiLumaDenom );
const UInt uiChromaDenom = rcSWP.getChromaDenom();
rcSH.setChromaLog2WeightDenom( ( uiChromaDenom == MSYS_UINT_MAX ) ? gIntRandom(0,7) : uiChromaDenom );
}
const Int iChromaScale = 1<<rcSH.getChromaLog2WeightDenom();
const Int iLumaScale = 1<<rcSH.getLumaLog2WeightDenom();
m_pcControlMng->initSliceForWeighting(rcSH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -