[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