[x265] x265-devel Digest, Vol 12, Issue 41

Ashok Kumar Mishra ashok at multicorewareinc.com
Tue May 20 16:50:12 CEST 2014


On Tue, May 20, 2014 at 7:40 PM, <x265-devel-request at videolan.org> wrote:

> Send x265-devel mailing list submissions to
>         x265-devel at videolan.org
>
> To subscribe or unsubscribe via the World Wide Web, visit
>         https://mailman.videolan.org/listinfo/x265-devel
> or, via email, send a message with subject or body 'help' to
>         x265-devel-request at videolan.org
>
> You can reach the person managing the list at
>         x265-devel-owner at videolan.org
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of x265-devel digest..."
>
>
> Today's Topics:
>
>    1. Re: x265-devel Digest, Vol 12, Issue 38 (Steve Borho)
>    2. Re: [PATCH] noise reduction feature, ported from x264
>       (Steve Borho)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Tue, 20 May 2014 08:29:32 -0500
> From: Steve Borho <steve at borho.org>
> To: Development for x265 <x265-devel at videolan.org>
> Subject: Re: [x265] x265-devel Digest, Vol 12, Issue 38
> Message-ID:
>         <CACD6pqMDaiKzeiEEkUBg5B3e4QuW0qDQ=6K_o6Yn=
> CyhHhvUqQ at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Tue, May 20, 2014 at 3:34 AM, Ashok Kumar Mishra
> <ashok at multicorewareinc.com> wrote:
> >
> >
> >
> >> ------------------------------
> >>
> >> Message: 2
> >> Date: Mon, 19 May 2014 18:33:37 -0500
> >> From: Steve Borho <steve at borho.org>
> >> To: Development for x265 <x265-devel at videolan.org>
> >> Subject: Re: [x265] [PATCH] fix : square chroma transform expected
> >>         error   message
> >> Message-ID:
> >>
> >> <CACD6pqN6dErJB5ye3t7pQkMraniEFpcQ1-a6Q0YBDfCAMcfBUw at mail.gmail.com>
> >> Content-Type: text/plain; charset=UTF-8
> >>
> >> On Mon, May 19, 2014 at 8:49 AM,  <ashok at multicorewareinc.com> wrote:
> >> > # HG changeset patch
> >> > # User Ashok Kumar Mishra<ashok at multicorewareinc.com>
> >> > # Date 1400507347 -19800
> >> > #      Mon May 19 19:19:07 2014 +0530
> >> > # Node ID 8647c7861144eee4a0f96687794607b3e98d7b9f
> >> > # Parent  ba2a9f61ea06f0ac799d8c0247eec770065465bb
> >> > fix :  square chroma transform expected error message
> >> >
> >> > diff -r ba2a9f61ea06 -r 8647c7861144
> >> > source/Lib/TLibEncoder/TEncSearch.cpp
> >> > --- a/source/Lib/TLibEncoder/TEncSearch.cpp     Fri May 16 19:20:46
> 2014
> >> > +0900
> >> > +++ b/source/Lib/TLibEncoder/TEncSearch.cpp     Mon May 19 19:19:07
> 2014
> >> > +0530
> >> > @@ -2975,7 +2975,7 @@
> >> >                  else
> >> >                  {
> >> >                      int16_t *ptr = resiYuv->getCbAddr(absTUPartIdxC);
> >> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma
> >> > transform expected\n");
> >> > +                    X265_CHECK(widthC == heightC, "square chroma
> >> > transform expected\n");
> >>
> >> this sets off warning bells to me; the blockfill_s primitive is
> >> writing (filling) a square block based on trWidthC.  Is this safe for
> >> 4:2:2?
> >>
> >> >
> >> > primitives.blockfill_s[(int)g_convertToBit[trWidthC]](ptr,
> >> > resiYuv->m_cwidth, 0);
> >> >                  }
> >> >                  if (absSumV)
> >> > @@ -2991,7 +2991,7 @@
> >> >                  else
> >> >                  {
> >> >                      int16_t *ptr =
>  resiYuv->getCrAddr(absTUPartIdxC);
> >> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma
> >> > transform expected\n");
> >> > +                    X265_CHECK(widthC == heightC, "square chroma
> >> > transform expected\n");
> >> >
> >> > primitives.blockfill_s[(int)g_convertToBit[trWidthC]](ptr,
> >> > resiYuv->m_cwidth, 0);
> >> >                  }
> >> >                  cu->setCbfPartRange(absSumU ? setCbf : 0,
> >> > TEXT_CHROMA_U, absTUPartIdxC, tuIterator.m_absPartIdxStep);
> >> > @@ -3348,7 +3348,7 @@
> >> >                  {
> >> >                      int16_t *ptr =
> >> > m_qtTempShortYuv[qtlayer].getCbAddr(tuIterator.m_absPartIdxTURelCU);
> >> >                      const uint32_t stride =
> >> > m_qtTempShortYuv[qtlayer].m_cwidth;
> >> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma
> >> > transform expected\n");
> >> > +                    X265_CHECK(widthC == heightC, "square chroma
> >> > transform expected\n");
> >> >
> >> > primitives.blockfill_s[(int)g_convertToBit[widthC]](ptr, stride, 0);
> >> >                  }
> >> >
> >> > @@ -3416,7 +3416,7 @@
> >> >                  {
> >> >                      int16_t *ptr =
> >> > m_qtTempShortYuv[qtlayer].getCrAddr(tuIterator.m_absPartIdxTURelCU);
> >> >                      const uint32_t stride =
> >> > m_qtTempShortYuv[qtlayer].m_cwidth;
> >> > -                    X265_CHECK(trWidthC == trHeightC, "square chroma
> >> > transform expected\n");
> >> > +                    X265_CHECK(widthC == heightC, "square chroma
> >> > transform expected\n");
> >> >
> >> > primitives.blockfill_s[(int)g_convertToBit[widthC]](ptr, stride, 0);
> >> >                  }
> >> >
> >>
> >>
> >> Yes, it is safe for 422, since trWidthC is same as widthC. But trHeightC
> >> is getting halved in case of 422 and stored in heightC.
>
> That only answers half the question though.  The other half is whether
> it is safe to write a widthC x widthC square block into that buffer,
> or whether that buffer was allocated as widthC x heightC.
>
> --
> Steve Borho
>
> Since it must be a square block, widthC and heightC are same value. So it
is safe to write two
widthC x widthC   square blocks into that buffer in two iterations for 422
format.

Regards
Ashok

>
> ------------------------------
>
> Message: 2
> Date: Tue, 20 May 2014 09:10:42 -0500
> From: Steve Borho <steve at borho.org>
> To: Development for x265 <x265-devel at videolan.org>
> Subject: Re: [x265] [PATCH] noise reduction feature, ported from x264
> Message-ID:
>         <
> CACD6pqP7w9JDawov5OwdsbPs4CdrvxT1GP6dE059Tavv6W79mA at mail.gmail.com>
> Content-Type: text/plain; charset=UTF-8
>
> On Tue, May 20, 2014 at 2:20 AM,  <praveen at multicorewareinc.com> wrote:
> > # HG changeset patch
> > # User Praveen Tiwari
> > # Date 1400570170 -19800
> > # Node ID 5dd459c0b7a0c4d7a4c194323d00fdc044f2ba13
> > # Parent  b35a5d8f012b5d2d45865bf2a1419df2cd8087d6
> > noise reduction feature, ported from x264
>
> I was going to queue this today, but I discovered too many problems
> still remaining.
>
> >
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 doc/reST/cli.rst
> > --- a/doc/reST/cli.rst  Sun May 18 15:02:27 2014 +0900
> > +++ b/doc/reST/cli.rst  Tue May 20 12:46:10 2014 +0530
> > @@ -184,6 +184,14 @@
> >         picture. Only applicable when the input bit depth is larger than
> >         8bits and internal bit depth is 8bits. Default disabled
> >
> > +.. option:: --nr
> > +
> > +    It's just an adaptive deadzone applied after DCT (subtracting from
> DCT coefficients),
> > +    before quantization, on inter blocks. It does no pixel-level
> filtering, doesn't cross
> > +    DCT block boundaries, has no overlap, doesn't affect intra blocks.
> > +
> > +    **Values:** any value in range of 100 to 1000. Default disabled.
> > +
> >         **CLI ONLY**
>
> CLI ONLY is for the dither option above, it doesn't apply to --nr.
> Also, you need to specify the argument type and in general I had
> improved the description locally to look like this:
>
> .. option:: --nr <integer>
>
>  Noise reduction - an adaptive deadzone applied after DCT
>  (subtracting from DCT coefficients), before quantization, on inter
>  blocks. It does no pixel-level filtering, doesn't cross DCT block
>  boundaries, has no overlap, and doesn't affect intra blocks. The
>  higher the strength value parameter, the more aggressively it will
>  reduce noise.
>
>     **Values:** any value in range of 100 to 1000. Default disabled.
>
>
> >
> >  .. option:: --input-res <wxh>
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibCommon/TComRom.h
> > --- a/source/Lib/TLibCommon/TComRom.h   Sun May 18 15:02:27 2014 +0900
> > +++ b/source/Lib/TLibCommon/TComRom.h   Tue May 20 12:46:10 2014 +0530
> > @@ -278,6 +278,10 @@
> >  // CABAC tables
> >  extern const uint8_t g_lpsTable[64][4];
> >  extern const uint8_t x265_exp2_lut[64];
> > +
> > +// DCT denoise tables
> > +extern const uint32_t g_dctDenoiseWeight4x4[16];
> > +extern const uint32_t g_dctDenoiseWeight8x8[64];
> >  }
> >
> >  #endif  //ifndef X265_TCOMROM_H
> > diff -r b35a5d8f012b -r 5dd459c0b7a0
> source/Lib/TLibCommon/TComTrQuant.cpp
> > --- a/source/Lib/TLibCommon/TComTrQuant.cpp     Sun May 18 15:02:27 2014
> +0900
> > +++ b/source/Lib/TLibCommon/TComTrQuant.cpp     Tue May 20 12:46:10 2014
> +0530
> > @@ -95,6 +95,19 @@
> >      destroyScalingList();
> >  }
> >
> > +static void denoiseDct(coeff_t* dctCoef, uint32_t* resSum, uint16_t*
> offset, int size)
> > +{
> > +    for (int i = 0; i < size; i++)
> > +    {
> > +        int level = dctCoef[i];
> > +        int sign = level >> 31;
> > +        level = (level + sign) ^ sign;
> > +        resSum[i] += level;
> > +        level -= offset[i];
> > +        dctCoef[i] = level < 0 ? 0 : (level ^ sign) - sign;
> > +    }
> > +}
> > +
> >  /** Set qP for Quantization.
> >   * \param qpy QPy
> >   * \param bLowpass
> > @@ -300,16 +313,17 @@
> >      m_useTransformSkipFast = useTransformSkipFast;
> >  }
> >
> > -uint32_t TComTrQuant::transformNxN(TComDataCU* cu,
> > -                                   int16_t*    residual,
> > -                                   uint32_t    stride,
> > -                                   coeff_t*    coeff,
> > -                                   uint32_t    trSize,
> > -                                   TextType    ttype,
> > -                                   uint32_t    absPartIdx,
> > -                                   int32_t*    lastPos,
> > -                                   bool        useTransformSkip,
> > -                                   bool        curUseRDOQ)
> > +uint32_t TComTrQuant::transformNxN(TComDataCU*     cu,
> > +                                   int16_t*        residual,
> > +                                   uint32_t        stride,
> > +                                   coeff_t*        coeff,
> > +                                   uint32_t        trSize,
> > +                                   TextType        ttype,
> > +                                   uint32_t        absPartIdx,
> > +                                   int32_t*        lastPos,
> > +                                   NoiseReduction* nr,
> > +                                   bool            useTransformSkip,
> > +                                   bool            curUseRDOQ)
> >  {
> >      if (cu->getCUTransquantBypass(absPartIdx))
> >      {
> > @@ -346,6 +360,15 @@
> >          // TODO: this may need larger data types for X265_DEPTH > 8
> >          const uint32_t log2BlockSize = g_convertToBit[trSize];
> >          primitives.dct[DCT_4x4 + log2BlockSize - ((trSize == 4) &&
> (mode != REG_DCT))](residual, m_tmpCoeff, stride);
> > +        if (nr->bNoiseReduction)
> > +        {
> > +            int index = (DCT_4x4 + log2BlockSize - ((trSize == 4) &&
> (mode != REG_DCT)));
> > +            if (index > 0 && index < 5)
> > +            {
> > +                denoiseDct(m_tmpCoeff, nr->residualSum[index - 1],
> nr->offset[index - 1], (16 << (index - 1) * 2 ));
> > +                nr->count[index - 1]++;
> > +            }
> > +        }
> >      }
> >      return xQuant(cu, m_tmpCoeff, coeff, trSize, ttype, absPartIdx,
> lastPos, curUseRDOQ);
> >  }
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/Lib/TLibCommon/TComTrQuant.h
> > --- a/source/Lib/TLibCommon/TComTrQuant.h       Sun May 18 15:02:27 2014
> +0900
> > +++ b/source/Lib/TLibCommon/TComTrQuant.h       Tue May 20 12:46:10 2014
> +0530
> > @@ -128,7 +128,7 @@
> >
> >      // transform & inverse transform functions
> >      uint32_t transformNxN(TComDataCU* cu, int16_t* residual, uint32_t
> stride, coeff_t* coeff, uint32_t trSize,
> > -                          TextType ttype, uint32_t absPartIdx, int32_t*
> lastPos, bool useTransformSkip = false, bool curUseRDOQ = true);
> > +                          TextType ttype, uint32_t absPartIdx, int32_t*
> lastPos, NoiseReduction* nr, bool useTransformSkip = false, bool curUseRDOQ
> = true);
> >
> >      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);
> >
> > diff -r b35a5d8f012b -r 5dd459c0b7a0
> source/Lib/TLibEncoder/TEncSearch.cpp
> > --- a/source/Lib/TLibEncoder/TEncSearch.cpp     Sun May 18 15:02:27 2014
> +0900
> > +++ b/source/Lib/TLibEncoder/TEncSearch.cpp     Tue May 20 12:46:10 2014
> +0530
> > @@ -465,7 +465,7 @@
> >      m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, QP_BD_OFFSET, 0,
> chFmt);
> >      m_trQuant->selectLambda(TEXT_LUMA);
> >
> > -    absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, TEXT_LUMA, absPartIdx, &lastPos, useTransformSkip);
> > +    absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, TEXT_LUMA, absPartIdx, &lastPos, &(m_cfg->m_nr), useTransformSkip);
> >
> >      //--- set coded block flag ---
> >      cu->setCbfSubParts((absSum ? 1 : 0) << trDepth, TEXT_LUMA,
> absPartIdx, fullDepth);
> > @@ -589,7 +589,7 @@
> >
> >          m_trQuant->selectLambda(TEXT_CHROMA);
> >
> > -        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, ttype, absPartIdx, &lastPos, useTransformSkipChroma);
> > +        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, ttype, absPartIdx, &lastPos, &(m_cfg->m_nr),
> useTransformSkipChroma);
> >
> >          //--- set coded block flag ---
> >          cu->setCbfPartRange((((absSum > 0) ? 1 : 0) << origTrDepth),
> ttype, absPartIdx, absPartIdxStep);
> > @@ -902,7 +902,7 @@
> >
> >          m_trQuant->setQPforQuant(cu->getQP(0), TEXT_LUMA, QP_BD_OFFSET,
> 0, chFmt);
> >          m_trQuant->selectLambda(TEXT_LUMA);
> > -        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, TEXT_LUMA, absPartIdx, &lastPos, useTransformSkip);
> > +        absSum = m_trQuant->transformNxN(cu, residual, stride, coeff,
> tuSize, TEXT_LUMA, absPartIdx, &lastPos, &(m_cfg->m_nr), useTransformSkip);
> >
> >          //--- set coded block flag ---
> >          cu->setCbfSubParts((absSum ? 1 : 0) << trDepth, TEXT_LUMA,
> absPartIdx, fullDepth);
> > @@ -1497,7 +1497,7 @@
> >
> >                  m_trQuant->selectLambda(TEXT_CHROMA);
> >
> > -                absSum = m_trQuant->transformNxN(cu, residual, stride,
> coeff, tuSize, ttype, absTUPartIdxC, &lastPos, useTransformSkipChroma);
> > +                absSum = m_trQuant->transformNxN(cu, residual, stride,
> coeff, tuSize, ttype, absTUPartIdxC, &lastPos, &(m_cfg->m_nr),
> useTransformSkipChroma);
> >
> >                  //--- set coded block flag ---
> >                  cu->setCbfPartRange((((absSum > 0) ? 1 : 0) <<
> origTrDepth), ttype, absTUPartIdxC, tuIterator.m_absPartIdxStep);
> > @@ -2901,7 +2901,7 @@
> >          m_trQuant->selectLambda(TEXT_LUMA);
> >
> >          absSumY = m_trQuant->transformNxN(cu,
> resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,
> > -                                          trWidth, TEXT_LUMA,
> absPartIdx, &lastPosY, false, curuseRDOQ);
> > +                                          trWidth, TEXT_LUMA,
> absPartIdx, &lastPosY, &(m_cfg->m_nr), false, curuseRDOQ);
> >
> >          cu->setCbfSubParts(absSumY ? setCbf : 0, TEXT_LUMA, absPartIdx,
> depth);
> >
> > @@ -2945,12 +2945,12 @@
> >                  m_trQuant->selectLambda(TEXT_CHROMA);
> >
> >                  absSumU = m_trQuant->transformNxN(cu,
> resiYuv->getCbAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurU +
> subTUBufferOffset,
> > -                                                  trWidthC,
> TEXT_CHROMA_U, absTUPartIdxC, &lastPosU, false, curuseRDOQ);
> > +                                                  trWidthC,
> TEXT_CHROMA_U, absTUPartIdxC, &lastPosU, &(m_cfg->m_nr), false, curuseRDOQ);
> >
> >                  curChromaQpOffset =
> cu->getSlice()->getPPS()->getChromaCrQpOffset() +
> cu->getSlice()->getSliceQpDeltaCr();
> >                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA,
> cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);
> >                  absSumV = m_trQuant->transformNxN(cu,
> resiYuv->getCrAddr(absTUPartIdxC), resiYuv->m_cwidth, coeffCurV +
> subTUBufferOffset,
> > -                                                  trWidthC,
> TEXT_CHROMA_V, absTUPartIdxC, &lastPosV, false, curuseRDOQ);
> > +                                                  trWidthC,
> TEXT_CHROMA_V, absTUPartIdxC, &lastPosV, &(m_cfg->m_nr), false, curuseRDOQ);
> >
> >                  cu->setCbfPartRange(absSumU ? setCbf : 0,
> TEXT_CHROMA_U, absTUPartIdxC, tuIterator.m_absPartIdxStep);
> >                  cu->setCbfPartRange(absSumV ? setCbf : 0,
> TEXT_CHROMA_V, absTUPartIdxC, tuIterator.m_absPartIdxStep);
> > @@ -3118,7 +3118,7 @@
> >          m_trQuant->selectLambda(TEXT_LUMA);
> >
> >          absSum[TEXT_LUMA][0] = m_trQuant->transformNxN(cu,
> resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,
> > -                                                       trWidth,
> TEXT_LUMA, absPartIdx, &lastPos[TEXT_LUMA][0], false, curuseRDOQ);
> > +                                                       trWidth,
> TEXT_LUMA, absPartIdx, &lastPos[TEXT_LUMA][0], &(m_cfg->m_nr), false,
> curuseRDOQ);
> >
> >          cu->setCbfSubParts(absSum[TEXT_LUMA][0] ? setCbf : 0,
> TEXT_LUMA, absPartIdx, depth);
> >
> > @@ -3156,12 +3156,12 @@
> >                  m_trQuant->selectLambda(TEXT_CHROMA);
> >
> >                  absSum[TEXT_CHROMA_U][tuIterator.m_section] =
> m_trQuant->transformNxN(cu,
> resiYuv->getCbAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth,
> coeffCurU + subTUBufferOffset,
> > -
>                widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU,
> &lastPos[TEXT_CHROMA_U][tuIterator.m_section], false, curuseRDOQ);
> > +
>                widthC, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU,
> &lastPos[TEXT_CHROMA_U][tuIterator.m_section], &(m_cfg->m_nr), false,
> curuseRDOQ);
> >                  //Cr transform
> >                  curChromaQpOffset =
> cu->getSlice()->getPPS()->getChromaCrQpOffset() +
> cu->getSlice()->getSliceQpDeltaCr();
> >                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA,
> cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);
> >                  absSum[TEXT_CHROMA_V][tuIterator.m_section] =
> m_trQuant->transformNxN(cu,
> resiYuv->getCrAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth,
> coeffCurV + subTUBufferOffset,
> > -
>                widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU,
> &lastPos[TEXT_CHROMA_V][tuIterator.m_section], false, curuseRDOQ);
> > +
>                widthC, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU,
> &lastPos[TEXT_CHROMA_V][tuIterator.m_section], &(m_cfg->m_nr), false,
> curuseRDOQ);
>
> We don't use parens around &(m_cfg->m_nr). Order of precedence in C
> make &m_cfg->m_nr work just fine.
>
> >
> >
>  cu->setCbfPartRange(absSum[TEXT_CHROMA_U][tuIterator.m_section] ? setCbf :
> 0, TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU,
> tuIterator.m_absPartIdxStep);
> >
>  cu->setCbfPartRange(absSum[TEXT_CHROMA_V][tuIterator.m_section] ? setCbf :
> 0, TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU,
> tuIterator.m_absPartIdxStep);
> > @@ -3451,7 +3451,7 @@
> >
> >              m_trQuant->selectLambda(TEXT_LUMA);
> >              absSumTransformSkipY = m_trQuant->transformNxN(cu,
> resiYuv->getLumaAddr(absTUPartIdx), resiYuv->m_width, coeffCurY,
> > -                                                           trWidth,
> TEXT_LUMA, absPartIdx, &lastPosTransformSkip[TEXT_LUMA][0], true,
> curuseRDOQ);
> > +                                                           trWidth,
> TEXT_LUMA, absPartIdx, &lastPosTransformSkip[TEXT_LUMA][0], &(m_cfg->m_nr),
> true, curuseRDOQ);
> >              cu->setCbfSubParts(absSumTransformSkipY ? setCbf : 0,
> TEXT_LUMA, absPartIdx, depth);
> >
> >              if (absSumTransformSkipY)
> > @@ -3544,11 +3544,11 @@
> >                  m_trQuant->selectLambda(TEXT_CHROMA);
> >
> >                  absSumTransformSkipU = m_trQuant->transformNxN(cu,
> resiYuv->getCbAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth,
> coeffCurU + subTUBufferOffset,
> > -                                                               widthC,
> TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU,
> &lastPosTransformSkip[TEXT_CHROMA_U][tuIterator.m_section], true,
> curuseRDOQ);
> > +                                                               widthC,
> TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU,
> &lastPosTransformSkip[TEXT_CHROMA_U][tuIterator.m_section], &(m_cfg->m_nr),
> true, curuseRDOQ);
> >                  curChromaQpOffset =
> cu->getSlice()->getPPS()->getChromaCrQpOffset() +
> cu->getSlice()->getSliceQpDeltaCr();
> >                  m_trQuant->setQPforQuant(cu->getQP(0), TEXT_CHROMA,
> cu->getSlice()->getSPS()->getQpBDOffsetC(), curChromaQpOffset, chFmt);
> >                  absSumTransformSkipV = m_trQuant->transformNxN(cu,
> resiYuv->getCrAddr(tuIterator.m_absPartIdxTURelCU), resiYuv->m_cwidth,
> coeffCurV + subTUBufferOffset,
> > -                                                               widthC,
> TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU,
> &lastPosTransformSkip[TEXT_CHROMA_V][tuIterator.m_section], true,
> curuseRDOQ);
> > +                                                               widthC,
> TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU,
> &lastPosTransformSkip[TEXT_CHROMA_V][tuIterator.m_section], &(m_cfg->m_nr),
> true, curuseRDOQ);
> >
> >                  cu->setCbfPartRange(absSumTransformSkipU ? setCbf : 0,
> TEXT_CHROMA_U, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);
> >                  cu->setCbfPartRange(absSumTransformSkipV ? setCbf : 0,
> TEXT_CHROMA_V, tuIterator.m_absPartIdxTURelCU, tuIterator.m_absPartIdxStep);
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/common/common.h
> > --- a/source/common/common.h    Sun May 18 15:02:27 2014 +0900
> > +++ b/source/common/common.h    Tue May 20 12:46:10 2014 +0530
> > @@ -177,6 +177,21 @@
> >  #define X265_LOG2(x)  log2(x)
> >  #endif
> >
> > +struct NoiseReduction
> > +{
> > +    bool bNoiseReduction;
> > +
> > +    /* 0 = luma 4x4, 1 = luma 8x8, 2 = luma 16x16, 3 = luma 32x32
> > +     * 4 = chroma 4x4, 5 = chroma 8x8, 6 = chroma 16x16, 7 = chroma
> 32x32 */
> > +    uint16_t (*offset)[1024];
> > +    uint32_t (*residualSum)[1024];
> > +    uint32_t *count;
> > +
> > +    uint16_t offsetDenoise[8][1024];
> > +    uint32_t residualSumBuf[4][8][1024];
> > +    uint32_t countBuf[4][8];
> > +};
> > +
> >  /* defined in common.cpp */
> >  int64_t x265_mdate(void);
> >  void x265_log(const x265_param *param, int level, const char *fmt, ...);
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/common/param.cpp
> > --- a/source/common/param.cpp   Sun May 18 15:02:27 2014 +0900
> > +++ b/source/common/param.cpp   Tue May 20 12:46:10 2014 +0530
> > @@ -694,6 +694,7 @@
> >                           &p->vui.defDispWinRightOffset,
> >                           &p->vui.defDispWinBottomOffset) != 4;
> >      }
> > +    OPT("nr") p->noiseReduction = atoi(value);
> >      else
> >          return X265_PARAM_BAD_NAME;
> >  #undef OPT
> > @@ -986,6 +987,8 @@
> >      CHECK(param->rc.bitrate < 0,
> >            "Target bitrate can not be less than zero");
> >      CHECK(param->bFrameBias < 0, "Bias towards B frame decisions must
> be 0 or greater");
> > +    if (param->noiseReduction)
> > +        CHECK(100 > param->noiseReduction || param->noiseReduction >
> 1000, "Valid noise reduction range 100 - 1000");
> >      return check_failed;
> >  }
> >
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/encoder/encoder.cpp
> > --- a/source/encoder/encoder.cpp        Sun May 18 15:02:27 2014 +0900
> > +++ b/source/encoder/encoder.cpp        Tue May 20 12:46:10 2014 +0530
> > @@ -64,6 +64,14 @@
> >      m_csvfpt = NULL;
> >      param = NULL;
> >
> > +    memset(m_nr.offsetDenoise, 0, sizeof(m_nr.offsetDenoise[0][0]) * 8
> * 1024);
> > +    memset(m_nr.residualSumBuf, 0, sizeof(m_nr.residualSumBuf[0][0][0])
> * 4 * 8 * 1024);
> > +    memset(m_nr.countBuf, 0, sizeof(m_nr.countBuf[0][0]) * 4 * 8);
> > +
> > +    m_nr.offset = m_nr.offsetDenoise;
> > +    m_nr.residualSum = m_nr.residualSumBuf[0];
> > +    m_nr.count = m_nr.countBuf[0];
> > +
> >  #if ENC_DEC_TRACE
> >      g_hTrace = fopen("TraceEnc.txt", "wb");
> >      g_bJustDoIt = g_bEncDecTraceDisable;
> > @@ -186,6 +194,7 @@
> >      }
> >      m_lookahead->init();
> >      m_encodeStartTime = x265_mdate();
> > +    m_nr.bNoiseReduction = !!param->noiseReduction;
> >  }
> >
> >  int Encoder::getStreamHeaders(NALUnitEBSP **nalunits)
> > @@ -218,6 +227,44 @@
> >      }
> >  }
> >
> >
> +/****************************************************************************
> > + * DCT-domain noise reduction / adaptive deadzone
> > + * from libavcodec
> > +
> ****************************************************************************/
> > +
> > +void Encoder::noiseReductionUpdate(NoiseReduction* h)
>
> naming this pointer `h` is probably an x264'ism we don't need to bring
> along from their code.  `nr` would be better.
>
> > +{
> > +    h->offset = h->offsetDenoise;
> > +    h->residualSum = h->residualSumBuf[0];
> > +    h->count = h->countBuf[0];
> > +
> > +    int transformSize[4] = {16, 64, 256, 1024};
> > +    uint32_t blockCount[4] = { 1 << 18, 1 << 16, 1 << 14, 1 << 12 };
> > +
> > +    int isCspI444 = (param->internalCsp == X265_CSP_I444) ? 1 : 0;
> > +    for (int cat = 0; cat < 7 + isCspI444; cat++)
> > +    {
> > +        int index = cat % 4;
> > +        int size = transformSize[index];
> > +
> > +        if (h->count[cat] > blockCount[index])
> > +        {
> > +            for (int i = 0; i < size; i++)
> > +                h->residualSum[cat][i] >>= 1;
> > +            h->count[cat] >>= 1;
> > +        }
> > +
> > +        for (int i = 0; i < size; i++)
> > +            h->offset[cat][i] =
> > +                (uint16_t)(((uint64_t)param->noiseReduction *
> h->count[cat]
> > +                 + h->residualSum[cat][i] / 2)
> > +              / ((uint64_t)h->residualSum[cat][i] + 1));
> > +
> > +        // Don't denoise DC coefficients
> > +        h->offset[cat][0] = 0;
> > +    }
>
> Now we get to the more serious problem; this function is not thread
> safe and it makes the encoder non-deterministic.
>
> In order to make the encoder deterministic, noiseReductionUpdate()
> cannot be run at the same time a worker thread might be reading the
> noise reduction structure.  So m_nr needs to be moved from the top
> level Encoder to the FrameEncoder class (based on the name of the
> parameter to the function, x264 did roughly the same thing).
> noiseReductionUpdate() would need to be called at the end of
> compressFrame().
>
> Note that even after moving the m_nr structure to the FrameEncoder,
> --nr will be the only option which will make the outputs diverge
> between -FN and -FM (where N != M and N != 1 && M != 1), and this
> needs to be clearly documented in the --nr section of cli.txt and in
> the discussion of frame parallelism in threading.txt.
>
> > +}
> > +
> >  #define VERBOSE_RATE 0
> >  #if VERBOSE_RATE
> >  static const char* nalUnitTypeToString(NalUnitType type)
> > @@ -434,6 +481,9 @@
> >          m_rateControl->rateControlEnd(out, bits, &curEncoder->m_rce);
> >          finishFrameStats(out, curEncoder, bits);
> >
> > +        if (m_nr.bNoiseReduction)
> > +            noiseReductionUpdate(&m_nr);
> > +
> >          // Allow this frame to be recycled if no frame encoders are
> using it for reference
> >          ATOMIC_DEC(&out->m_countRefEncoders);
> >          m_dpb->recycleUnreferenced(m_freeList);
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/encoder/encoder.h
> > --- a/source/encoder/encoder.h  Sun May 18 15:02:27 2014 +0900
> > +++ b/source/encoder/encoder.h  Tue May 20 12:46:10 2014 +0530
> > @@ -194,6 +194,8 @@
> >      x265_nal*          m_nals;
> >      char*              m_packetData;
> >
> > +    NoiseReduction     m_nr;
> > +
> >      Encoder();
> >
> >      virtual ~Encoder();
> > @@ -227,6 +229,8 @@
> >
> >      void updateVbvPlan(RateControl* rc);
> >
> > +    void noiseReductionUpdate(NoiseReduction* nr);
> > +
> >  protected:
> >
> >      void finishFrameStats(TComPic* pic, FrameEncoder *curEncoder,
> uint64_t bits);
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/x265.cpp
> > --- a/source/x265.cpp   Sun May 18 15:02:27 2014 +0900
> > +++ b/source/x265.cpp   Tue May 20 12:46:10 2014 +0530
> > @@ -176,6 +176,7 @@
> >      { "qpfile",         required_argument, NULL, 0 },
> >      { "b-intra",              no_argument, NULL, 0 },
> >      { "no-b-intra",           no_argument, NULL, 0 },
> > +    { "nr",             required_argument, NULL, 0 },
> >      { 0, 0, 0, 0 }
> >  };
> >
> > @@ -414,6 +415,8 @@
> >      H0("\nReconstructed video options (debugging):\n");
> >      H0("-r/--recon <filename>            Reconstructed raw image YUV or
> Y4M output file name\n");
> >      H0("   --recon-depth <integer>       Bit-depth of reconstructed raw
> image file. Defaults to input bit depth, or 8 if Y4M\n");
> > +    H0("\nNoiseReduction option:\n");
> > +    H0("   --nr <integer>                An integer value in range of
> 100 to 1000, which denotes strength of noise reduction. Default
> disabled\n");
> >  #undef OPT
> >  #undef H0
> >      printf("\n\nFull documentation may be found at
> http://x265.readthedocs.org/en/default/cli.html\n");
> > diff -r b35a5d8f012b -r 5dd459c0b7a0 source/x265.h
> > --- a/source/x265.h     Sun May 18 15:02:27 2014 +0900
> > +++ b/source/x265.h     Tue May 20 12:46:10 2014 +0530
> > @@ -646,6 +646,10 @@
> >       * regardless of this setting. */
> >      int       bIntraInBFrames;
> >
> > +    /* An integer value in range of 100 to 1000, which denotes strength
> of noise
> > +     * reduction */
> > +    int       noiseReduction;
> > +
> >      /*== Rate Control ==*/
> >
> >      struct
>
> Lastly, the patch needs to increase X265_BUILD
>
> --
> Steve Borho
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
> ------------------------------
>
> End of x265-devel Digest, Vol 12, Issue 41
> ******************************************
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20140520/2d62b701/attachment-0001.html>


More information about the x265-devel mailing list