[x265] [PATCH] Relax frame level bitrate constraints with frame-rc feature
Kirithika Kalirathnam
kirithika at multicorewareinc.com
Thu Mar 6 09:23:02 UTC 2025
>From bd0a7bb60ede41680f6217bf32f05805db779b2f Mon Sep 17 00:00:00 2001
From: Kirithika <kirithika at multicorewareinc.com>
Date: Fri, 29 Nov 2024 14:07:31 +0530
Subject: [PATCH] Relax frame level bitrate constraints with frame-rc feature
This patch relaxes the frame level bitrate constraints when frame-rc is enabled in bitrate mode
to improve quality
---
source/encoder/ratecontrol.cpp | 65 +++-------------------------------
source/encoder/ratecontrol.h | 1 -
2 files changed, 4 insertions(+), 62 deletions(-)
diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp
index b2db871ac..6749503b1 100644
--- a/source/encoder/ratecontrol.cpp
+++ b/source/encoder/ratecontrol.cpp
@@ -1863,14 +1863,10 @@ double RateControl::tuneAbrQScaleFromFeedback(double qScale)
}
if (wantedBits > 0 && encodedBits > 0 && (!m_partialResidualFrames ||
- m_param->rc.bStrictCbr || m_isGrainEnabled || (m_bRcReConfig && m_param->rc.rateControlMode == X265_RC_ABR)))
+ m_param->rc.bStrictCbr || m_isGrainEnabled))
{
abrBuffer *= X265_MAX(1, sqrt(timeDone));
overflow = x265_clip3(.5, 2.0, 1.0 + (encodedBits - wantedBits) / abrBuffer);
- if (m_bRcReConfig && overflow > 1.05)
- qScale *= m_lstep;
- if (m_bRcReConfig && overflow < 0.95)
- qScale /= m_lstep;
qScale *= overflow;
}
return qScale;
@@ -1920,7 +1916,6 @@ double RateControl::tuneQScaleForGrain(double rcOverflow)
double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
{
double q;
-
if (m_2pass)
{
if (m_sliceType != rce->sliceType)
@@ -2097,13 +2092,6 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
qScale = x265_clip3(lmin, lmax, qScale);
m_lastQScaleFor[m_sliceType] = qScale;
}
-
- if (m_bRcReConfig && m_param->rc.rateControlMode == X265_RC_ABR)
- {
- qScale = tuneQscaleToUpdatedBitrate(curFrame, qScale);
- rce->qpNoVbv = x265_qScale2qp(qScale);
- m_lastQScaleFor[m_sliceType] = qScale;
- }
}
if (m_2pass)
@@ -2299,7 +2287,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
}
double tunedQScale = tuneAbrQScaleFromFeedback(initialQScale);
overflow = tunedQScale / initialQScale;
- q = (!m_partialResidualFrames || m_bRcReConfig) ? 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);
@@ -2326,7 +2314,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
{
lqmin = m_lastQScaleFor[m_sliceType] / m_lstep;
lqmax = m_lastQScaleFor[m_sliceType] * m_lstep;
- if (!m_partialResidualFrames || m_isGrainEnabled || m_bRcReConfig)
+ if (!m_partialResidualFrames || m_isGrainEnabled)
{
if (overflow > 1.1 && m_framesDone > 3)
lqmax *= m_lstep;
@@ -2385,13 +2373,6 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)
rce->qpNoVbv = x265_qScale2qp(q);
}
q = clipQscale(curFrame, rce, q);
-
- if (m_bRcReConfig && m_param->rc.rateControlMode == X265_RC_ABR)
- {
- q = tuneQscaleToUpdatedBitrate(curFrame, q);
- rce->qpNoVbv = x265_qScale2qp(q);
- }
-
if (m_2pass)
rce->frameSizePlanned = qScale2bits(rce, q);
else
@@ -2582,43 +2563,6 @@ double RateControl::tuneQscaleForSBRC(Frame* curFrame, double q)
return q;
}
-double RateControl::tuneQscaleToUpdatedBitrate(Frame* curFrame, double q)
-{
- int depth = 18;
- if (m_isVbv && m_currentSatd > 0 && curFrame)
- {
- for (int iterations = 0; iterations < 100; iterations++)
- {
- int i;
- double frameBitsTotal = m_fps * predictSize(&m_pred[m_predType], q, (double)m_currentSatd);
- for (i = 0; i < depth; i++)
- {
- int type = curFrame->m_lowres.plannedType[i];
- if (type == X265_TYPE_AUTO)
- break;
- int64_t satd = curFrame->m_lowres.plannedSatd[i] >> (X265_DEPTH - 8);
- 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;
- int predType = getPredictorType(curFrame->m_lowres.plannedType[i], type);
- double curBits = m_fps * predictSize(&m_pred[predType], q, (double)satd);
- frameBitsTotal += curBits;
- }
- frameBitsTotal /= i;
- double allowedSize = (double)(curFrame->m_targetBitrate * 1000);
- if (frameBitsTotal >= 1.1 * allowedSize)
- q = q * 1.1;
- else if (frameBitsTotal >= 1.05 * allowedSize)
- q = q * 1.05;
- else if (frameBitsTotal <= 0.9 * allowedSize)
- q = q / 1.1;
- else if (frameBitsTotal <= 0.95 * allowedSize)
- q = q / 1.05;
- else
- break;
- }
- }
- return q;
-}
-
double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)
{
// B-frames are not directly subject to VBV,
@@ -2656,8 +2600,7 @@ double RateControl::clipQscale(Frame* curFrame, RateControlEntry* rce, double q)
if (type == X265_TYPE_AUTO || totalDuration >= 1.0)
break;
totalDuration += m_frameDuration;
- double wantedFrameSize = ((m_bRcReConfig && m_param->rc.rateControlMode == X265_RC_ABR) ?
- curFrame->m_targetBitrate * 1000 : m_vbvMaxRate) * m_frameDuration;
+ double wantedFrameSize = m_vbvMaxRate * m_frameDuration;
if (bufferFillCur + wantedFrameSize <= m_bufferSize)
bufferFillCur += wantedFrameSize;
int64_t satd = curFrame->m_lowres.plannedSatd[j] >> (X265_DEPTH - 8);
diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h
index 9a6b889b8..40e568d53 100644
--- a/source/encoder/ratecontrol.h
+++ b/source/encoder/ratecontrol.h
@@ -303,7 +303,6 @@ protected:
double tuneAbrQScaleFromFeedback(double qScale);
double tuneQScaleForZone(RateControlEntry *rce, double qScale); // Tune qScale to adhere to zone budget
double tuneQscaleForSBRC(Frame* curFrame, double q); // Tune qScale to adhere to segment budget
- double tuneQscaleToUpdatedBitrate(Frame* curFrame, double q); // Tune qScale according to updated bitrate
void accumPQpUpdate();
int getPredictorType(int lowresSliceType, int sliceType);
--
2.28.0.windows.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20250306/d5a5003f/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch-frame-rc.diff
Type: application/octet-stream
Size: 7252 bytes
Desc: patch-frame-rc.diff
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20250306/d5a5003f/attachment-0001.obj>
More information about the x265-devel
mailing list