📄 sliceencoder.cpp
字号:
if( rcSH.isInterB() )
{
ROTRS( 1 != rcSH.getPPS().getWeightedBiPredIdc(), Err::m_nOK );
}
else
{
ROTRS( ! rcSH.getPPS().getWeightedPredFlag(), Err::m_nOK );
}
if( rcSH.isInterB() )
{
RNOK( rcSH.getPredWeightTable(LIST_1).initDefaults( rcSH.getLumaLog2WeightDenom(), rcSH.getChromaLog2WeightDenom() ) );
}
RNOK( rcSH.getPredWeightTable(LIST_0).initDefaults( rcSH.getLumaLog2WeightDenom(), rcSH.getChromaLog2WeightDenom() ) );
Double afFwWeight[MAX_REF_FRAMES][3];
Double afBwWeight[MAX_REF_FRAMES][3];
Double afFwOffsets[MAX_REF_FRAMES][3];
Double afBwOffsets[MAX_REF_FRAMES][3];
Double fDiscardThr = m_pcCodingParameter->getSampleWeightingParams(rcSH.getLayerId()).getDiscardThr();
/* init arrays with default weights */
for (UInt x = 0; x < MAX_REF_FRAMES; x++)
{
xInitDefaultWeights(afFwWeight[x], rcSH.getLumaLog2WeightDenom(), rcSH.getChromaLog2WeightDenom());
xInitDefaultWeights(afBwWeight[x], rcSH.getLumaLog2WeightDenom(), rcSH.getChromaLog2WeightDenom());
afFwOffsets[x][0] = afFwOffsets[x][1] = afFwOffsets[x][2] = 0;
afBwOffsets[x][0] = afBwOffsets[x][1] = afBwOffsets[x][2] = 0;
}
if( rcSH.isInterB() )
{
RNOK( m_pcMbEncoder->getPredWeights( rcSH, LIST_1, afBwWeight,
pOrgFrame, rcRefFrameList1 ) );
RNOK( rcSH.getPredWeightTable( LIST_1).setPredWeightsAndFlags( iLumaScale, iChromaScale,
afBwWeight, fDiscardThr ) );
}
RNOK( m_pcMbEncoder->getPredWeights( rcSH, LIST_0, afFwWeight, pOrgFrame, rcRefFrameList0 ) );
RNOK( rcSH.getPredWeightTable( LIST_0).setPredWeightsAndFlags( iLumaScale, iChromaScale,
afFwWeight, fDiscardThr ) );
return Err::m_nOK;
}
//TMM_WP
// JVT-V035
ErrVal
SliceEncoder::updatePictureAVCRewrite( ControlData& rcControlData,
UInt uiMbInRow )
{
ROF( m_bInitDone );
SliceHeader& rcSliceHeader = *rcControlData.getSliceHeader ();
MbDataCtrl* pcMbDataCtrl = rcControlData.getMbDataCtrl ();
MbDataCtrl* pcBaseLayerCtrl = rcControlData.getBaseLayerCtrl ();
UInt uiMbAddress = rcSliceHeader.getFirstMbInSlice ();
UInt uiLastMbAddress = rcSliceHeader.getLastMbInSlice ();
//====== initialization ======
RNOK( pcMbDataCtrl ->initSlice ( rcSliceHeader, ENCODE_PROCESS, false, NULL ) );
if( rcSliceHeader.getAVCRewriteFlag() == true )
{
// Update the macroblock state
// Must be done after the bit-stream has been constructed
uiMbAddress = rcSliceHeader.getFirstMbInSlice ();
for( ; uiMbAddress <= uiLastMbAddress; )
{
UInt uiMbY = uiMbAddress / uiMbInRow;
UInt uiMbX = uiMbAddress % uiMbInRow;
MbDataAccess* pcMbDataAccess = 0;
MbDataAccess* pcMbDataAccessBase = 0;
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
if( pcBaseLayerCtrl )
{
RNOK( pcBaseLayerCtrl ->initMb ( pcMbDataAccessBase, uiMbY, uiMbX ) );
pcMbDataAccess->setMbDataAccessBase( pcMbDataAccessBase );
}
if( ( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL || pcMbDataAccess->getMbData().getResidualPredFlag( PART_16x16) )
&& pcMbDataAccess->getSH().getAVCRewriteFlag() )
{
if( pcMbDataAccess->getMbData().getMbMode() == INTRA_BL )
{
// We're going to use the BL skip flag to correctly decode the intra prediction mode
AOT( pcMbDataAccess->getMbData().getBLSkipFlag() == false );
// Inherit the mode of the base block
pcMbDataAccess->getMbData().setMbMode( pcMbDataAccessBase->getMbData().getMbMode() );
// Inherit intra prediction modes
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
pcMbDataAccess->getMbData().intraPredMode(cIdx) = pcMbDataAccessBase->getMbData().intraPredMode(cIdx);
pcMbDataAccess->getMbData().setChromaPredMode( pcMbDataAccessBase->getMbData().getChromaPredMode() );
}
if( pcMbDataAccess->getMbData().getResidualPredFlag( PART_16x16 ) ||
( pcMbDataAccess->getMbData().isIntra() && pcMbDataAccess->getMbData().getBLSkipFlag() ) )
{
// The 8x8 transform flag is present in the bit-stream unless transform coefficients
// are not transmitted at the enhancement layer. In this case, inherit the base layer
// transform type. This makes intra predition work correctly, etc.
if( !( pcMbDataAccess->getMbData().getMbCbp() & 0x0F ) )
pcMbDataAccess->getMbData().setTransformSize8x8( pcMbDataAccessBase->getMbData().isTransformSize8x8() );
}
if( pcMbDataAccess->getMbData().getResidualPredFlag( PART_16x16 )
|| ( pcMbDataAccess->getMbData().isIntra() && pcMbDataAccess->getMbData().getBLSkipFlag() ) )
{
xAddTCoeffs2( *pcMbDataAccess, *pcMbDataAccessBase );
}
}
// overwrite the QP so that rewriter can get correct QP
if (pcMbDataAccess->getSH().getAVCRewriteFlag() && (pcMbDataAccess->getSH().getBaseLayerId() != MSYS_UINT_MAX)
&& (pcMbDataAccess->getSH().getLayerId() != pcMbDataAccess->getSH().getBaseLayerId())) {
if(( pcMbDataAccess->getMbData().getMbExtCbp() == 0 ) && (!pcMbDataAccess->getMbData().isIntra16x16()))
pcMbDataAccess->getMbData().setQp( pcMbDataAccess->getLastQp()); // JANE'S BIG FIX
}
uiMbAddress = rcSliceHeader.getFMO()->getNextMBNr(uiMbAddress );
}
}
return Err::m_nOK;
}
ErrVal
SliceEncoder::xAddTCoeffs2( MbDataAccess& rcMbDataAccess, MbDataAccess& rcMbDataAccessBase )
{
UInt uiBCBP = 0;
UInt uiCoded = 0;
Bool bCoded = false;
Bool bChromaAC = false;
Bool bChromaDC = false;
// Add the luma coefficients and track the new BCBP
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
bCoded = false;
m_pcTransform->addPrediction8x8Blk( rcMbDataAccess.getMbTCoeffs().get8x8( c8x8Idx ),
rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx ),
rcMbDataAccess.getMbData().getQp(),
rcMbDataAccessBase.getMbData().getQp(), bCoded );
if( rcMbDataAccess.getMbData().isIntra16x16() )
AOT(1);
if( bCoded )
uiBCBP |= (0x33 << c8x8Idx.b4x4());
}
}
else
{
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
uiCoded = 0;
m_pcTransform->addPrediction4x4Blk( rcMbDataAccess.getMbTCoeffs().get( cIdx ),
rcMbDataAccessBase.getMbTCoeffs().get( cIdx ),
rcMbDataAccess.getMbData().getQp(),
rcMbDataAccessBase.getMbData().getQp(), uiCoded );
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
if( *(rcMbDataAccess.getMbTCoeffs().get( cIdx )) )
uiCoded--;
}
if( uiCoded )
uiBCBP |= 1<<cIdx;
}
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
uiBCBP = uiBCBP?((1<<16)-1):0;
}
}
// Add the chroma coefficients and update the BCBP
m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(0) ),
rcMbDataAccessBase.getMbTCoeffs().get( CIdx(0) ),
rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQp() ),
rcMbDataAccessBase.getSH().getChromaQp( rcMbDataAccessBase.getMbData().getQp() ),
bChromaDC, bChromaAC );
m_pcTransform->addPredictionChromaBlocks( rcMbDataAccess.getMbTCoeffs().get( CIdx(4) ),
rcMbDataAccessBase.getMbTCoeffs().get( CIdx(4) ),
rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQp() ),
rcMbDataAccessBase.getSH().getChromaQp( rcMbDataAccessBase.getMbData().getQp() ),
bChromaDC, bChromaAC );
uiBCBP |= (bChromaAC?2:(bChromaDC?1:0))<<16;
// Update the CBP
rcMbDataAccess.getMbData().setAndConvertMbExtCbp( uiBCBP );
// Update the Intra16x16 mode
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
UInt uiMbType = INTRA_4X4 + 1;
UInt uiPredMode = rcMbDataAccess.getMbData().intraPredMode();
UInt uiChromaCbp = uiBCBP>>16;
Bool bACcoded = (uiBCBP && ((1<<16)-1));
uiMbType += uiPredMode;
uiMbType += ( bACcoded ) ? 12 : 0;
uiMbType += uiChromaCbp << 2;
rcMbDataAccess.getMbData().setMbMode( MbMode(uiMbType) );
// Sanity checks
if( rcMbDataAccess.getMbData().intraPredMode() != uiPredMode )
AOT(1);
if( rcMbDataAccess.getMbData().getCbpChroma16x16() != uiChromaCbp )
AOT(1);
if( rcMbDataAccess.getMbData().isAcCoded() != bACcoded )
AOT(1);
}
return Err::m_nOK;
UInt uiScaleFactor[6] = {8, 9, 10, 11, 13, 14};
Quantizer cSrcQuantizer, cDstQuantizer;
cSrcQuantizer.setQp( rcMbDataAccessBase, false );
cDstQuantizer.setQp( rcMbDataAccess, false );
// Process luma blocks
const QpParameter& cSrcLQp = cSrcQuantizer.getLumaQp ();
const QpParameter& cDstLQp = cDstQuantizer.getLumaQp ();
QpParameter cScaleQp;
cScaleQp.setQp( (cSrcLQp.per()-cDstLQp.per())*6+(cSrcLQp.rem()-cDstLQp.rem()), true );
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
TCoeff *pcDst = rcMbDataAccess.getMbData().getMbTCoeffs().get( cIdx );
TCoeff *pcSrc = rcMbDataAccessBase.getMbData().getMbTCoeffs().get( cIdx );
for( UInt n=0; n<16; n++ )
{
TCoeff cCoeff;
cCoeff = pcSrc[n]<<cScaleQp.per();
cCoeff *= uiScaleFactor[cScaleQp.rem()];
cCoeff += ( cCoeff>0 ) ? 4 : -4;
cCoeff /= 8;
pcDst[n] += cCoeff;
}
}
// Process chroma blocks
const QpParameter& cSrcCQp = cSrcQuantizer.getChromaQp();
const QpParameter& cDstCQp = cDstQuantizer.getChromaQp();
// Set scale factor
cScaleQp.setQp( (cSrcCQp.per()*6+cSrcCQp.rem()) - (cDstCQp.per()*6+cDstCQp.rem()), true );
for( CIdx cIdxi; cIdxi.isLegal(); cIdxi++ )
{
TCoeff *pcDst = rcMbDataAccess.getMbData().getMbTCoeffs().get( cIdxi );
TCoeff *pcSrc = rcMbDataAccessBase.getMbData().getMbTCoeffs().get( cIdxi );
for( UInt n=0; n<16; n++ )
{
TCoeff cCoeff;
cCoeff = pcSrc[n]<<cScaleQp.per();
cCoeff *= uiScaleFactor[cScaleQp.rem()];
cCoeff += ( cCoeff>0 ) ? 4 : -4;
cCoeff /= 8;
pcDst[n] += cCoeff;
}
}
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -