[x265] [PATCH 2 of 3] lambda: change chroma lambda distortion weighting to resemble x264
Deepthi Nandakumar
deepthi at multicorewareinc.com
Mon Jun 16 16:12:07 CEST 2014
Agreed, thats what I thought too. But the g_chromatable is not in the HEVC
spec at all, it's just carried over from HM.
On Jun 16, 2014 5:38 PM, "Aarthi Priya Thirumalai" <
aarthi at multicorewareinc.com> wrote:
>
>
>
>
> On Mon, Jun 16, 2014 at 4:49 PM, <deepthi at multicorewareinc.com> wrote:
>>
>> # HG changeset patch
>> # User Deepthi Nandakumar <deepthi at multicorewareinc.com>
>> # Date 1402916716 -19800
>> # Mon Jun 16 16:35:16 2014 +0530
>> # Node ID 4d76a9c8b5abbf143e5869d55cf80a8816d99a68
>> # Parent ff3a85f715d43e2c21aec295426ae9dbe7c03d75
>> lambda: change chroma lambda distortion weighting to resemble x264.
>>
>> 1. x264 scales the chroma distortion by a factor derived from a lambda
offset table
>> when psyRd is enabled.
>>
>> 2. This patch also removes the separate Cb and Cr distortion weights
that were carried over from HM,
>> and replaces it with 256 when psy-rd is disabled, and the
above-mentioned lambda offset when it is enabled.
>>
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab
source/Lib/TLibEncoder/TEncSearch.cpp
>> --- a/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:12:00 2014
+0530
>> +++ b/source/Lib/TLibEncoder/TEncSearch.cpp Mon Jun 16 16:35:16 2014
+0530
>> @@ -143,16 +143,22 @@
>> return false;
>> }
>>
>> -void TEncSearch::setQP(int qp, double crWeight, double cbWeight)
>> +void TEncSearch::setQP(int qp)
>> {
>> - double lambda2 = x265_lambda2_tab[qp];
>> - double chromaLambda = lambda2 / crWeight;
>> + double lambda2 = x265_lambda2_tab[qp];
>> +
>> +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)
>
>
>> + int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] +
X265_MAX(qp - QP_MAX_SPEC, 0);
>> + double chromaLambda = x265_lambda2_tab[effective_chroma_qp];
>> + int chroma_offset_idx = X265_MIN (qp - effective_chroma_qp + 12,
MAX_CHROMA_LAMBDA_OFFSET);
>> + uint64_t chromaWeight = m_rdCost->psyRdEnabled() ?
x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256;
>> +#undef SPEC_QP
>
>
> Luma to chroma qp mapping should be done as mentioned in the HEVC
standards. the array chroma_qp_table[] is written according to H.264
spec. We cant be using that for HEVC.
> g_chromaScale[chFmt][qpc]) - gives the correct mapping of chroma qp as
per HEVC spec. chroma qp needs to be obtained from luma qp (0-69) before it
can be clipped to QP_MAX_SPEC for HEVC.
>
>
>>
>> m_me.setQP(qp);
>> m_trQuant->setLambda(lambda2, chromaLambda);
>> m_rdCost->setLambda(lambda2, x265_lambda_tab[qp]);
>> - m_rdCost->setCbDistortionWeight(cbWeight);
>> - m_rdCost->setCrDistortionWeight(crWeight);
>> + m_rdCost->setCbDistortionWeight(chromaWeight);
>> + m_rdCost->setCrDistortionWeight(chromaWeight);
>> }
>>
>> 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 ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.h
>> --- a/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:12:00 2014
+0530
>> +++ b/source/Lib/TLibEncoder/TEncSearch.h Mon Jun 16 16:35:16 2014
+0530
>> @@ -142,7 +142,7 @@
>>
>> void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) {
m_rdGoOnSbacCoder = rdGoOnSbacCoder; }
>>
>> - void setQP(int QP, double crWeight, double cbWeight);
>> + void setQP(int QP);
>>
>> TEncSearch();
>> virtual ~TEncSearch();
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/frameencoder.cpp
>> --- a/source/encoder/frameencoder.cpp Mon Jun 16 16:12:00 2014 +0530
>> +++ b/source/encoder/frameencoder.cpp Mon Jun 16 16:35:16 2014 +0530
>> @@ -363,22 +363,8 @@
>> }
>>
>> 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
>> -
>> - 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, crWeight, cbWeight);
>> +{
>> + m_rows[row].m_search.setQP(qp);
>> }
>>
>> void FrameEncoder::compressFrame()
>> @@ -387,7 +373,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;
>> @@ -515,21 +500,13 @@
>> }
>>
>> 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
>> -
>> - 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
>> -
>> +
>> double lambda = x265_lambda2_tab[qp];
>> - double chromaLambda = lambda / crWeight;
>> +
>> +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)
>> + int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] +
X265_MAX(qp - QP_MAX_SPEC, 0);
>> + double chromaLambda = x265_lambda2_tab[effective_chroma_qp];
>> +#undef SPEC_QP
>>
>> // NOTE: set SAO lambda every Frame
>> m_frameFilter.m_sao.lumaLambda = lambda;
>> @@ -539,7 +516,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, crWeight, cbWeight);
>> + m_rows[i].m_search.setQP(qp);
>> }
>>
>> // Clip qps back to 0-51 range before encoding
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/rdcost.h
>> --- a/source/encoder/rdcost.h Mon Jun 16 16:12:00 2014 +0530
>> +++ b/source/encoder/rdcost.h Mon Jun 16 16:35:16 2014 +0530
>> @@ -53,14 +53,14 @@
>> m_lambdaSAD = (uint64_t)floor(256.0 * lambda);
>> }
>>
>> - void setCbDistortionWeight(double cbDistortionWeight)
>> + void setCbDistortionWeight(uint64_t cbDistortionWeight)
>> {
>> - m_cbDistortionWeight = (uint64_t)floor(256.0 *
cbDistortionWeight);
>> + m_cbDistortionWeight = cbDistortionWeight;
>> }
>>
>> - void setCrDistortionWeight(double crDistortionWeight)
>> + void setCrDistortionWeight(uint64_t crDistortionWeight)
>> {
>> - m_crDistortionWeight = (uint64_t)floor(256.0 *
crDistortionWeight);
>> + m_crDistortionWeight = crDistortionWeight;
>> }
>>
>> void setPsyRdScale(double scale)
>> _______________________________________________
>> x265-devel mailing list
>> x265-devel at videolan.org
>> https://mailman.videolan.org/listinfo/x265-devel
>
>
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140616/7f3b9069/attachment.html>
More information about the x265-devel
mailing list