...
 
Commits (8)
......@@ -1640,10 +1640,16 @@ Specifies a file containing a list of QP deltas. The $n$-th line
value delta for the picture with POC value $n$.
\\
\Option{PerceptQPA (-qpa)} &
%\ShortOption{-qpa} &
\Default{false} &
Enables or disables the perceptually optimized QP adaptation (QPA) method described in JVET-H0047, JVET-K0206, and JVET-M0091. Use this together with 'SliceChromaQPOffsetPeriodicity=1' for best subjective quality. Cannot be used together with 'SelectiveRDOQ' (see above) or 'AdaptiveQp' (see below).
\\
\Option{AdaptiveQp (-aq)} &
%\ShortOption{-aq} &
\Default{false} &
Enable or disable QP adaptation based upon a psycho-visual model.
Enables or disables the legacy QP adaptation method based upon a psycho-visual model.
\\
\Option{MaxQPAdaptationRange (-aqr)} &
......@@ -2305,7 +2311,7 @@ Enables or disables the use of intra block differential pulse code modulation mo
\begin{tabular}{cp{0.45\textwidth}}
0 & Disable BDPCM for luma and chroma.\\
1 & Enable BDPCM for luma.\\
2 & Enable BDPCM for luma and chroma. BDPCM for chroma is avaialble for 444. \\
2 & Enable BDPCM for luma and chroma. BDPCM for chroma is available for 444.\\
\end{tabular}
\\
......
......@@ -2395,7 +2395,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
#endif
#if ENABLE_QPA
if (m_bUsePerceptQPA && !m_bUseAdaptiveQP && m_dualTree && (m_cbQpOffsetDualTree != 0 || m_crQpOffsetDualTree != 0))
if (m_bUsePerceptQPA && !m_bUseAdaptiveQP && m_dualTree && (m_cbQpOffsetDualTree != 0 || m_crQpOffsetDualTree != 0 || m_cbCrQpOffsetDualTree != 0))
{
msg( WARNING, "*************************************************************************\n" );
msg( WARNING, "* WARNING: chroma QPA on, ignoring nonzero dual-tree chroma QP offsets! *\n" );
......
......@@ -152,6 +152,9 @@ public:
double getLambda() { return m_dLambda; }
#endif
double getChromaWeight() { return ((m_distortionWeight[COMPONENT_Cb] + m_distortionWeight[COMPONENT_Cr]) / 2.0); }
#if RDOQ_CHROMA_LAMBDA
double getDistortionWeight ( const ComponentID compID ) const { return m_distortionWeight[compID % MAX_NUM_COMPONENT]; }
#endif
void setCostMode(CostMode m) { m_costMode = m; }
......
......@@ -1119,8 +1119,9 @@ void EncCu::updateLambda (Slice* slice, const int dQP,
#endif
const double newLambda = oldLambda * pow (2.0, ((double)dQP - oldQP) / 3.0);
#if RDOQ_CHROMA_LAMBDA
const double chromaLambda = newLambda / m_pcRdCost->getChromaWeight();
const double lambdaArray[MAX_NUM_COMPONENT] = {newLambda, chromaLambda, chromaLambda};
const double lambdaArray[MAX_NUM_COMPONENT] = {newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Y),
newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cb),
newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cr)};
m_pcTrQuant->setLambdas (lambdaArray);
#else
m_pcTrQuant->setLambda (newLambda);
......
......@@ -533,6 +533,7 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
const bool bUseIntraOrPeriodicOffset = (rpcSlice->isIntra() && !rpcSlice->getSPS()->getIBCFlag()) || (m_pcCfg->getSliceChromaOffsetQpPeriodicity() > 0 && (rpcSlice->getPOC() % m_pcCfg->getSliceChromaOffsetQpPeriodicity()) == 0);
int cbQP = bUseIntraOrPeriodicOffset ? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(false) : m_pcCfg->getGOPEntry(iGOPid).m_CbQPoffset;
int crQP = bUseIntraOrPeriodicOffset ? m_pcCfg->getSliceChromaOffsetQpIntraOrPeriodic(true) : m_pcCfg->getGOPEntry(iGOPid).m_CrQPoffset;
int cbCrQP = (cbQP + crQP) >> 1; // use floor of average chroma QP offset for joint-Cb/Cr coding
cbQP = Clip3( -12, 12, cbQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb);
crQP = Clip3( -12, 12, crQP + rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr) ) - rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr);
......@@ -540,6 +541,11 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
CHECK(!(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cb)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cb)>=-12), "Unspecified error");
rpcSlice->setSliceChromaQpDelta(COMPONENT_Cr, Clip3( -12, 12, crQP));
CHECK(!(rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)<=12 && rpcSlice->getSliceChromaQpDelta(COMPONENT_Cr)+rpcSlice->getPPS()->getQpOffset(COMPONENT_Cr)>=-12), "Unspecified error");
if (rpcSlice->getSPS()->getJointCbCrEnabledFlag())
{
cbCrQP = Clip3(-12, 12, cbCrQP + rpcSlice->getPPS()->getQpOffset(JOINT_CbCr)) - rpcSlice->getPPS()->getQpOffset(JOINT_CbCr);
rpcSlice->setSliceChromaQpDelta(JOINT_CbCr, Clip3( -12, 12, cbCrQP ));
}
}
else
{
......@@ -563,6 +569,9 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr
dLambda *= lambdaModifier;
#endif
#if RDOQ_CHROMA_LAMBDA
m_pcRdCost->setDistortionWeight (COMPONENT_Y, 1.0); // no chroma weighting for luma
#endif
setUpLambda(rpcSlice, dLambda, iQP);
#if WCG_EXT
......@@ -776,6 +785,9 @@ void EncSlice::resetQP( Picture* pic, int sliceQP, double lambda )
// store lambda
slice->setSliceQp( sliceQP );
#if RDOQ_CHROMA_LAMBDA
m_pcRdCost->setDistortionWeight (COMPONENT_Y, 1.0); // no chroma weighting for luma
#endif
setUpLambda(slice, lambda, sliceQP);
#if WCG_EXT
m_pcRdCost->saveUnadjustedLambda();
......@@ -1635,9 +1647,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
#endif
#if RDOQ_CHROMA_LAMBDA
// set lambda for RDOQ
const double chromaLambda = estLambda / pRdCost->getChromaWeight();
const double lambdaArray[MAX_NUM_COMPONENT] = { estLambda, chromaLambda, chromaLambda };
const double lambdaArray[MAX_NUM_COMPONENT] = {estLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Y),
estLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cb),
estLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cr)};
pTrQuant->setLambdas( lambdaArray );
#else
pTrQuant->setLambda( estLambda );
......@@ -1659,8 +1671,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
#if !ENABLE_QPA_SUB_CTU
#if RDOQ_CHROMA_LAMBDA
pTrQuant->getLambdas (oldLambdaArray); // save the old lambdas
const double chromaLambda = newLambda / pRdCost->getChromaWeight();
const double lambdaArray[MAX_NUM_COMPONENT] = {newLambda, chromaLambda, chromaLambda};
const double lambdaArray[MAX_NUM_COMPONENT] = {newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Y),
newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cb),
newLambda / m_pcRdCost->getDistortionWeight (COMPONENT_Cr)};
pTrQuant->setLambdas (lambdaArray);
#else
pTrQuant->setLambda (newLambda);
......