[x265] [PATCH 2 of 3] lambda: change chroma lambda distortion weighting to resemble x264

Aarthi Priya Thirumalai aarthi at multicorewareinc.com
Mon Jun 16 16:40:10 CEST 2014


pg 155 of HEVC standard:
Table 8-9 – Specification of QpC as a function of qPi
qPi < 30 30 31 32 33 34 35 36 37 38 39 40 41 42 43 > 43
QpC = qPi 29 30 31 32 33 33 34 34 35 35 36 36 37 37 = qPi − 6

AFAIK, values in g_chromaScale[CHROMA_420] follows the spec exactly. not
sure how the values for other chroma formats were derived.


On Mon, Jun 16, 2014 at 7:42 PM, Deepthi Nandakumar <
deepthi at multicorewareinc.com> wrote:

> 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
> >
>
> _______________________________________________
> 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/bda3da78/attachment-0001.html>


More information about the x265-devel mailing list