>From d409be0b90ce91f8ffda343864636debd62ffe37 Mon Sep 17 00:00:00 2001 From: Kirithika <kirith...@multicorewareinc.com> Date: Thu, 5 Oct 2023 12:26:35 +0530 Subject: [PATCH] Fix quality drop with SBRC feature
--- source/encoder/encoder.cpp | 21 +++++++++++++++------ source/encoder/ratecontrol.cpp | 31 +++++++++++++++++++------------ source/x265.h | 2 ++ 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp index 8ec01bebe..1280ccc66 100644 --- a/source/encoder/encoder.cpp +++ b/source/encoder/encoder.cpp @@ -4402,16 +4402,25 @@ void Encoder::configure(x265_param *p) m_param->searchRange = m_param->hmeRange[2]; } - if (p->bEnableSBRC && p->bOpenGOP) + if (p->bEnableSBRC && (p->rc.rateControlMode != X265_RC_CRF || (p->rc.vbvBufferSize == 0 || p->rc.vbvMaxBitrate == 0))) { - x265_log(p, X265_LOG_WARNING, "Segment based RateControl requires closed gop structure. Enabling closed GOP.\n"); - p->bOpenGOP = 0; + x265_log(p, X265_LOG_WARNING, "SBRC can be enabled only with CRF+VBV mode. Disabling SBRC\n"); + p->bEnableSBRC = 0; } - if (p->bEnableSBRC && (p->keyframeMax != p->keyframeMin)) + if (p->bEnableSBRC) { - x265_log(p, X265_LOG_WARNING, "Segment based RateControl requires fixed gop length. Force set min-keyint equal to keyint.\n"); - p->keyframeMin = p->keyframeMax; + p->rc.ipFactor = p->rc.ipFactor * X265_IPRATIO_STRENGTH; + if (p->bOpenGOP) + { + x265_log(p, X265_LOG_WARNING, "Segment based RateControl requires closed gop structure. Enabling closed GOP.\n"); + p->bOpenGOP = 0; + } + if (p->keyframeMax != p->keyframeMin) + { + x265_log(p, X265_LOG_WARNING, "Segment based RateControl requires fixed gop length. Force set min-keyint equal to keyint.\n"); + p->keyframeMin = p->keyframeMax; + } } } diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp index 80f4ac3e9..099a03f0a 100644 --- a/source/encoder/ratecontrol.cpp +++ b/source/encoder/ratecontrol.cpp @@ -433,7 +433,7 @@ void RateControl::initVBV(const SPS& sps) bool RateControl::init(const SPS& sps) { - if (m_isVbv && (!m_initVbv || m_param->bEnableSBRC)) + if (m_isVbv && !m_initVbv) initVBV(sps); if (!m_param->bResetZoneConfig && (m_relativeComplexity == NULL)) @@ -480,7 +480,7 @@ bool RateControl::init(const SPS& sps) /* estimated ratio that produces a reasonable QP for the first I-frame */ m_cplxrSum = .01 * pow(7.0e5, m_qCompress) * pow(m_ncu, 0.5) * tuneCplxFactor; - m_wantedBitsWindow = (m_param->bEnableSBRC ? (m_bitrate * ( 1.0 / m_param->keyframeMax )) :m_bitrate * m_frameDuration); + m_wantedBitsWindow = m_bitrate * m_frameDuration; m_accumPNorm = .01; m_accumPQp = (m_param->rc.rateControlMode == X265_RC_CRF ? CRF_INIT_QP : ABR_INIT_QP_MIN) * m_accumPNorm; @@ -1823,8 +1823,7 @@ double RateControl::tuneAbrQScaleFromFeedback(double qScale) double abrBuffer = 2 * m_rateTolerance * m_bitrate; /* use framesDone instead of POC as poc count is not serial with bframes enabled */ double overflow = 1.0; - double duration = m_param->bEnableSBRC ? (1.0 / m_param->keyframeMax) : m_frameDuration; - double timeDone = (double)(m_framesDone - m_param->frameNumThreads + 1) * duration; + double timeDone = (double)(m_framesDone - m_param->frameNumThreads + 1) * m_frameDuration; double wantedBits = timeDone * m_bitrate; int64_t encodedBits = m_totalBits; if (m_param->totalFrames && m_param->totalFrames <= 2 * m_fps) @@ -1834,7 +1833,7 @@ double RateControl::tuneAbrQScaleFromFeedback(double qScale) } if (wantedBits > 0 && encodedBits > 0 && (!m_partialResidualFrames || - m_param->rc.bStrictCbr || m_isGrainEnabled || m_param->bEnableSBRC)) + m_param->rc.bStrictCbr || m_isGrainEnabled)) { abrBuffer *= X265_MAX(1, sqrt(timeDone)); overflow = x265_clip3(.5, 2.0, 1.0 + (encodedBits - wantedBits) / abrBuffer); @@ -1924,7 +1923,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce) m_sliderPos++; } - if (m_sliceType == B_SLICE) + if((!m_param->bEnableSBRC && m_sliceType == B_SLICE) || (m_param->bEnableSBRC && !IS_REFERENCED(curFrame))) { /* B-frames don't have independent rate control, but rather get the * average QP of the two adjacent P-frames + an offset */ @@ -2196,8 +2195,18 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce) if (m_param->rc.rateControlMode == X265_RC_CRF) { - if (!m_param->rc.bStatRead && m_param->bEnableSBRC) - checkAndResetCRF(rce); + if (m_param->bEnableSBRC) + { + double rfConstant = m_param->rc.rfConstant; + if (m_currentSatd < rce->movingAvgSum) + rfConstant += 2; + rfConstant = (rce->sliceType == I_SLICE ? rfConstant - m_ipOffset : + (rce->sliceType == B_SLICE ? rfConstant + m_pbOffset : rfConstant)); + double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0; + double qComp = (m_param->rc.cuTree && !m_param->rc.hevcAq) ? 0.99 : m_param->rc.qCompress; + m_rateFactorConstant = pow(m_currentSatd, 1.0 - qComp) / + x265_qp2qScale(rfConstant + mbtree_offset); + } q = getQScale(rce, m_rateFactorConstant); x265_zone* zone = getZone(); if (zone) @@ -2223,7 +2232,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce) } double tunedQScale = tuneAbrQScaleFromFeedback(initialQScale); overflow = tunedQScale / initialQScale; - q = (!m_partialResidualFrames || m_param->bEnableSBRC)? tunedQScale : initialQScale; + q = !m_partialResidualFrames ? tunedQScale : initialQScale; bool isEncodeEnd = (m_param->totalFrames && m_framesDone > 0.75 * m_param->totalFrames) ? 1 : 0; bool isEncodeBeg = m_framesDone < (int)(m_fps + 0.5); @@ -2420,8 +2429,6 @@ void RateControl::checkAndResetABR(RateControlEntry* rce, bool isFrameDone) m_shortTermCplxCount = 1; m_isAbrReset = true; m_lastAbrResetPoc = rce->poc; - if(m_param->bEnableSBRC) - rce->blurredComplexity = m_shortTermCplxSum / m_shortTermCplxCount; } } else if (m_isAbrReset && isFrameDone) @@ -3062,7 +3069,7 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* * Not perfectly accurate with B-refs, but good enough. */ m_cplxrSum += (bits * x265_qp2qScale(rce->qpaRc) / (rce->qRceq * fabs(m_param->rc.pbFactor))) - (rce->rowCplxrSum); } - m_wantedBitsWindow += (m_param->bEnableSBRC ? (m_bitrate * (1.0 / m_param->keyframeMax)) : m_frameDuration * m_bitrate); + m_wantedBitsWindow += m_frameDuration * m_bitrate; m_totalBits += bits - rce->rowTotalBits; m_encodedBits += actualBits; int pos = m_sliderPos - m_param->frameNumThreads; diff --git a/source/x265.h b/source/x265.h index fb1a5dca7..d2bee6e37 100644 --- a/source/x265.h +++ b/source/x265.h @@ -623,6 +623,8 @@ typedef enum #define X265_MAX_GOP_LENGTH 16 #define MAX_T_LAYERS 7 +#define X265_IPRATIO_STRENGTH 1.43 + typedef struct x265_cli_csp { int planes; -- 2.28.0.windows.1 *Thanks,* *Kirithika*
patch2-sbrc.diff
Description: Binary data
_______________________________________________ x265-devel mailing list x265-devel@videolan.org https://mailman.videolan.org/listinfo/x265-devel