pushed the patch to master branch On Thu, Jan 5, 2023 at 9:42 AM Kirithika Kalirathnam < [email protected]> wrote:
> Please find the updated version > > From 3f30f806b0e4235eb6ab805f23330a8311f086b6 Mon Sep 17 00:00:00 2001 > From: Kirithika <[email protected]> > Date: Fri, 9 Dec 2022 12:31:27 +0530 > Subject: [PATCH] Add support for Segment Based Rate Control > > 1.Configure segment length based on keyint > 2.Changes frame duration settings with SBRC 3.Reset RateControl (CRF/ABR) > at the segment beginning > --- > doc/reST/cli.rst | 3 +- > source/common/common.h | 2 - > source/encoder/encoder.cpp | 12 ++++ > source/encoder/ratecontrol.cpp | 108 +++++++++++++++++++-------------- > source/encoder/ratecontrol.h | 3 + > 5 files changed, 80 insertions(+), 48 deletions(-) > > diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst > index f40afc65c..f1d9fa36c 100755 > --- a/doc/reST/cli.rst > +++ b/doc/reST/cli.rst > @@ -1761,7 +1761,8 @@ Quality, rate control and rate distortion options > > .. option:: --sbrc --no-sbrc > > - To enable and disable segment based rate control. > + To enable and disable segment based rate control.Segment duration > depends on the > + keyframe interval specified.If unspecified,default keyframe interval > will be used. > Default: disabled. > > .. option:: --hevc-aq > diff --git a/source/common/common.h b/source/common/common.h > index 3d7fc1ebf..37c19ae72 100644 > --- a/source/common/common.h > +++ b/source/common/common.h > @@ -130,7 +130,6 @@ typedef uint64_t sum2_t; > typedef uint64_t pixel4; > typedef int64_t ssum2_t; > #define SHIFT_TO_BITPLANE 9 > -#define HISTOGRAM_BINS 1024 > #else > typedef uint8_t pixel; > typedef uint16_t sum_t; > @@ -138,7 +137,6 @@ typedef uint32_t sum2_t; > typedef uint32_t pixel4; > typedef int32_t ssum2_t; // Signed sum > #define SHIFT_TO_BITPLANE 7 > -#define HISTOGRAM_BINS 256 > #endif // if HIGH_BIT_DEPTH > > #if X265_DEPTH < 10 > diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp > index 64a4e231c..f20c9a266 100644 > --- a/source/encoder/encoder.cpp > +++ b/source/encoder/encoder.cpp > @@ -4396,6 +4396,18 @@ void Encoder::configure(x265_param *p) > if (m_param->searchRange != m_param->hmeRange[2]) > m_param->searchRange = m_param->hmeRange[2]; > } > + > + if (p->bEnableSBRC && p->bOpenGOP) > + { > + x265_log(p, X265_LOG_WARNING, "Segment based RateControl requires > closed gop structure. Enabling closed GOP.\n"); > + p->bOpenGOP = 0; > + } > + > + if (p->bEnableSBRC && (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; > + } > } > > void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, > const x265_picture* picIn, int paramBytes) > diff --git a/source/encoder/ratecontrol.cpp > b/source/encoder/ratecontrol.cpp > index 090d0a35f..162c9dd7b 100644 > --- a/source/encoder/ratecontrol.cpp > +++ b/source/encoder/ratecontrol.cpp > @@ -392,46 +392,48 @@ bool RateControl::initCUTreeSharedMem() > return true; > } > > -bool RateControl::init(const SPS& sps) > +void RateControl::initVBV(const SPS& sps) > { > - if (m_isVbv && !m_initVbv) > + /* We don't support changing the ABR bitrate right now, > + * so if the stream starts as CBR, keep it CBR. */ > + if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate / > m_fps)) > { > - /* We don't support changing the ABR bitrate right now, > - * so if the stream starts as CBR, keep it CBR. */ > - if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate / > m_fps)) > - { > - m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate / > m_fps); > - x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot > be smaller than one frame, using %d kbit\n", > - m_param->rc.vbvBufferSize); > - } > - int vbvBufferSize = m_param->rc.vbvBufferSize * 1000; > - int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000; > + m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate / > m_fps); > + x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot be > smaller than one frame, using %d kbit\n", > + m_param->rc.vbvBufferSize); > + } > + int vbvBufferSize = m_param->rc.vbvBufferSize * 1000; > + int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000; > > - if (m_param->bEmitHRDSEI && !m_param->decoderVbvMaxRate) > - { > - const HRDInfo* hrd = &sps.vuiParameters.hrdParameters; > - vbvBufferSize = hrd->cpbSizeValue << (hrd->cpbSizeScale + > CPB_SHIFT); > - vbvMaxBitrate = hrd->bitRateValue << (hrd->bitRateScale + > BR_SHIFT); > - } > - m_bufferRate = vbvMaxBitrate / m_fps; > - m_vbvMaxRate = vbvMaxBitrate; > - m_bufferSize = vbvBufferSize; > - m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize; > + if (m_param->bEmitHRDSEI && !m_param->decoderVbvMaxRate) > + { > + const HRDInfo* hrd = &sps.vuiParameters.hrdParameters; > + vbvBufferSize = hrd->cpbSizeValue << (hrd->cpbSizeScale + > CPB_SHIFT); > + vbvMaxBitrate = hrd->bitRateValue << (hrd->bitRateScale + > BR_SHIFT); > + } > + m_bufferRate = vbvMaxBitrate / m_fps; > + m_vbvMaxRate = vbvMaxBitrate; > + m_bufferSize = vbvBufferSize; > + m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize; > + > + if (m_param->rc.vbvBufferInit > 1.) > + m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, > m_param->rc.vbvBufferInit / m_param->rc.vbvBufferSize); > + if (m_param->vbvBufferEnd > 1.) > + m_param->vbvBufferEnd = x265_clip3(0.0, 1.0, > m_param->vbvBufferEnd / m_param->rc.vbvBufferSize); > + if (m_param->vbvEndFrameAdjust > 1.) > + m_param->vbvEndFrameAdjust = x265_clip3(0.0, 1.0, > m_param->vbvEndFrameAdjust); > + m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, > X265_MAX(m_param->rc.vbvBufferInit, m_bufferRate / m_bufferSize)); > + m_bufferFillFinal = m_bufferSize * m_param->rc.vbvBufferInit; > + m_bufferFillActual = m_bufferFillFinal; > + m_bufferExcess = 0; > + m_minBufferFill = m_param->minVbvFullness / 100; > + m_maxBufferFill = 1 - (m_param->maxVbvFullness / 100); > +} > > - if (m_param->rc.vbvBufferInit > 1.) > - m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, > m_param->rc.vbvBufferInit / m_param->rc.vbvBufferSize); > - if (m_param->vbvBufferEnd > 1.) > - m_param->vbvBufferEnd = x265_clip3(0.0, 1.0, > m_param->vbvBufferEnd / m_param->rc.vbvBufferSize); > - if (m_param->vbvEndFrameAdjust > 1.) > - m_param->vbvEndFrameAdjust = x265_clip3(0.0, 1.0, > m_param->vbvEndFrameAdjust); > - m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, > X265_MAX(m_param->rc.vbvBufferInit, m_bufferRate / m_bufferSize)); > - m_bufferFillFinal = m_bufferSize * m_param->rc.vbvBufferInit; > - m_bufferFillActual = m_bufferFillFinal; > - m_bufferExcess = 0; > - m_minBufferFill = m_param->minVbvFullness / 100; > - m_maxBufferFill = 1 - (m_param->maxVbvFullness / 100); > - m_initVbv = true; > - } > +bool RateControl::init(const SPS& sps) > +{ > + if (m_isVbv) > + initVBV(sps); > > if (!m_param->bResetZoneConfig && (m_relativeComplexity == NULL)) > { > @@ -477,7 +479,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_bitrate * m_frameDuration; > + m_wantedBitsWindow = (m_param->bEnableSBRC ? (m_bitrate * ( 1.0 / > m_param->keyframeMax )) :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; > > @@ -1819,7 +1821,8 @@ 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 timeDone = (double)(m_framesDone - m_param->frameNumThreads + > 1) * m_frameDuration; > + double duration = m_param->bEnableSBRC ? (1.0 / m_param->keyframeMax) > : m_frameDuration; > + double timeDone = (double)(m_framesDone - m_param->frameNumThreads + > 1) * duration; > double wantedBits = timeDone * m_bitrate; > int64_t encodedBits = m_totalBits; > if (m_param->totalFrames && m_param->totalFrames <= 2 * m_fps) > @@ -1829,7 +1832,7 @@ double RateControl::tuneAbrQScaleFromFeedback(double > qScale) > } > > if (wantedBits > 0 && encodedBits > 0 && (!m_partialResidualFrames || > - m_param->rc.bStrictCbr || m_isGrainEnabled)) > + m_param->rc.bStrictCbr || m_isGrainEnabled || > m_param->bEnableSBRC)) > { > abrBuffer *= X265_MAX(1, sqrt(timeDone)); > overflow = x265_clip3(.5, 2.0, 1.0 + (encodedBits - wantedBits) / > abrBuffer); > @@ -2191,6 +2194,8 @@ 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); > q = getQScale(rce, m_rateFactorConstant); > x265_zone* zone = getZone(); > if (zone) > @@ -2216,7 +2221,7 @@ double RateControl::rateEstimateQscale(Frame* > curFrame, RateControlEntry *rce) > } > double tunedQScale = > tuneAbrQScaleFromFeedback(initialQScale); > overflow = tunedQScale / initialQScale; > - q = !m_partialResidualFrames? tunedQScale : initialQScale; > + q = (!m_partialResidualFrames || m_param->bEnableSBRC)? > 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); > @@ -2385,15 +2390,27 @@ void > RateControl::rateControlUpdateStats(RateControlEntry* rce) > } > } > > + > +void RateControl::checkAndResetCRF(RateControlEntry* rce) > +{ > + if(rce->poc % m_param->keyframeMax == 0) > + { > + init(*m_curSlice->m_sps); > + m_shortTermCplxSum = rce->lastSatd / > (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION); > + m_shortTermCplxCount = 1; > + rce->blurredComplexity = m_shortTermCplxSum / > m_shortTermCplxCount; > + } > +} > + > void RateControl::checkAndResetABR(RateControlEntry* rce, bool > isFrameDone) > { > double abrBuffer = 2 * m_rateTolerance * m_bitrate; > > // Check if current Slice is a scene cut that follows low > detailed/blank frames > - if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut || > rce->isFadeEnd) > + if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut || > rce->isFadeEnd || (m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax > == 0))) > { > if (!m_isAbrReset && rce->movingAvgSum > 0 > - && (m_isPatternPresent || !m_param->bframes)) > + && (m_isPatternPresent || !m_param->bframes > ||(m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax == 0)))) > { > int pos = X265_MAX(m_sliderPos - m_param->frameNumThreads, 0); > int64_t shrtTermWantedBits = (int64_t) (X265_MIN(pos, > s_slidingWindowFrames) * m_bitrate * m_frameDuration); > @@ -2403,7 +2420,7 @@ void RateControl::checkAndResetABR(RateControlEntry* > rce, bool isFrameDone) > shrtTermTotalBitsSum += m_encodedBitsWindow[i]; > double underflow = (shrtTermTotalBitsSum - > shrtTermWantedBits) / abrBuffer; > const double epsilon = 0.0001f; > - if ((underflow < epsilon || rce->isFadeEnd) && !isFrameDone) > + if ((underflow < epsilon || rce->isFadeEnd || > (m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax == 0))) && > !isFrameDone) > { > init(*m_curSlice->m_sps); > // Reduce tune complexity factor for scenes that follow > blank frames > @@ -2413,6 +2430,7 @@ void RateControl::checkAndResetABR(RateControlEntry* > rce, bool isFrameDone) > m_shortTermCplxCount = 1; > m_isAbrReset = true; > m_lastAbrResetPoc = rce->poc; > + rce->blurredComplexity = m_shortTermCplxSum / > m_shortTermCplxCount; > } > } > else if (m_isAbrReset && isFrameDone) > @@ -2487,7 +2505,7 @@ double RateControl::clipQscale(Frame* curFrame, > RateControlEntry* rce, double q) > for (int j = 0; bufferFillCur >= 0 && iter ; j++) > { > int type = curFrame->m_lowres.plannedType[j]; > - if (type == X265_TYPE_AUTO || totalDuration >= 1.0) > + if (type == X265_TYPE_AUTO || totalDuration >= 1.0 || > (m_param->bEnableSBRC && type == X265_TYPE_IDR)) > break; > totalDuration += m_frameDuration; > double wantedFrameSize = m_vbvMaxRate * > m_frameDuration; > @@ -3053,7 +3071,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_frameDuration * m_bitrate; > + m_wantedBitsWindow += (m_param->bEnableSBRC ? (m_bitrate * (1.0 / > m_param->keyframeMax)) : m_frameDuration * m_bitrate); > m_totalBits += bits - rce->rowTotalBits; > m_encodedBits += actualBits; > int pos = m_sliderPos - m_param->frameNumThreads; > diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h > index e9fd0e182..9c2fe0ed6 100644 > --- a/source/encoder/ratecontrol.h > +++ b/source/encoder/ratecontrol.h > @@ -150,6 +150,7 @@ public: > int m_lastScenecutAwareIFrame; > double m_rateTolerance; > double m_frameDuration; /* current frame duration in seconds */ > + double m_frameDurInGOP; /* current frame duration when considered > as a segment */ > double m_bitrate; > double m_rateFactorConstant; > double m_bufferSize; > @@ -255,6 +256,7 @@ public: > RateControl(x265_param& p, Encoder *enc); > bool init(const SPS& sps); > void initHRD(SPS& sps); > + void initVBV(const SPS& sps); > void reconfigureRC(); > > void setFinalFrameCount(int count); > @@ -315,6 +317,7 @@ protected: > double tuneQScaleForGrain(double rcOverflow); > void splitdeltaPOC(char deltapoc[], RateControlEntry *rce); > void splitbUsed(char deltapoc[], RateControlEntry *rce); > + void checkAndResetCRF(RateControlEntry* rce); > }; > } > #endif // ifndef X265_RATECONTROL_H > -- > 2.28.0.windows.1 > > *Thanks,* > *Kirithika* > > > On Thu, Dec 29, 2022 at 9:59 PM Kirithika Kalirathnam < > [email protected]> wrote: > >> From 817342031263956fba544b1aac9f29e814bb1fdf Mon Sep 17 00:00:00 2001 >> From: Kirithika <[email protected]> >> Date: Fri, 9 Dec 2022 12:31:27 +0530 >> Subject: [PATCH] Add support for Segment Based Rate Control >> >> 1.Configure keyframe interval to be 2 seconds >> >> 2.Changes frame duration settings with SBRC 3.Reset RateControl (CRF/ABR) >> at the GOP beginning >> --- >> source/encoder/encoder.cpp | 10 +++ >> source/encoder/ratecontrol.cpp | 110 ++++++++++++++++++++------------- >> source/encoder/ratecontrol.h | 3 + >> 3 files changed, 79 insertions(+), 44 deletions(-) >> >> diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp >> index 64a4e231c..ad15b984a 100644 >> --- a/source/encoder/encoder.cpp >> +++ b/source/encoder/encoder.cpp >> @@ -4396,6 +4396,16 @@ void Encoder::configure(x265_param *p) >> if (m_param->searchRange != m_param->hmeRange[2]) >> m_param->searchRange = m_param->hmeRange[2]; >> } >> + >> + if (m_param->bEnableSBRC && p->bOpenGOP) >> + { >> + x265_log(p, X265_LOG_WARNING, "Segment based RateControl >> requires closed gop structure. Enabling closed GOP.\n"); >> + m_param->bOpenGOP = 0; >> + >> + //Configure GOP to 2s duration >> + p->keyframeMax = 2 * (m_param->fpsNum / m_param->fpsDenom); >> + p->keyframeMin = 2 * (m_param->fpsNum / m_param->fpsDenom); >> + } >> } >> >> void Encoder::readAnalysisFile(x265_analysis_data* analysis, int curPoc, >> const x265_picture* picIn, int paramBytes) >> diff --git a/source/encoder/ratecontrol.cpp >> b/source/encoder/ratecontrol.cpp >> index 32399eda6..1c29e4a00 100644 >> --- a/source/encoder/ratecontrol.cpp >> +++ b/source/encoder/ratecontrol.cpp >> @@ -392,45 +392,49 @@ bool RateControl::initCUTreeSharedMem() >> return true; >> } >> >> -bool RateControl::init(const SPS& sps) >> +void RateControl::initVBV(const SPS& sps) >> { >> - if (m_isVbv && !m_initVbv) >> + /* We don't support changing the ABR bitrate right now, >> + * so if the stream starts as CBR, keep it CBR. */ >> + if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate / >> m_fps)) >> { >> - /* We don't support changing the ABR bitrate right now, >> - * so if the stream starts as CBR, keep it CBR. */ >> - if (m_param->rc.vbvBufferSize < (int)(m_param->rc.vbvMaxBitrate >> / m_fps)) >> - { >> - m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate >> / m_fps); >> - x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot >> be smaller than one frame, using %d kbit\n", >> - m_param->rc.vbvBufferSize); >> - } >> - int vbvBufferSize = m_param->rc.vbvBufferSize * 1000; >> - int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000; >> + m_param->rc.vbvBufferSize = (int)(m_param->rc.vbvMaxBitrate / >> m_fps); >> + x265_log(m_param, X265_LOG_WARNING, "VBV buffer size cannot be >> smaller than one frame, using %d kbit\n", >> + m_param->rc.vbvBufferSize); >> + } >> + int vbvBufferSize = m_param->rc.vbvBufferSize * 1000; >> + int vbvMaxBitrate = m_param->rc.vbvMaxBitrate * 1000; >> >> - if (m_param->bEmitHRDSEI && !m_param->decoderVbvMaxRate) >> - { >> - const HRDInfo* hrd = &sps.vuiParameters.hrdParameters; >> - vbvBufferSize = hrd->cpbSizeValue << (hrd->cpbSizeScale + >> CPB_SHIFT); >> - vbvMaxBitrate = hrd->bitRateValue << (hrd->bitRateScale + >> BR_SHIFT); >> - } >> - m_bufferRate = vbvMaxBitrate / m_fps; >> - m_vbvMaxRate = vbvMaxBitrate; >> - m_bufferSize = vbvBufferSize; >> - m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize; >> + if (m_param->bEmitHRDSEI && !m_param->decoderVbvMaxRate) >> + { >> + const HRDInfo* hrd = &sps.vuiParameters.hrdParameters; >> + vbvBufferSize = hrd->cpbSizeValue << (hrd->cpbSizeScale + >> CPB_SHIFT); >> + vbvMaxBitrate = hrd->bitRateValue << (hrd->bitRateScale + >> BR_SHIFT); >> + } >> + m_bufferRate = vbvMaxBitrate / m_fps; >> + m_vbvMaxRate = vbvMaxBitrate; >> + m_bufferSize = vbvBufferSize; >> + m_singleFrameVbv = m_bufferRate * 1.1 > m_bufferSize; >> + >> + if (m_param->rc.vbvBufferInit > 1.) >> + m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, >> m_param->rc.vbvBufferInit / m_param->rc.vbvBufferSize); >> + if (m_param->vbvBufferEnd > 1.) >> + m_param->vbvBufferEnd = x265_clip3(0.0, 1.0, >> m_param->vbvBufferEnd / m_param->rc.vbvBufferSize); >> + if (m_param->vbvEndFrameAdjust > 1.) >> + m_param->vbvEndFrameAdjust = x265_clip3(0.0, 1.0, >> m_param->vbvEndFrameAdjust); >> + m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, >> X265_MAX(m_param->rc.vbvBufferInit, m_bufferRate / m_bufferSize)); >> + m_bufferFillFinal = m_bufferSize * m_param->rc.vbvBufferInit; >> + m_bufferFillActual = m_bufferFillFinal; >> + m_bufferExcess = 0; >> + m_minBufferFill = m_param->minVbvFullness / 100; >> + m_maxBufferFill = 1 - (m_param->maxVbvFullness / 100); >> +} >> >> - if (m_param->rc.vbvBufferInit > 1.) >> - m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, >> m_param->rc.vbvBufferInit / m_param->rc.vbvBufferSize); >> - if (m_param->vbvBufferEnd > 1.) >> - m_param->vbvBufferEnd = x265_clip3(0.0, 1.0, >> m_param->vbvBufferEnd / m_param->rc.vbvBufferSize); >> - if (m_param->vbvEndFrameAdjust > 1.) >> - m_param->vbvEndFrameAdjust = x265_clip3(0.0, 1.0, >> m_param->vbvEndFrameAdjust); >> - m_param->rc.vbvBufferInit = x265_clip3(0.0, 1.0, >> X265_MAX(m_param->rc.vbvBufferInit, m_bufferRate / m_bufferSize)); >> - m_bufferFillFinal = m_bufferSize * m_param->rc.vbvBufferInit; >> - m_bufferFillActual = m_bufferFillFinal; >> - m_bufferExcess = 0; >> - m_minBufferFill = m_param->minVbvFullness / 100; >> - m_maxBufferFill = 1 - (m_param->maxVbvFullness / 100); >> - m_initVbv = true; >> +bool RateControl::init(const SPS& sps) >> +{ >> + if (m_isVbv) >> + { >> + initVBV(sps); >> } >> >> if (!m_param->bResetZoneConfig && (m_relativeComplexity == NULL)) >> @@ -477,7 +481,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_bitrate * m_frameDuration; >> + m_wantedBitsWindow = (m_param->bEnableSBRC ? (m_bitrate * ( 1.0 / >> m_param->keyframeMax )) :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; >> >> @@ -1819,7 +1823,8 @@ 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 timeDone = (double)(m_framesDone - m_param->frameNumThreads + >> 1) * m_frameDuration; >> + double duration = m_param->bEnableSBRC ? (1.0 / >> m_param->keyframeMax) : m_frameDuration; >> + double timeDone = (double)(m_framesDone - m_param->frameNumThreads + >> 1) * duration; >> double wantedBits = timeDone * m_bitrate; >> int64_t encodedBits = m_totalBits; >> if (m_param->totalFrames && m_param->totalFrames <= 2 * m_fps) >> @@ -1829,7 +1834,7 @@ double >> RateControl::tuneAbrQScaleFromFeedback(double qScale) >> } >> >> if (wantedBits > 0 && encodedBits > 0 && (!m_partialResidualFrames >> || >> - m_param->rc.bStrictCbr || m_isGrainEnabled)) >> + m_param->rc.bStrictCbr || m_isGrainEnabled || >> m_param->bEnableSBRC)) >> { >> abrBuffer *= X265_MAX(1, sqrt(timeDone)); >> overflow = x265_clip3(.5, 2.0, 1.0 + (encodedBits - wantedBits) >> / abrBuffer); >> @@ -2191,6 +2196,10 @@ 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); >> + } >> q = getQScale(rce, m_rateFactorConstant); >> x265_zone* zone = getZone(); >> if (zone) >> @@ -2216,7 +2225,7 @@ double RateControl::rateEstimateQscale(Frame* >> curFrame, RateControlEntry *rce) >> } >> double tunedQScale = >> tuneAbrQScaleFromFeedback(initialQScale); >> overflow = tunedQScale / initialQScale; >> - q = !m_partialResidualFrames? tunedQScale : >> initialQScale; >> + q = (!m_partialResidualFrames || m_param->bEnableSBRC)? >> 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); >> @@ -2385,15 +2394,27 @@ void >> RateControl::rateControlUpdateStats(RateControlEntry* rce) >> } >> } >> >> + >> +void RateControl::checkAndResetCRF(RateControlEntry* rce) >> +{ >> + if(rce->poc % m_param->keyframeMax == 0) >> + { >> + init(*m_curSlice->m_sps); >> + m_shortTermCplxSum = rce->lastSatd / >> (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION); >> + m_shortTermCplxCount = 1; >> + rce->blurredComplexity = m_shortTermCplxSum / >> m_shortTermCplxCount; >> + } >> +} >> + >> void RateControl::checkAndResetABR(RateControlEntry* rce, bool >> isFrameDone) >> { >> double abrBuffer = 2 * m_rateTolerance * m_bitrate; >> >> // Check if current Slice is a scene cut that follows low >> detailed/blank frames >> - if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut || >> rce->isFadeEnd) >> + if (rce->lastSatd > 4 * rce->movingAvgSum || rce->scenecut || >> rce->isFadeEnd || (m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax >> == 0))) >> { >> if (!m_isAbrReset && rce->movingAvgSum > 0 >> - && (m_isPatternPresent || !m_param->bframes)) >> + && (m_isPatternPresent || !m_param->bframes >> ||(m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax == 0)))) >> { >> int pos = X265_MAX(m_sliderPos - m_param->frameNumThreads, >> 0); >> int64_t shrtTermWantedBits = (int64_t) (X265_MIN(pos, >> s_slidingWindowFrames) * m_bitrate * m_frameDuration); >> @@ -2403,7 +2424,7 @@ void >> RateControl::checkAndResetABR(RateControlEntry* rce, bool isFrameDone) >> shrtTermTotalBitsSum += m_encodedBitsWindow[i]; >> double underflow = (shrtTermTotalBitsSum - >> shrtTermWantedBits) / abrBuffer; >> const double epsilon = 0.0001f; >> - if ((underflow < epsilon || rce->isFadeEnd) && !isFrameDone) >> + if ((underflow < epsilon || rce->isFadeEnd || >> (m_param->bEnableSBRC && (rce->poc % m_param->keyframeMax == 0))) && >> !isFrameDone) >> { >> init(*m_curSlice->m_sps); >> // Reduce tune complexity factor for scenes that follow >> blank frames >> @@ -2413,6 +2434,7 @@ void >> RateControl::checkAndResetABR(RateControlEntry* rce, bool isFrameDone) >> m_shortTermCplxCount = 1; >> m_isAbrReset = true; >> m_lastAbrResetPoc = rce->poc; >> + rce->blurredComplexity = m_shortTermCplxSum / >> m_shortTermCplxCount; >> } >> } >> else if (m_isAbrReset && isFrameDone) >> @@ -2487,7 +2509,7 @@ double RateControl::clipQscale(Frame* curFrame, >> RateControlEntry* rce, double q) >> for (int j = 0; bufferFillCur >= 0 && iter ; j++) >> { >> int type = curFrame->m_lowres.plannedType[j]; >> - if (type == X265_TYPE_AUTO || totalDuration >= 1.0) >> + if (type == X265_TYPE_AUTO || totalDuration >= 1.0 >> || (m_param->bEnableSBRC && type == X265_TYPE_IDR)) >> break; >> totalDuration += m_frameDuration; >> double wantedFrameSize = m_vbvMaxRate * >> m_frameDuration; >> @@ -3053,7 +3075,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_frameDuration * m_bitrate; >> + m_wantedBitsWindow += (m_param->bEnableSBRC ? (m_bitrate * (1.0 >> / m_param->keyframeMax)) : m_frameDuration * m_bitrate); >> m_totalBits += bits - rce->rowTotalBits; >> m_encodedBits += actualBits; >> int pos = m_sliderPos - m_param->frameNumThreads; >> diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h >> index e9fd0e182..9c2fe0ed6 100644 >> --- a/source/encoder/ratecontrol.h >> +++ b/source/encoder/ratecontrol.h >> @@ -150,6 +150,7 @@ public: >> int m_lastScenecutAwareIFrame; >> double m_rateTolerance; >> double m_frameDuration; /* current frame duration in seconds */ >> + double m_frameDurInGOP; /* current frame duration when >> considered as a segment */ >> double m_bitrate; >> double m_rateFactorConstant; >> double m_bufferSize; >> @@ -255,6 +256,7 @@ public: >> RateControl(x265_param& p, Encoder *enc); >> bool init(const SPS& sps); >> void initHRD(SPS& sps); >> + void initVBV(const SPS& sps); >> void reconfigureRC(); >> >> void setFinalFrameCount(int count); >> @@ -315,6 +317,7 @@ protected: >> double tuneQScaleForGrain(double rcOverflow); >> void splitdeltaPOC(char deltapoc[], RateControlEntry *rce); >> void splitbUsed(char deltapoc[], RateControlEntry *rce); >> + void checkAndResetCRF(RateControlEntry* rce); >> }; >> } >> #endif // ifndef X265_RATECONTROL_H >> -- >> 2.28.0.windows.1 >> >> *Thanks,* >> *Kirithika* >> > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
