[x265] [PATCH] lambda: [CHANGES OUTPUT] Change the distortion weights applied to chroma
deepthi at multicorewareinc.com
deepthi at multicorewareinc.com
Wed Jun 18 11:29:33 CEST 2014
# HG changeset patch
# User Deepthi Nandakumar <deepthi at multicorewareinc.com>
# Date 1403083757 -19800
# Wed Jun 18 14:59:17 2014 +0530
# Node ID da3d728616c0f5eb5caf41062ab4f9a05ddd078f
# Parent a43a223a12944ef4e3d83318d51ce8bbcbb855d4
lambda: [CHANGES OUTPUT] Change the distortion weights applied to chroma.
Inside R-D, a single lambda is applied for both luma and chroma. To account for the different QPs,
(as defined by the standard) the chroma distortion was weighted by a factor proportional to the
difference in QPs. This patch eliminates the extra weighting given to the chroma distortion
(since it is visually less perceptible).
diff -r a43a223a1294 -r da3d728616c0 source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp Wed Jun 18 00:04:09 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp Wed Jun 18 14:59:17 2014 +0530
@@ -143,15 +143,17 @@
return false;
}
-void TEncSearch::setQP(int qp, double cbWeight, double crWeight)
+void TEncSearch::setQP(int qp, int qpCb, int qpCr)
{
double lambda2 = x265_lambda2_tab[qp];
+ double lambdaCb = x265_lambda2_tab[qpCb];
+ double lambdaCr = x265_lambda2_tab[qpCr];
m_me.setQP(qp);
- m_trQuant->setLambdas(lambda2, lambda2 / cbWeight, lambda2 / crWeight);
+ m_trQuant->setLambdas(lambda2, lambdaCb, lambdaCr);
m_rdCost->setLambda(lambda2, x265_lambda_tab[qp]);
- m_rdCost->setCbDistortionWeight(cbWeight);
- m_rdCost->setCrDistortionWeight(crWeight);
+ m_rdCost->setCbDistortionWeight(1.0);
+ m_rdCost->setCrDistortionWeight(1.0);
}
void TEncSearch::xEncSubdivCbfQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height, bool bLuma, bool bChroma)
diff -r a43a223a1294 -r da3d728616c0 source/Lib/TLibEncoder/TEncSearch.h
--- a/source/Lib/TLibEncoder/TEncSearch.h Wed Jun 18 00:04:09 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.h Wed Jun 18 14:59:17 2014 +0530
@@ -140,7 +140,7 @@
void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; }
- void setQP(int QP, double cbWeight, double crWeight);
+ void setQP(int qp, int qpCb, int qpCr);
TEncSearch();
virtual ~TEncSearch();
diff -r a43a223a1294 -r da3d728616c0 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Wed Jun 18 00:04:09 2014 -0500
+++ b/source/encoder/frameencoder.cpp Wed Jun 18 14:59:17 2014 +0530
@@ -364,20 +364,14 @@
void FrameEncoder::setLambda(int qp, int row)
{
TComSlice* slice = m_pic->getSlice();
- int chFmt = slice->getSPS()->getChromaFormatIdc();
-
- // for RDO
- // in RdCost there is only one lambda because the luma and chroma bits are not separated,
- // instead we weight the distortion of chroma.
+
int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
- int qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
- double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+ int qpCb = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+
chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
- qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
- double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
- m_rows[row].m_search.setQP(qp, cbWeight, crWeight);
+ int qpCr = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+
+ m_rows[row].m_search.setQP(qp, qpCb, qpCr);
}
void FrameEncoder::compressFrame()
@@ -386,7 +380,6 @@
int64_t startCompressTime = x265_mdate();
TEncEntropy* entropyCoder = getEntropyCoder(0);
TComSlice* slice = m_pic->getSlice();
- int chFmt = slice->getSPS()->getChromaFormatIdc();
int totalCoded = (int)m_top->m_encodedFrameNum - 1;
m_nalCount = 0;
@@ -512,20 +505,15 @@
int qp = slice->getSliceQp();
- // for RDO
- // in RdCost there is only one lambda because the luma and chroma bits are not separated,
- // instead we weight the distortion of chroma.
- int qpc;
int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();
- qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
- double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+ int qpCb = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+
chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();
- qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
- double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset
-
+ int qpCr = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);
+
double lambda = x265_lambda2_tab[qp];
- double chromaLambda = lambda / crWeight;
+ /* Assuming qpCb and qpCr are the same, since SAO takes only a single chroma lambda. TODO: Check why */
+ double chromaLambda = x265_lambda2_tab[qpCb];
// NOTE: set SAO lambda every Frame
m_frameFilter.m_sao.lumaLambda = lambda;
@@ -535,7 +523,7 @@
for (int i = 0; i < m_numRows; i++)
{
m_rows[i].m_search.m_me.setSourcePlane(fenc->getLumaAddr(), fenc->getStride());
- m_rows[i].m_search.setQP(qp, cbWeight, crWeight);
+ m_rows[i].m_search.setQP(qp, qpCb, qpCr);
}
// Clip qps back to 0-51 range before encoding
More information about the x265-devel
mailing list