[x265] [PATCH] noise reduction, ported from x264
praveen at multicorewareinc.com
praveen at multicorewareinc.com
Mon May 19 13:51:38 CEST 2014
# HG changeset patch
# User Praveen Tiwari
# Date 1400500268 -19800
# Node ID 58f440b7172fedf630a329d698cdfb6d9a337c49
# Parent c78bed701db4f1b412f6d1bf661e289049b0e6e8
noise reduction, ported from x264
diff -r c78bed701db4 -r 58f440b7172f doc/reST/cli.rst
--- a/doc/reST/cli.rst Mon May 19 00:56:18 2014 -0500
+++ b/doc/reST/cli.rst Mon May 19 17:21:08 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**
.. option:: --input-res <wxh>
diff -r c78bed701db4 -r 58f440b7172f source/Lib/TLibCommon/TComRom.h
--- a/source/Lib/TLibCommon/TComRom.h Mon May 19 00:56:18 2014 -0500
+++ b/source/Lib/TLibCommon/TComRom.h Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/Lib/TLibCommon/TComTrQuant.cpp
--- a/source/Lib/TLibCommon/TComTrQuant.cpp Mon May 19 00:56:18 2014 -0500
+++ b/source/Lib/TLibCommon/TComTrQuant.cpp Mon May 19 17:21:08 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,30 @@
// 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 == 1)
+ {
+ denoiseDct(m_tmpCoeff, nr->residualSum[0], nr->offset[0], 16);
+ nr->count[0]++;
+ }
+ else if (index == 2)
+ {
+ denoiseDct(m_tmpCoeff, nr->residualSum[1], nr->offset[1], 64);
+ nr->count[1]++;
+ }
+ else if (index == 3)
+ {
+ denoiseDct(m_tmpCoeff, nr->residualSum[2], nr->offset[2], 256);
+ nr->count[2]++;
+ }
+ else if (index == 4)
+ {
+ denoiseDct(m_tmpCoeff, nr->residualSum[3], nr->offset[3], 1024);
+ nr->count[3]++;
+ }
+ }
}
return xQuant(cu, m_tmpCoeff, coeff, trSize, ttype, absPartIdx, lastPos, curUseRDOQ);
}
diff -r c78bed701db4 -r 58f440b7172f source/Lib/TLibCommon/TComTrQuant.h
--- a/source/Lib/TLibCommon/TComTrQuant.h Mon May 19 00:56:18 2014 -0500
+++ b/source/Lib/TLibCommon/TComTrQuant.h Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/Lib/TLibEncoder/TEncSearch.cpp
--- a/source/Lib/TLibEncoder/TEncSearch.cpp Mon May 19 00:56:18 2014 -0500
+++ b/source/Lib/TLibEncoder/TEncSearch.cpp Mon May 19 17:21:08 2014 +0530
@@ -447,7 +447,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);
@@ -571,7 +571,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);
@@ -884,7 +884,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);
@@ -1479,7 +1479,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);
@@ -2891,7 +2891,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);
@@ -2935,12 +2935,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);
@@ -3108,7 +3108,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);
@@ -3145,12 +3145,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);
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);
@@ -3438,7 +3438,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 != 0)
@@ -3531,11 +3531,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 c78bed701db4 -r 58f440b7172f source/common/common.h
--- a/source/common/common.h Mon May 19 00:56:18 2014 -0500
+++ b/source/common/common.h Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/common/param.cpp
--- a/source/common/param.cpp Mon May 19 00:56:18 2014 -0500
+++ b/source/common/param.cpp Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Mon May 19 00:56:18 2014 -0500
+++ b/source/encoder/encoder.cpp Mon May 19 17:21:08 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)
+{
+ h->offset = h->offsetDenoise;
+ h->residualSum = h->residualSumBuf[0];
+ h->count = h->countBuf[0];
+
+ int transformSize[4] = {16, 64, 256, 1024};
+ int 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] =
+ ((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;
+ }
+}
+
#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 c78bed701db4 -r 58f440b7172f source/encoder/encoder.h
--- a/source/encoder/encoder.h Mon May 19 00:56:18 2014 -0500
+++ b/source/encoder/encoder.h Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/x265.cpp
--- a/source/x265.cpp Mon May 19 00:56:18 2014 -0500
+++ b/source/x265.cpp Mon May 19 17:21:08 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 c78bed701db4 -r 58f440b7172f source/x265.h
--- a/source/x265.h Mon May 19 00:56:18 2014 -0500
+++ b/source/x265.h Mon May 19 17:21:08 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
More information about the x265-devel
mailing list