<div dir="ltr"> Patch pushed to master branch.<font color="#888888"><font color="#888888"><br></font><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div></div></div></div></font><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>Karam Singh</div>Senior Software (Video Codec) Engineer<div>MulticoreWare, India</div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Mar 28, 2024 at 11:44 AM Kirithika Kalirathnam <<a href="mailto:kirithika@multicorewareinc.com">kirithika@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">From 17f2420bbd07db40b618e96a36586da909a26efb Mon Sep 17 00:00:00 2001<br>From: Kirithika <<a href="mailto:kirithika@multicorewareinc.com" target="_blank">kirithika@multicorewareinc.com</a>><br>Date: Sat, 3 Feb 2024 08:28:18 +0530<br>Subject: [PATCH] SBRC:Tune Qp based on segment size constraints<br><br>This Commit adds support to tune QP for frames based on the segment<br>size constraints<br>---<br> source/encoder/ratecontrol.cpp | 67 +++++++++++++++++++++++++++++++++-<br> source/encoder/ratecontrol.h | 3 ++<br> 2 files changed, 69 insertions(+), 1 deletion(-)<br><br>diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp<br>index 099a03f0a..5c447d8ad 100644<br>--- a/source/encoder/ratecontrol.cpp<br>+++ b/source/encoder/ratecontrol.cpp<br>@@ -260,6 +260,8 @@ RateControl::RateControl(x265_param& p, Encoder *top)<br> m_initVbv = false;<br> m_singleFrameVbv = 0;<br> m_rateTolerance = 1.0;<br>+ m_encodedSegmentBits = 0;<br>+ m_segDur = 0;<br> <br> if (m_param->rc.vbvBufferSize)<br> {<br>@@ -448,7 +450,9 @@ bool RateControl::init(const SPS& sps)<br> <br> m_totalBits = 0;<br> m_encodedBits = 0;<br>+ m_encodedSegmentBits = 0;<br> m_framesDone = 0;<br>+ m_segDur = 0;<br> m_residualCost = 0;<br> m_partialResidualCost = 0;<br> m_amortizeFraction = 0.85;<br>@@ -1351,6 +1355,16 @@ int RateControl::rateControlStart(Frame* curFrame, RateControlEntry* rce, Encode<br> m_predType = getPredictorType(curFrame->m_lowres.sliceType, m_sliceType);<br> rce->poc = m_curSlice->m_poc;<br> <br>+ if (m_param->bEnableSBRC)<br>+ {<br>+ if (rce->poc == 0 || (m_framesDone % m_param->keyframeMax == 0))<br>+ {<br>+ //Reset SBRC buffer<br>+ m_encodedSegmentBits = 0;<br>+ m_segDur = 0;<br>+ }<br>+ }<br>+<br> if (!m_param->bResetZoneConfig && (rce->encodeOrder % m_param->reconfigWindowSize == 0))<br> {<br> int index = m_zoneBufferIdx % m_param->rc.zonefileCount;<br>@@ -1974,8 +1988,16 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)<br> double minScenecutQscale =x265_qp2qScale(ABR_SCENECUT_INIT_QP_MIN); <br> m_lastQScaleFor[P_SLICE] = X265_MAX(minScenecutQscale, m_lastQScaleFor[P_SLICE]);<br> }<br>+<br> double qScale = x265_qp2qScale(q);<br> rce->qpNoVbv = q;<br>+<br>+ if (m_param->bEnableSBRC)<br>+ {<br>+ qScale = tuneQscaleForSBRC(curFrame, qScale);<br>+ rce->qpNoVbv = x265_qScale2qp(qScale);<br>+ }<br>+<br> double lmin = 0, lmax = 0;<br> if (m_isGrainEnabled && m_isFirstMiniGop)<br> {<br>@@ -2200,7 +2222,8 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)<br> double rfConstant = m_param->rc.rfConstant;<br> if (m_currentSatd < rce->movingAvgSum)<br> rfConstant += 2;<br>- rfConstant = (rce->sliceType == I_SLICE ? rfConstant - m_ipOffset :<br>+ double ipOffset = (curFrame->m_lowres.bScenecut ? m_ipOffset : m_ipOffset / 2.0);<br>+ rfConstant = (rce->sliceType == I_SLICE ? rfConstant - ipOffset :<br> (rce->sliceType == B_SLICE ? rfConstant + m_pbOffset : rfConstant));<br> double mbtree_offset = m_param->rc.cuTree ? (1.0 - m_param->rc.qCompress) * 13.5 : 0;<br> double qComp = (m_param->rc.cuTree && !m_param->rc.hevcAq) ? 0.99 : m_param->rc.qCompress;<br>@@ -2288,6 +2311,9 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)<br> q = X265_MAX(minScenecutQscale, q);<br> m_lastQScaleFor[P_SLICE] = X265_MAX(minScenecutQscale, m_lastQScaleFor[P_SLICE]);<br> }<br>+ if (m_param->bEnableSBRC)<br>+ q = tuneQscaleForSBRC(curFrame, q);<br>+<br> rce->qpNoVbv = x265_qScale2qp(q);<br> if (m_sliceType == P_SLICE)<br> {<br>@@ -2469,6 +2495,43 @@ double RateControl::predictSize(Predictor *p, double q, double var)<br> return (p->coeff * var + p->offset) / (q * p->count);<br> }<br> <br>+double RateControl::tuneQscaleForSBRC(Frame* curFrame, double q)<br>+{<br>+ int depth = 0;<br>+ int framesDoneInSeg = m_framesDone % m_param->keyframeMax;<br>+ if (framesDoneInSeg + m_param->lookaheadDepth <= m_param->keyframeMax)<br>+ depth = m_param->lookaheadDepth;<br>+ else<br>+ depth = m_param->keyframeMax - framesDoneInSeg;<br>+ for (int iterations = 0; iterations < 1000; iterations++)<br>+ {<br>+ double totalDuration = m_segDur;<br>+ double frameBitsTotal = m_encodedSegmentBits + predictSize(&m_pred[m_predType], q, (double)m_currentSatd);<br>+ for (int i = 0; i < depth; i++)<br>+ {<br>+ int type = curFrame->m_lowres.plannedType[i];<br>+ if (type == X265_TYPE_AUTO)<br>+ break;<br>+ int64_t satd = curFrame->m_lowres.plannedSatd[i] >> (X265_DEPTH - 8);<br>+ type = IS_X265_TYPE_I(curFrame->m_lowres.plannedType[i]) ? I_SLICE : IS_X265_TYPE_B(curFrame->m_lowres.plannedType[i]) ? B_SLICE : P_SLICE;<br>+ int predType = getPredictorType(curFrame->m_lowres.plannedType[i], type);<br>+ double curBits = predictSize(&m_pred[predType], q, (double)satd);<br>+ frameBitsTotal += curBits;<br>+ totalDuration += m_frameDuration;<br>+ }<br>+ //Check for segment buffer overflow and adjust QP accordingly<br>+ double segDur = m_param->keyframeMax / m_fps;<br>+ double allowedSize = m_vbvMaxRate * segDur;<br>+ double remDur = segDur - totalDuration;<br>+ double remainingBits = frameBitsTotal / totalDuration * remDur;<br>+ if (frameBitsTotal + remainingBits > 0.9 * allowedSize)<br>+ q = q * 1.01;<br>+ else<br>+ break;<br>+ }<br>+ return q;<br>+}<br>+<br> double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)<br> {<br> // B-frames are not directly subject to VBV,<br>@@ -3072,6 +3135,8 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry*<br> m_wantedBitsWindow += m_frameDuration * m_bitrate;<br> m_totalBits += bits - rce->rowTotalBits;<br> m_encodedBits += actualBits;<br>+ m_encodedSegmentBits += actualBits;<br>+ m_segDur += m_frameDuration;<br> int pos = m_sliderPos - m_param->frameNumThreads;<br> if (pos >= 0)<br> m_encodedBitsWindow[pos % s_slidingWindowFrames] = actualBits;<br>diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h<br>index 7c3f60cc7..c3dc0406f 100644<br>--- a/source/encoder/ratecontrol.h<br>+++ b/source/encoder/ratecontrol.h<br>@@ -191,6 +191,8 @@ public:<br> double m_qCompress;<br> int64_t m_totalBits; /* total bits used for already encoded frames (after ammortization) */<br> int64_t m_encodedBits; /* bits used for encoded frames (without ammortization) */<br>+ int64_t m_encodedSegmentBits; /* bits used for encoded frames in a segment*/<br>+ double m_segDur;<br> double m_fps;<br> int64_t m_satdCostWindow[50];<br> int64_t m_encodedBitsWindow[50];<br>@@ -296,6 +298,7 @@ protected:<br> double rateEstimateQscale(Frame* pic, RateControlEntry *rce); // main logic for calculating QP based on ABR<br> double tuneAbrQScaleFromFeedback(double qScale);<br> double tuneQScaleForZone(RateControlEntry *rce, double qScale); // Tune qScale to adhere to zone budget<br>+ double tuneQscaleForSBRC(Frame* curFrame, double q); // Tune qScale to adhere to segment budget<br> void accumPQpUpdate();<br> <br> int getPredictorType(int lowresSliceType, int sliceType);<br>-- <br>2.28.0.windows.1<br><br><div><div dir="ltr" class="gmail_signature"><div dir="ltr"><i>Thanks,</i><div><i>Kirithika</i></div></div></div></div></div>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div>