<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, May 20, 2014 at 7:40 PM,  <span dir="ltr"><<a href="mailto:x265-devel-request@videolan.org" target="_blank">x265-devel-request@videolan.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Send x265-devel mailing list submissions to<br>
        <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
        <a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
or, via email, send a message with subject or body 'help' to<br>
        <a href="mailto:x265-devel-request@videolan.org">x265-devel-request@videolan.org</a><br>
<br>
You can reach the person managing the list at<br>
        <a href="mailto:x265-devel-owner@videolan.org">x265-devel-owner@videolan.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of x265-devel digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
   1. Re: x265-devel Digest, Vol 12, Issue 38 (Steve Borho)<br>
   2. Re: [PATCH] noise reduction feature, ported from x264<br>
      (Steve Borho)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Tue, 20 May 2014 08:29:32 -0500<br>
From: Steve Borho <<a href="mailto:steve@borho.org">steve@borho.org</a>><br>
To: Development for x265 <<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a>><br>
Subject: Re: [x265] x265-devel Digest, Vol 12, Issue 38<br>
Message-ID:<br>
        <CACD6pqMDaiKzeiEEkUBg5B3e4QuW0qDQ=6K_o6Yn=<a href="mailto:CyhHhvUqQ@mail.gmail.com">CyhHhvUqQ@mail.gmail.com</a>><br>
Content-Type: text/plain; charset=UTF-8<br>
<br>
On Tue, May 20, 2014 at 3:34 AM, Ashok Kumar Mishra<br>
<<a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a>> wrote:<br>
><br>
><br>
><br>
>> ------------------------------<br>
>><br>
>> Message: 2<br>
>> Date: Mon, 19 May 2014 18:33:37 -0500<br>
>> From: Steve Borho <<a href="mailto:steve@borho.org">steve@borho.org</a>><br>
>> To: Development for x265 <<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a>><br>
>> Subject: Re: [x265] [PATCH] fix : square chroma transform expected<br>
>>         error   message<br>
>> Message-ID:<br>
>><br>
>> <<a href="mailto:CACD6pqN6dErJB5ye3t7pQkMraniEFpcQ1-a6Q0YBDfCAMcfBUw@mail.gmail.com">CACD6pqN6dErJB5ye3t7pQkMraniEFpcQ1-a6Q0YBDfCAMcfBUw@mail.gmail.com</a>><br>
>> Content-Type: text/plain; charset=UTF-8<br>
>><br>
>> On Mon, May 19, 2014 at 8:49 AM,  <<a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a>> wrote:<br>
>> > # HG changeset patch<br>
>> > # User Ashok Kumar Mishra<<a href="mailto:ashok@multicorewareinc.com">ashok@multicorewareinc.com</a>><br>
>> > # Date 1400507347 -19800<br>
>> > #      Mon May 19 19:19:07 2014 +0530<br>
>> > # Node ID 8647c7861144eee4a0f96687794607b3e98d7b9f<br>
>> > # Parent  ba2a9f61ea06f0ac799d8c0247eec770065465bb<br>
>> > fix :  square chroma transform expected error message<br>
>> ><br>
>> > diff -r ba2a9f61ea06 -r 8647c7861144<br>
>> > source/Lib/TLibEncoder/TEncSearch.cpp<br>
>> > --- a/source/Lib/TLibEncoder/TEncSearch.cpp     Fri May 16 19:20:46 2014<br>
>> > +0900<br>
>> > +++ b/source/Lib/TLibEncoder/TEncSearch.cpp     Mon May 19 19:19:07 2014<br>
>> > +0530<br>
>> > @@ -2975,7 +2975,7 @@<br>
>> >                  else<br>
>> >                  {<br>
>> >                      int16_t *ptr = resiYuv->getCbAddr(absTUPartIdxC);<br>
>> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma<br>
>> > transform expected\n");<br>
>> > +                    X265_CHECK(widthC == heightC, "square chroma<br>
>> > transform expected\n");<br>
>><br>
>> this sets off warning bells to me; the blockfill_s primitive is<br>
>> writing (filling) a square block based on trWidthC.  Is this safe for<br>
>> 4:2:2?<br>
>><br>
>> ><br>
>> > primitives.blockfill_s[(int)g_convertToBit[trWidthC]](ptr,<br>
>> > resiYuv->m_cwidth, 0);<br>
>> >                  }<br>
>> >                  if (absSumV)<br>
>> > @@ -2991,7 +2991,7 @@<br>
>> >                  else<br>
>> >                  {<br>
>> >                      int16_t *ptr =  resiYuv->getCrAddr(absTUPartIdxC);<br>
>> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma<br>
>> > transform expected\n");<br>
>> > +                    X265_CHECK(widthC == heightC, "square chroma<br>
>> > transform expected\n");<br>
>> ><br>
>> > primitives.blockfill_s[(int)g_convertToBit[trWidthC]](ptr,<br>
>> > resiYuv->m_cwidth, 0);<br>
>> >                  }<br>
>> >                  cu->setCbfPartRange(absSumU ? setCbf : 0,<br>
>> > TEXT_CHROMA_U, absTUPartIdxC, tuIterator.m_absPartIdxStep);<br>
>> > @@ -3348,7 +3348,7 @@<br>
>> >                  {<br>
>> >                      int16_t *ptr =<br>
>> > m_qtTempShortYuv[qtlayer].getCbAddr(tuIterator.m_absPartIdxTURelCU);<br>
>> >                      const uint32_t stride =<br>
>> > m_qtTempShortYuv[qtlayer].m_cwidth;<br>
>> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma<br>
>> > transform expected\n");<br>
>> > +                    X265_CHECK(widthC == heightC, "square chroma<br>
>> > transform expected\n");<br>
>> ><br>
>> > primitives.blockfill_s[(int)g_convertToBit[widthC]](ptr, stride, 0);<br>
>> >                  }<br>
>> ><br>
>> > @@ -3416,7 +3416,7 @@<br>
>> >                  {<br>
>> >                      int16_t *ptr =<br>
>> > m_qtTempShortYuv[qtlayer].getCrAddr(tuIterator.m_absPartIdxTURelCU);<br>
>> >                      const uint32_t stride =<br>
>> > m_qtTempShortYuv[qtlayer].m_cwidth;<br>
>> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma<br>
>> > transform expected\n");<br>
>> > +                    X265_CHECK(widthC == heightC, "square chroma<br>
>> > transform expected\n");<br>
>> ><br>
>> > primitives.blockfill_s[(int)g_convertToBit[widthC]](ptr, stride, 0);<br>
>> >                  }<br>
>> ><br>
>><br>
>><br>
>> Yes, it is safe for 422, since trWidthC is same as widthC. But trHeightC<br>
>> is getting halved in case of 422 and stored in heightC.<br>
<br>
That only answers half the question though.  The other half is whether<br>
it is safe to write a widthC x widthC square block into that buffer,<br>
or whether that buffer was allocated as widthC x heightC.<br>
<br>
--<br>
Steve Borho<br>
<br></blockquote><div>Since it must be a square block, widthC and heightC are same value. So it is safe to write two </div><div>widthC x widthC   square blocks into that buffer in two iterations for 422 format.</div><div>
<br></div><div>Regards</div><div>Ashok</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
------------------------------<br>
<br>
Message: 2<br>
Date: Tue, 20 May 2014 09:10:42 -0500<br>
From: Steve Borho <<a href="mailto:steve@borho.org">steve@borho.org</a>><br>
To: Development for x265 <<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a>><br>
Subject: Re: [x265] [PATCH] noise reduction feature, ported from x264<br>
Message-ID:<br>
        <<a href="mailto:CACD6pqP7w9JDawov5OwdsbPs4CdrvxT1GP6dE059Tavv6W79mA@mail.gmail.com">CACD6pqP7w9JDawov5OwdsbPs4CdrvxT1GP6dE059Tavv6W79mA@mail.gmail.com</a>><br>
Content-Type: text/plain; charset=UTF-8<br>
<br>
On Tue, May 20, 2014 at 2:20 AM,  <<a href="mailto:praveen@multicorewareinc.com">praveen@multicorewareinc.com</a>> wrote:<br>
> # HG changeset patch<br>
> # User Praveen Tiwari<br>
> # Date 1400570170 -19800<br>
> # Node ID 5dd459c0b7a0c4d7a4c194323d00fdc044f2ba13<br>
> # Parent  b35a5d8f012b5d2d45865bf2a1419df2cd8087d6<br>
> noise reduction feature, ported from x264<br>
<br>
I was going to queue this today, but I discovered too many problems<br>
still remaining.<br>
<br>
><br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 doc/reST/cli.rst<br>
> --- a/doc/reST/cli.rst  Sun May 18 15:02:27 2014 +0900<br>
> +++ b/doc/reST/cli.rst  Tue May 20 12:46:10 2014 +0530<br>
> @@ -184,6 +184,14 @@<br>
>         picture. Only applicable when the input bit depth is larger than<br>
>         8bits and internal bit depth is 8bits. Default disabled<br>
><br>
> +.. option:: --nr<br>
> +<br>
> +    It's just an adaptive deadzone applied after DCT (subtracting from DCT coefficients),<br>
> +    before quantization, on inter blocks. It does no pixel-level filtering, doesn't cross<br>
> +    DCT block boundaries, has no overlap, doesn't affect intra blocks.<br>
> +<br>
> +    **Values:** any value in range of 100 to 1000. Default disabled.<br>
> +<br>
>         **CLI ONLY**<br>
<br>
CLI ONLY is for the dither option above, it doesn't apply to --nr.<br>
Also, you need to specify the argument type and in general I had<br>
improved the description locally to look like this:<br>
<br>
.. option:: --nr <integer><br>
<br>
 Noise reduction - an adaptive deadzone applied after DCT<br>
 (subtracting from DCT coefficients), before quantization, on inter<br>
 blocks. It does no pixel-level filtering, doesn't cross DCT block<br>
 boundaries, has no overlap, and doesn't affect intra blocks. The<br>
 higher the strength value parameter, the more aggressively it will<br>
 reduce noise.<br>
<br>
    **Values:** any value in range of 100 to 1000. Default disabled.<br>
<br>
<br>
><br>
>  .. option:: --input-res <wxh><br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibCommon/TComRom.h<br>
> --- a/source/Lib/TLibCommon/TComRom.h   Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/Lib/TLibCommon/TComRom.h   Tue May 20 12:46:10 2014 +0530<br>
> @@ -278,6 +278,10 @@<br>
>  // CABAC tables<br>
>  extern const uint8_t g_lpsTable[64][4];<br>
>  extern const uint8_t x265_exp2_lut[64];<br>
> +<br>
> +// DCT denoise tables<br>
> +extern const uint32_t g_dctDenoiseWeight4x4[16];<br>
> +extern const uint32_t g_dctDenoiseWeight8x8[64];<br>
>  }<br>
><br>
>  #endif  //ifndef X265_TCOMROM_H<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibCommon/TComTrQuant.cpp<br>
> --- a/source/Lib/TLibCommon/TComTrQuant.cpp     Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/Lib/TLibCommon/TComTrQuant.cpp     Tue May 20 12:46:10 2014 +0530<br>
> @@ -95,6 +95,19 @@<br>
>      destroyScalingList();<br>
>  }<br>
><br>
> +static void denoiseDct(coeff_t* dctCoef, uint32_t* resSum, uint16_t* offset, int size)<br>
> +{<br>
> +    for (int i = 0; i < size; i++)<br>
> +    {<br>
> +        int level = dctCoef[i];<br>
> +        int sign = level >> 31;<br>
> +        level = (level + sign) ^ sign;<br>
> +        resSum[i] += level;<br>
> +        level -= offset[i];<br>
> +        dctCoef[i] = level < 0 ? 0 : (level ^ sign) - sign;<br>
> +    }<br>
> +}<br>
> +<br>
>  /** Set qP for Quantization.<br>
>   * \param qpy QPy<br>
>   * \param bLowpass<br>
> @@ -300,16 +313,17 @@<br>
>      m_useTransformSkipFast = useTransformSkipFast;<br>
>  }<br>
><br>
> -uint32_t TComTrQuant::transformNxN(TComDataCU* cu,<br>
> -                                   int16_t*    residual,<br>
> -                                   uint32_t    stride,<br>
> -                                   coeff_t*    coeff,<br>
> -                                   uint32_t    trSize,<br>
> -                                   TextType    ttype,<br>
> -                                   uint32_t    absPartIdx,<br>
> -                                   int32_t*    lastPos,<br>
> -                                   bool        useTransformSkip,<br>
> -                                   bool        curUseRDOQ)<br>
> +uint32_t TComTrQuant::transformNxN(TComDataCU*     cu,<br>
> +                                   int16_t*        residual,<br>
> +                                   uint32_t        stride,<br>
> +                                   coeff_t*        coeff,<br>
> +                                   uint32_t        trSize,<br>
> +                                   TextType        ttype,<br>
> +                                   uint32_t        absPartIdx,<br>
> +                                   int32_t*        lastPos,<br>
> +                                   NoiseReduction* nr,<br>
> +                                   bool            useTransformSkip,<br>
> +                                   bool            curUseRDOQ)<br>
>  {<br>
>      if (cu->getCUTransquantBypass(absPartIdx))<br>
>      {<br>
> @@ -346,6 +360,15 @@<br>
>          // TODO: this may need larger data types for X265_DEPTH > 8<br>
>          const uint32_t log2BlockSize = g_convertToBit[trSize];<br>
>          primitives.dct[DCT_4x4 + log2BlockSize - ((trSize == 4) && (mode != REG_DCT))](residual, m_tmpCoeff, stride);<br>
> +        if (nr->bNoiseReduction)<br>
> +        {<br>
> +            int index = (DCT_4x4 + log2BlockSize - ((trSize == 4) && (mode != REG_DCT)));<br>
> +            if (index > 0 && index < 5)<br>
> +            {<br>
> +                denoiseDct(m_tmpCoeff, nr->residualSum[index - 1], nr->offset[index - 1], (16 << (index - 1) * 2 ));<br>
> +                nr->count[index - 1]++;<br>
> +            }<br>
> +        }<br>
>      }<br>
>      return xQuant(cu, m_tmpCoeff, coeff, trSize, ttype, absPartIdx, lastPos, curUseRDOQ);<br>
>  }<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibCommon/TComTrQuant.h<br>
> --- a/source/Lib/TLibCommon/TComTrQuant.h       Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/Lib/TLibCommon/TComTrQuant.h       Tue May 20 12:46:10 2014 +0530<br>
> @@ -128,7 +128,7 @@<br>
><br>
>      // transform & inverse transform functions<br>
>      uint32_t transformNxN(TComDataCU* cu, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t trSize,<br>
> -                          TextType ttype, uint32_t absPartIdx, int32_t* lastPos, bool useTransformSkip = false, bool curUseRDOQ = true);<br>
> +                          TextType ttype, uint32_t absPartIdx, int32_t* lastPos, NoiseReduction* nr, bool useTransformSkip = false, bool curUseRDOQ = true);<br>
><br>
>      void invtransformNxN(bool transQuantBypass, uint32_t mode, int16_t* residual, uint32_t stride, coeff_t* coeff, uint32_t trSize, int scalingListType, bool useTransformSkip = false, int lastPos = MAX_INT);<br>
><br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibEncoder/TEncSearch.cpp<br>
> --- a/source/Lib/TLibEncoder/TEncSearch.cpp     Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/Lib/TLibEncoder/TEncSearch.cpp     Tue May 20 12:46:10 2014 +0530<br>
> @@ -465,7 +465,7 @@<br>
>      m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, QP_BD_OFFSET, 0, chFmt);<br>
>      m_trQuant->selectLambda(TEXT_LUMA);<br>
><br>
> -    absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, TEXT_LUMA, absPartIdx, &lastPos, useTransformSkip);<br>
> +    absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, TEXT_LUMA, absPartIdx, &lastPos, &(m_cfg->m_nr), useTransformSkip);<br>
><br>
>      //--- set coded block flag ---<br>
>      cu->setCbfSubParts((absSum ? 1 : 0) << trDepth, TEXT_LUMA, absPartIdx, fullDepth);<br>
> @@ -589,7 +589,7 @@<br>
><br>
>          m_trQuant->selectLambda(TEXT_CHROMA);<br>
><br>
> -        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, ttype, absPartIdx, &lastPos, useTransformSkipChroma);<br>
> +        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, ttype, absPartIdx, &lastPos, &(m_cfg->m_nr), useTransformSkipChroma);<br>
><br>
>          //--- set coded block flag ---<br>
>          cu->setCbfPartRange((((absSum > 0) ? 1 : 0) << origTrDepth), ttype, absPartIdx, absPartIdxStep);<br>
> @@ -902,7 +902,7 @@<br>
><br>
>          m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, QP_BD_OFFSET, 0, chFmt);<br>
>          m_trQuant->selectLambda(TEXT_LUMA);<br>
> -        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, TEXT_LUMA, absPartIdx, &lastPos, useTransformSkip);<br>
> +        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, TEXT_LUMA, absPartIdx, &lastPos, &(m_cfg->m_nr), useTransformSkip);<br>
><br>
>          //--- set coded block flag ---<br>
>          cu->setCbfSubParts((absSum ? 1 : 0) << trDepth, TEXT_LUMA, absPartIdx, fullDepth);<br>
> @@ -1497,7 +1497,7 @@<br>
><br>
>                  m_trQuant->selectLambda(TEXT_CHROMA);<br>
><br>
> -                absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, ttype, absTUPartIdxC, &lastPos, useTransformSkipChroma);<br>
> +                absSum = m_trQuant->transformNxN(cu, residual, stride, coeff, tuSize, ttype, absTUPartIdxC, &lastPos, &(m_cfg->m_nr), useTransformSkipChroma);<br>
><br>
>                  //--- set coded block flag ---<br>
>                  cu->setCbfPartRange((((absSum > 0) ? 1 : 0) << origTrDepth), ttype, absTUPartIdxC, tuIterator.m_absPartIdxStep);<br>
> @@ -2901,7 +2901,7 @@<br>
>          m_trQuant->selectLambda(TEXT_LUMA);<br>
><br>
>          absSumY = m_trQuant->transformNxN(cu, resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,<br>
> -                                          trWidth, TEXT_LUMA, absPartIdx, &lastPosY, false, curuseRDOQ);<br>
> +                                          trWidth, TEXT_LUMA, absPartIdx, &lastPosY, &(m_cfg->m_nr), false, curuseRDOQ);<br>
><br>
>          cu->setCbfSubParts(absSumY ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);<br>
><br>
> @@ -2945,12 +2945,12 @@<br>
>                  m_trQuant->selectLambda(TEXT_CHROMA);<br>
><br>
>                  absSumU = m_trQuant->transformNxN(cu, resiYuv->getCbAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurU + subTUBufferOffset,<br>
> -                                                  trWidthC, TEXT_CHROMA_U, absTUPartIdxC, &lastPosU, false, curuseRDOQ);<br>
> +                                                  trWidthC, TEXT_CHROMA_U, absTUPartIdxC, &lastPosU, &(m_cfg->m_nr), false, curuseRDOQ);<br>
><br>
>                  curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();<br>
>                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);<br>
>                  absSumV = m_trQuant->transformNxN(cu, resiYuv->getCrAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurV + subTUBufferOffset,<br>
> -                                                  trWidthC, TEXT_CHROMA_V, absTUPartIdxC, &lastPosV, false, curuseRDOQ);<br>
> +                                                  trWidthC, TEXT_CHROMA_V, absTUPartIdxC, &lastPosV, &(m_cfg->m_nr), false, curuseRDOQ);<br>
><br>
>                  cu->setCbfPartRange(absSumU ? setCbf : 0, TEXT_CHROMA_U, absTUPartIdxC, tuIterator.m_absPartIdxStep);<br>
>                  cu->setCbfPartRange(absSumV ? setCbf : 0, TEXT_CHROMA_V, absTUPartIdxC, tuIterator.m_absPartIdxStep);<br>
> @@ -3118,7 +3118,7 @@<br>
>          m_trQuant->selectLambda(TEXT_LUMA);<br>
><br>
>          absSum[TEXT_LUMA][0] = m_trQuant->transformNxN(cu, resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,<br>
> -                                                       trWidth, TEXT_LUMA, absPartIdx, &lastPos[TEXT_LUMA][0], false, curuseRDOQ);<br>
> +                                                       trWidth, TEXT_LUMA, absPartIdx, &lastPos[TEXT_LUMA][0], &(m_cfg->m_nr), false, curuseRDOQ);<br>
><br>
>          cu->setCbfSubParts(absSum[TEXT_LUMA][0] ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);<br>
><br>
> @@ -3156,12 +3156,12 @@<br>
>                  m_trQuant->selectLambda(TEXT_CHROMA);<br>
><br>
>                  absSum[TEXT_CHROMA_U][tuIterator.m_section] = m_trQuant->transformNxN(cu, resiYuv->getCbAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth, coeffCurU + subTUBufferOffset,<br>
> -                                                                                      widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, &lastPos[TEXT_CHROMA_U][tuIterator.m_section], false, curuseRDOQ);<br>

> +                                                                                      widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, &lastPos[TEXT_CHROMA_U][tuIterator.m_section], &(m_cfg->m_nr), false, curuseRDOQ);<br>

>                  //Cr transform<br>
>                  curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();<br>
>                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);<br>
>                  absSum[TEXT_CHROMA_V][tuIterator.m_section] = m_trQuant->transformNxN(cu, resiYuv->getCrAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth, coeffCurV + subTUBufferOffset,<br>
> -                                                                                      widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, &lastPos[TEXT_CHROMA_V][tuIterator.m_section], false, curuseRDOQ);<br>

> +                                                                                      widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, &lastPos[TEXT_CHROMA_V][tuIterator.m_section], &(m_cfg->m_nr), false, curuseRDOQ);<br>

<br>
We don't use parens around &(m_cfg->m_nr). Order of precedence in C<br>
make &m_cfg->m_nr work just fine.<br>
<br>
><br>
>                  cu->setCbfPartRange(absSum[TEXT_CHROMA_U][tuIterator.m_section] ? setCbf : 0, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);<br>
>                  cu->setCbfPartRange(absSum[TEXT_CHROMA_V][tuIterator.m_section] ? setCbf : 0, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);<br>
> @@ -3451,7 +3451,7 @@<br>
><br>
>              m_trQuant->selectLambda(TEXT_LUMA);<br>
>              absSumTransformSkipY = m_trQuant->transformNxN(cu, resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,<br>
> -                                                           trWidth, TEXT_LUMA, absPartIdx, &lastPosTransformSkip[TEXT_LUMA][0], true, curuseRDOQ);<br>
> +                                                           trWidth, TEXT_LUMA, absPartIdx, &lastPosTransformSkip[TEXT_LUMA][0], &(m_cfg->m_nr), true, curuseRDOQ);<br>
>              cu->setCbfSubParts(absSumTransformSkipY ? setCbf : 0, TEXT_LUMA, absPartIdx, depth);<br>
><br>
>              if (absSumTransformSkipY)<br>
> @@ -3544,11 +3544,11 @@<br>
>                  m_trQuant->selectLambda(TEXT_CHROMA);<br>
><br>
>                  absSumTransformSkipU = m_trQuant->transformNxN(cu, resiYuv->getCbAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth, coeffCurU + subTUBufferOffset,<br>
> -                                                               widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, &lastPosTransformSkip[TEXT_CHROMA_U][tuIterator.m_section], true, curuseRDOQ);<br>
> +                                                               widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, &lastPosTransformSkip[TEXT_CHROMA_U][tuIterator.m_section], &(m_cfg->m_nr), true, curuseRDOQ);<br>

>                  curChromaQpOffset = cu->getSlice()->getPPS()->getChromaCrQpOffset() + cu->getSlice()->getSliceQpDeltaCr();<br>
>                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA, cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);<br>
>                  absSumTransformSkipV = m_trQuant->transformNxN(cu, resiYuv->getCrAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth, coeffCurV + subTUBufferOffset,<br>
> -                                                               widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, &lastPosTransformSkip[TEXT_CHROMA_V][tuIterator.m_section], true, curuseRDOQ);<br>
> +                                                               widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, &lastPosTransformSkip[TEXT_CHROMA_V][tuIterator.m_section], &(m_cfg->m_nr), true, curuseRDOQ);<br>

><br>
>                  cu->setCbfPartRange(absSumTransformSkipU ? setCbf : 0, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);<br>
>                  cu->setCbfPartRange(absSumTransformSkipV ? setCbf : 0, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/common/common.h<br>
> --- a/source/common/common.h    Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/common/common.h    Tue May 20 12:46:10 2014 +0530<br>
> @@ -177,6 +177,21 @@<br>
>  #define X265_LOG2(x)  log2(x)<br>
>  #endif<br>
><br>
> +struct NoiseReduction<br>
> +{<br>
> +    bool bNoiseReduction;<br>
> +<br>
> +    /* 0 = luma 4x4, 1 = luma 8x8, 2 = luma 16x16, 3 = luma 32x32<br>
> +     * 4 = chroma 4x4, 5 = chroma 8x8, 6 = chroma 16x16, 7 = chroma 32x32 */<br>
> +    uint16_t (*offset)[1024];<br>
> +    uint32_t (*residualSum)[1024];<br>
> +    uint32_t *count;<br>
> +<br>
> +    uint16_t offsetDenoise[8][1024];<br>
> +    uint32_t residualSumBuf[4][8][1024];<br>
> +    uint32_t countBuf[4][8];<br>
> +};<br>
> +<br>
>  /* defined in common.cpp */<br>
>  int64_t x265_mdate(void);<br>
>  void x265_log(const x265_param *param, int level, const char *fmt, ...);<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/common/param.cpp<br>
> --- a/source/common/param.cpp   Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/common/param.cpp   Tue May 20 12:46:10 2014 +0530<br>
> @@ -694,6 +694,7 @@<br>
>                           &p->vui.defDispWinRightOffset,<br>
>                           &p->vui.defDispWinBottomOffset) != 4;<br>
>      }<br>
> +    OPT("nr") p->noiseReduction = atoi(value);<br>
>      else<br>
>          return X265_PARAM_BAD_NAME;<br>
>  #undef OPT<br>
> @@ -986,6 +987,8 @@<br>
>      CHECK(param->rc.bitrate < 0,<br>
>            "Target bitrate can not be less than zero");<br>
>      CHECK(param->bFrameBias < 0, "Bias towards B frame decisions must be 0 or greater");<br>
> +    if (param->noiseReduction)<br>
> +        CHECK(100 > param->noiseReduction || param->noiseReduction > 1000, "Valid noise reduction range 100 - 1000");<br>
>      return check_failed;<br>
>  }<br>
><br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/encoder/encoder.cpp<br>
> --- a/source/encoder/encoder.cpp        Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/encoder/encoder.cpp        Tue May 20 12:46:10 2014 +0530<br>
> @@ -64,6 +64,14 @@<br>
>      m_csvfpt = NULL;<br>
>      param = NULL;<br>
><br>
> +    memset(m_nr.offsetDenoise, 0, sizeof(m_nr.offsetDenoise[0][0]) * 8 * 1024);<br>
> +    memset(m_nr.residualSumBuf, 0, sizeof(m_nr.residualSumBuf[0][0][0]) * 4 * 8 * 1024);<br>
> +    memset(m_nr.countBuf, 0, sizeof(m_nr.countBuf[0][0]) * 4 * 8);<br>
> +<br>
> +    m_nr.offset = m_nr.offsetDenoise;<br>
> +    m_nr.residualSum = m_nr.residualSumBuf[0];<br>
> +    m_nr.count = m_nr.countBuf[0];<br>
> +<br>
>  #if ENC_DEC_TRACE<br>
>      g_hTrace = fopen("TraceEnc.txt", "wb");<br>
>      g_bJustDoIt = g_bEncDecTraceDisable;<br>
> @@ -186,6 +194,7 @@<br>
>      }<br>
>      m_lookahead->init();<br>
>      m_encodeStartTime = x265_mdate();<br>
> +    m_nr.bNoiseReduction = !!param->noiseReduction;<br>
>  }<br>
><br>
>  int Encoder::getStreamHeaders(NALUnitEBSP **nalunits)<br>
> @@ -218,6 +227,44 @@<br>
>      }<br>
>  }<br>
><br>
> +/****************************************************************************<br>
> + * DCT-domain noise reduction / adaptive deadzone<br>
> + * from libavcodec<br>
> + ****************************************************************************/<br>
> +<br>
> +void Encoder::noiseReductionUpdate(NoiseReduction* h)<br>
<br>
naming this pointer `h` is probably an x264'ism we don't need to bring<br>
along from their code.  `nr` would be better.<br>
<br>
> +{<br>
> +    h->offset = h->offsetDenoise;<br>
> +    h->residualSum = h->residualSumBuf[0];<br>
> +    h->count = h->countBuf[0];<br>
> +<br>
> +    int transformSize[4] = {16, 64, 256, 1024};<br>
> +    uint32_t blockCount[4] = { 1 << 18, 1 << 16, 1 << 14, 1 << 12 };<br>
> +<br>
> +    int isCspI444 = (param->internalCsp == X265_CSP_I444) ? 1 : 0;<br>
> +    for (int cat = 0; cat < 7 + isCspI444; cat++)<br>
> +    {<br>
> +        int index = cat % 4;<br>
> +        int size = transformSize[index];<br>
> +<br>
> +        if (h->count[cat] > blockCount[index])<br>
> +        {<br>
> +            for (int i = 0; i < size; i++)<br>
> +                h->residualSum[cat][i] >>= 1;<br>
> +            h->count[cat] >>= 1;<br>
> +        }<br>
> +<br>
> +        for (int i = 0; i < size; i++)<br>
> +            h->offset[cat][i] =<br>
> +                (uint16_t)(((uint64_t)param->noiseReduction * h->count[cat]<br>
> +                 + h->residualSum[cat][i] / 2)<br>
> +              / ((uint64_t)h->residualSum[cat][i] + 1));<br>
> +<br>
> +        // Don't denoise DC coefficients<br>
> +        h->offset[cat][0] = 0;<br>
> +    }<br>
<br>
Now we get to the more serious problem; this function is not thread<br>
safe and it makes the encoder non-deterministic.<br>
<br>
In order to make the encoder deterministic, noiseReductionUpdate()<br>
cannot be run at the same time a worker thread might be reading the<br>
noise reduction structure.  So m_nr needs to be moved from the top<br>
level Encoder to the FrameEncoder class (based on the name of the<br>
parameter to the function, x264 did roughly the same thing).<br>
noiseReductionUpdate() would need to be called at the end of<br>
compressFrame().<br>
<br>
Note that even after moving the m_nr structure to the FrameEncoder,<br>
--nr will be the only option which will make the outputs diverge<br>
between -FN and -FM (where N != M and N != 1 && M != 1), and this<br>
needs to be clearly documented in the --nr section of cli.txt and in<br>
the discussion of frame parallelism in threading.txt.<br>
<br>
> +}<br>
> +<br>
>  #define VERBOSE_RATE 0<br>
>  #if VERBOSE_RATE<br>
>  static const char* nalUnitTypeToString(NalUnitType type)<br>
> @@ -434,6 +481,9 @@<br>
>          m_rateControl->rateControlEnd(out, bits, &curEncoder->m_rce);<br>
>          finishFrameStats(out, curEncoder, bits);<br>
><br>
> +        if (m_nr.bNoiseReduction)<br>
> +            noiseReductionUpdate(&m_nr);<br>
> +<br>
>          // Allow this frame to be recycled if no frame encoders are using it for reference<br>
>          ATOMIC_DEC(&out->m_countRefEncoders);<br>
>          m_dpb->recycleUnreferenced(m_freeList);<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/encoder/encoder.h<br>
> --- a/source/encoder/encoder.h  Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/encoder/encoder.h  Tue May 20 12:46:10 2014 +0530<br>
> @@ -194,6 +194,8 @@<br>
>      x265_nal*          m_nals;<br>
>      char*              m_packetData;<br>
><br>
> +    NoiseReduction     m_nr;<br>
> +<br>
>      Encoder();<br>
><br>
>      virtual ~Encoder();<br>
> @@ -227,6 +229,8 @@<br>
><br>
>      void updateVbvPlan(RateControl* rc);<br>
><br>
> +    void noiseReductionUpdate(NoiseReduction* nr);<br>
> +<br>
>  protected:<br>
><br>
>      void finishFrameStats(TComPic* pic, FrameEncoder *curEncoder, uint64_t bits);<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/x265.cpp<br>
> --- a/source/x265.cpp   Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/x265.cpp   Tue May 20 12:46:10 2014 +0530<br>
> @@ -176,6 +176,7 @@<br>
>      { "qpfile",         required_argument, NULL, 0 },<br>
>      { "b-intra",              no_argument, NULL, 0 },<br>
>      { "no-b-intra",           no_argument, NULL, 0 },<br>
> +    { "nr",             required_argument, NULL, 0 },<br>
>      { 0, 0, 0, 0 }<br>
>  };<br>
><br>
> @@ -414,6 +415,8 @@<br>
>      H0("\nReconstructed video options (debugging):\n");<br>
>      H0("-r/--recon <filename>            Reconstructed raw image YUV or Y4M output file name\n");<br>
>      H0("   --recon-depth <integer>       Bit-depth of reconstructed raw image file. Defaults to input bit depth, or 8 if Y4M\n");<br>
> +    H0("\nNoiseReduction option:\n");<br>
> +    H0("   --nr <integer>                An integer value in range of 100 to 1000, which denotes strength of noise reduction. Default disabled\n");<br>
>  #undef OPT<br>
>  #undef H0<br>
>      printf("\n\nFull documentation may be found at <a href="http://x265.readthedocs.org/en/default/cli.html\n" target="_blank">http://x265.readthedocs.org/en/default/cli.html\n</a>");<br>
> diff -r b35a5d8f012b -r 5dd459c0b7a0 source/x265.h<br>
> --- a/source/x265.h     Sun May 18 15:02:27 2014 +0900<br>
> +++ b/source/x265.h     Tue May 20 12:46:10 2014 +0530<br>
> @@ -646,6 +646,10 @@<br>
>       * regardless of this setting. */<br>
>      int       bIntraInBFrames;<br>
><br>
> +    /* An integer value in range of 100 to 1000, which denotes strength of noise<br>
> +     * reduction */<br>
> +    int       noiseReduction;<br>
> +<br>
>      /*== Rate Control ==*/<br>
><br>
>      struct<br>
<br>
Lastly, the patch needs to increase X265_BUILD<br>
<br>
--<br>
Steve Borho<br>
<br>
<br>
------------------------------<br>
<br>
Subject: Digest Footer<br>
<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>
<br>
------------------------------<br>
<br>
End of x265-devel Digest, Vol 12, Issue 41<br>
******************************************<br>
</blockquote></div><br></div></div>