<div dir="ltr"><div>pg 155 of HEVC standard:</div><div>Table 8-9 – Specification of QpC as a function of qPi</div><div>qPi < 30 30 31 32 33 34 35 36 37 38 39 40 41 42 43 > 43</div><div>QpC = qPi 29 30 31 32 33 33 34 34 35 35 36 36 37 37 = qPi − 6</div>
<div><br></div><div>AFAIK, values in g_chromaScale[CHROMA_420] follows the spec exactly. not sure how the values for other chroma formats were derived.</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Mon, Jun 16, 2014 at 7:42 PM, Deepthi Nandakumar <span dir="ltr"><<a href="mailto:deepthi@multicorewareinc.com" target="_blank">deepthi@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<p>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.</p><div class="HOEnZb"><div class="h5">
<p>On Jun 16, 2014 5:38 PM, "Aarthi Priya Thirumalai" <<a href="mailto:aarthi@multicorewareinc.com" target="_blank">aarthi@multicorewareinc.com</a>> wrote:<br>
><br>
><br>
><br>
><br>
> On Mon, Jun 16, 2014 at 4:49 PM, <<a href="mailto:deepthi@multicorewareinc.com" target="_blank">deepthi@multicorewareinc.com</a>> wrote:<br>
>><br>
>> # HG changeset patch<br>
>> # User Deepthi Nandakumar <<a href="mailto:deepthi@multicorewareinc.com" target="_blank">deepthi@multicorewareinc.com</a>><br>
>> # Date 1402916716 -19800<br>
>> #      Mon Jun 16 16:35:16 2014 +0530<br>
>> # Node ID 4d76a9c8b5abbf143e5869d55cf80a8816d99a68<br>
>> # Parent  ff3a85f715d43e2c21aec295426ae9dbe7c03d75<br>
>> lambda: change chroma lambda distortion weighting to resemble x264.<br>
>><br>
>> 1. x264 scales the chroma distortion by a factor derived from a lambda offset table<br>
>> when psyRd is enabled.<br>
>><br>
>> 2. This patch also removes the separate Cb and Cr distortion weights that were carried over from HM,<br>
>> and replaces it with 256 when psy-rd is disabled, and the above-mentioned lambda offset when it is enabled.<br>
>><br>
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.cpp<br>
>> --- a/source/Lib/TLibEncoder/TEncSearch.cpp     Mon Jun 16 16:12:00 2014 +0530<br>
>> +++ b/source/Lib/TLibEncoder/TEncSearch.cpp     Mon Jun 16 16:35:16 2014 +0530<br>
>> @@ -143,16 +143,22 @@<br>
>>      return false;<br>
>>  }<br>
>><br>
>> -void TEncSearch::setQP(int qp, double crWeight, double cbWeight)<br>
>> +void TEncSearch::setQP(int qp)<br>
>>  {<br>
>> -    double lambda2 = x265_lambda2_tab[qp];<br>
>> -    double chromaLambda = lambda2 / crWeight;<br>
>> +    double lambda2 = x265_lambda2_tab[qp];<br>
>> +<br>
>> +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)<br>
><br>
><br>
>> +    int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0);<br>
>> +    double chromaLambda = x265_lambda2_tab[effective_chroma_qp];<br>
>> +    int chroma_offset_idx = X265_MIN (qp - effective_chroma_qp + 12, MAX_CHROMA_LAMBDA_OFFSET);<br>
>> +    uint64_t chromaWeight = m_rdCost->psyRdEnabled() ? x265_chroma_lambda2_offset_tab[chroma_offset_idx] : 256;<br>
>> +#undef SPEC_QP<br>
><br>
>  <br>
> 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.<br>
> 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.<br>
><br>
><br>
>><br>
>>      m_me.setQP(qp);<br>
>>      m_trQuant->setLambda(lambda2, chromaLambda);<br>
>>      m_rdCost->setLambda(lambda2, x265_lambda_tab[qp]);<br>
>> -    m_rdCost->setCbDistortionWeight(cbWeight);<br>
>> -    m_rdCost->setCrDistortionWeight(crWeight);<br>
>> +    m_rdCost->setCbDistortionWeight(chromaWeight);<br>
>> +    m_rdCost->setCrDistortionWeight(chromaWeight);<br>
>>  }<br>
>><br>
>>  void TEncSearch::xEncSubdivCbfQT(TComDataCU* cu, uint32_t trDepth, uint32_t absPartIdx, uint32_t absPartIdxStep, uint32_t width, uint32_t height, bool bLuma, bool bChroma)<br>
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/Lib/TLibEncoder/TEncSearch.h<br>
>> --- a/source/Lib/TLibEncoder/TEncSearch.h       Mon Jun 16 16:12:00 2014 +0530<br>
>> +++ b/source/Lib/TLibEncoder/TEncSearch.h       Mon Jun 16 16:35:16 2014 +0530<br>
>> @@ -142,7 +142,7 @@<br>
>><br>
>>      void setRDGoOnSbacCoder(TEncSbac* rdGoOnSbacCoder) { m_rdGoOnSbacCoder = rdGoOnSbacCoder; }<br>
>><br>
>> -    void setQP(int QP, double crWeight, double cbWeight);<br>
>> +    void setQP(int QP);<br>
>><br>
>>      TEncSearch();<br>
>>      virtual ~TEncSearch();<br>
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/frameencoder.cpp<br>
>> --- a/source/encoder/frameencoder.cpp   Mon Jun 16 16:12:00 2014 +0530<br>
>> +++ b/source/encoder/frameencoder.cpp   Mon Jun 16 16:35:16 2014 +0530<br>
>> @@ -363,22 +363,8 @@<br>
>>  }<br>
>><br>
>>  void FrameEncoder::setLambda(int qp, int row)<br>
>> -{<br>
>> -    TComSlice*  slice = m_pic->getSlice();<br>
>> -    int         chFmt = slice->getSPS()->getChromaFormatIdc();<br>
>> -<br>
>> -    // for RDO<br>
>> -    // in RdCost there is only one lambda because the luma and chroma bits are not separated,<br>
>> -    // instead we weight the distortion of chroma.<br>
>> -    int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();<br>
>> -    int qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);<br>
>> -    double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset<br>
>> -<br>
>> -    chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();<br>
>> -    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);<br>
>> -    double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset<br>
>> -<br>
>> -    m_rows[row].m_search.setQP(qp, crWeight, cbWeight);<br>
>> +{<br>
>> +    m_rows[row].m_search.setQP(qp);<br>
>>  }<br>
>><br>
>>  void FrameEncoder::compressFrame()<br>
>> @@ -387,7 +373,6 @@<br>
>>      int64_t      startCompressTime = x265_mdate();<br>
>>      TEncEntropy* entropyCoder      = getEntropyCoder(0);<br>
>>      TComSlice*   slice             = m_pic->getSlice();<br>
>> -    int          chFmt             = slice->getSPS()->getChromaFormatIdc();<br>
>>      int          totalCoded        = (int)m_top->m_encodedFrameNum - 1;<br>
>><br>
>>      m_nalCount = 0;<br>
>> @@ -515,21 +500,13 @@<br>
>>      }<br>
>><br>
>>      int qp = slice->getSliceQp();<br>
>> -<br>
>> -    // for RDO<br>
>> -    // in RdCost there is only one lambda because the luma and chroma bits are not separated,<br>
>> -    // instead we weight the distortion of chroma.<br>
>> -    int qpc;<br>
>> -    int chromaQPOffset = slice->getPPS()->getChromaCbQpOffset() + slice->getSliceQpDeltaCb();<br>
>> -    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);<br>
>> -    double cbWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset<br>
>> -<br>
>> -    chromaQPOffset = slice->getPPS()->getChromaCrQpOffset() + slice->getSliceQpDeltaCr();<br>
>> -    qpc = Clip3(0, MAX_MAX_QP, qp + chromaQPOffset);<br>
>> -    double crWeight = pow(2.0, (qp - g_chromaScale[chFmt][qpc]) / 3.0); // takes into account of the chroma qp mapping and chroma qp Offset<br>
>> -<br>
>> +<br>
>>      double lambda = x265_lambda2_tab[qp];<br>
>> -    double chromaLambda = lambda / crWeight;<br>
>> +<br>
>> +#define SPEC_QP(x) X265_MIN(x, QP_MAX_SPEC)<br>
>> +    int effective_chroma_qp = chroma_qp_table[SPEC_QP(qp)] + X265_MAX(qp - QP_MAX_SPEC, 0);<br>
>> +    double chromaLambda = x265_lambda2_tab[effective_chroma_qp];<br>
>> +#undef SPEC_QP<br>
>><br>
>>      // NOTE: set SAO lambda every Frame<br>
>>      m_frameFilter.m_sao.lumaLambda = lambda;<br>
>> @@ -539,7 +516,7 @@<br>
>>      for (int i = 0; i < m_numRows; i++)<br>
>>      {<br>
>>          m_rows[i].m_search.m_me.setSourcePlane(fenc->getLumaAddr(), fenc->getStride());<br>
>> -        m_rows[i].m_search.setQP(qp, crWeight, cbWeight);<br>
>> +        m_rows[i].m_search.setQP(qp);<br>
>>      }<br>
>><br>
>>      // Clip qps back to 0-51 range before encoding<br>
>> diff -r ff3a85f715d4 -r 4d76a9c8b5ab source/encoder/rdcost.h<br>
>> --- a/source/encoder/rdcost.h   Mon Jun 16 16:12:00 2014 +0530<br>
>> +++ b/source/encoder/rdcost.h   Mon Jun 16 16:35:16 2014 +0530<br>
>> @@ -53,14 +53,14 @@<br>
>>          m_lambdaSAD = (uint64_t)floor(256.0 * lambda);<br>
>>      }<br>
>><br>
>> -    void setCbDistortionWeight(double cbDistortionWeight)<br>
>> +    void setCbDistortionWeight(uint64_t cbDistortionWeight)<br>
>>      {<br>
>> -        m_cbDistortionWeight = (uint64_t)floor(256.0 * cbDistortionWeight);<br>
>> +        m_cbDistortionWeight = cbDistortionWeight;<br>
>>      }<br>
>><br>
>> -    void setCrDistortionWeight(double crDistortionWeight)<br>
>> +    void setCrDistortionWeight(uint64_t crDistortionWeight)<br>
>>      {<br>
>> -        m_crDistortionWeight = (uint64_t)floor(256.0 * crDistortionWeight);<br>
>> +        m_crDistortionWeight = crDistortionWeight;<br>
>>      }<br>
>><br>
>>      void setPsyRdScale(double scale)<br>
>> _______________________________________________<br>
>> x265-devel mailing list<br>
>> <a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
>> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
><br>
><br>
><br>
> _______________________________________________<br>
> x265-devel mailing list<br>
> <a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
> <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
><br>
</p>
</div></div><br>_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
<br></blockquote></div><br></div>