[x265] [PATCH] Add filler bits when frame bits < vbv target in strict-cbr
aruna at multicorewareinc.com
aruna at multicorewareinc.com
Wed Jan 25 14:59:44 CET 2017
# HG changeset patch
# User Aruna Matheswaran <aruna at multicorewareinc.com>
# Date 1484888261 -19800
# Fri Jan 20 10:27:41 2017 +0530
# Node ID d1f6d9b8d6be1fb44d7d1dad7dd642c7ae95b226
# Parent 3737c70c3308c980259d60410c4231c74e892d23
Add filler bits when frame bits < vbv target in strict-cbr
diff -r 3737c70c3308 -r d1f6d9b8d6be source/common/common.h
--- a/source/common/common.h Fri Jan 20 16:44:03 2017 +0530
+++ b/source/common/common.h Fri Jan 20 10:27:41 2017 +0530
@@ -330,6 +330,10 @@
#define INTEGRAL_PLANE_NUM 12 // 12 integral planes for 32x32, 32x24, 32x8, 24x32, 16x16, 16x12, 16x4, 12x16, 8x32, 8x8, 4x16 and 4x4.
+#define NAL_TYPE_OVERHEAD 2
+#define START_CODE_OVERHEAD 3
+#define FILLER_OVERHEAD (NAL_TYPE_OVERHEAD + START_CODE_OVERHEAD + 1)
+
namespace X265_NS {
enum { SAO_NUM_OFFSET = 4 };
diff -r 3737c70c3308 -r d1f6d9b8d6be source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Fri Jan 20 16:44:03 2017 +0530
+++ b/source/encoder/frameencoder.cpp Fri Jan 20 10:27:41 2017 +0530
@@ -969,12 +969,29 @@
}
m_accessUnitBits = bytes << 3;
+ int filler = 0;
+ /* rateControlEnd may also block for earlier frames to call rateControlUpdateStats */
+ if (m_top->m_rateControl->rateControlEnd(m_frame, m_accessUnitBits, &m_rce, &filler) < 0)
+ m_top->m_aborted = true;
+
+ if (filler > 0)
+ {
+ filler = (filler - FILLER_OVERHEAD * 8) >> 3;
+ m_bs.resetBits();
+ while (filler > 0)
+ {
+ m_bs.write(0xff, 8);
+ filler--;
+ }
+ m_bs.writeByteAlignment();
+ m_nalList.serialize(NAL_UNIT_FILLER_DATA, m_bs);
+ bytes += m_nalList.m_nal[m_nalList.m_numNal - 1].sizeBytes;
+ bytes -= 3; //exclude start code prefix
+ m_accessUnitBits = bytes << 3;
+ }
+
m_endCompressTime = x265_mdate();
- /* rateControlEnd may also block for earlier frames to call rateControlUpdateStats */
- if (m_top->m_rateControl->rateControlEnd(m_frame, m_accessUnitBits, &m_rce) < 0)
- m_top->m_aborted = true;
-
/* Decrement referenced frame reference counts, allow them to be recycled */
for (int l = 0; l < numPredDir; l++)
{
diff -r 3737c70c3308 -r d1f6d9b8d6be source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Fri Jan 20 16:44:03 2017 +0530
+++ b/source/encoder/ratecontrol.cpp Fri Jan 20 10:27:41 2017 +0530
@@ -2479,14 +2479,16 @@
p->offset += new_offset;
}
-void RateControl::updateVbv(int64_t bits, RateControlEntry* rce)
+int RateControl::updateVbv(int64_t bits, RateControlEntry* rce)
{
int predType = rce->sliceType;
+ int filler = 0;
+ double bufferBits;
predType = rce->sliceType == B_SLICE && rce->keptAsRef ? 3 : predType;
if (rce->lastSatd >= m_ncu && rce->encodeOrder >= m_lastPredictorReset)
updatePredictor(&m_pred[predType], x265_qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);
if (!m_isVbv)
- return;
+ return 0;
m_bufferFillFinal -= bits;
@@ -2495,15 +2497,32 @@
m_bufferFillFinal = X265_MAX(m_bufferFillFinal, 0);
m_bufferFillFinal += m_bufferRate;
- m_bufferFillFinal = X265_MIN(m_bufferFillFinal, m_bufferSize);
- double bufferBits = X265_MIN(bits + m_bufferExcess, m_bufferRate);
- m_bufferExcess = X265_MAX(m_bufferExcess - bufferBits + bits, 0);
- m_bufferFillActual += bufferBits - bits;
- m_bufferFillActual = X265_MIN(m_bufferFillActual, m_bufferSize);
+
+ if (m_bufferFillFinal > m_bufferSize)
+ {
+ if (m_param->rc.bStrictCbr)
+ {
+ filler = (int)(m_bufferFillFinal - m_bufferSize);
+ filler += FILLER_OVERHEAD * 8;
+ m_bufferFillFinal -= filler;
+ bufferBits = X265_MIN(bits + filler + m_bufferExcess, m_bufferRate);
+ m_bufferExcess = X265_MAX(m_bufferExcess - bufferBits + bits + filler, 0);
+ m_bufferFillActual += bufferBits - bits - filler;
+ }
+ else
+ {
+ m_bufferFillFinal = X265_MIN(m_bufferFillFinal, m_bufferSize);
+ bufferBits = X265_MIN(bits + m_bufferExcess, m_bufferRate);
+ m_bufferExcess = X265_MAX(m_bufferExcess - bufferBits + bits, 0);
+ m_bufferFillActual += bufferBits - bits;
+ m_bufferFillActual = X265_MIN(m_bufferFillActual, m_bufferSize);
+ }
+ }
+ return filler;
}
/* After encoding one frame, update rate control state */
-int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* rce)
+int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* rce, int *filler)
{
int orderValue = m_startEndOrder.get();
int endOrdinal = (rce->encodeOrder + m_param->frameNumThreads) * 2 - 1;
@@ -2634,7 +2653,7 @@
if (m_isVbv)
{
- updateVbv(actualBits, rce);
+ *filler = updateVbv(actualBits, rce);
if (m_param->bEmitHRDSEI)
{
@@ -2656,9 +2675,9 @@
rce->hrdTiming->cpbInitialAT = hrd->cbrFlag ? m_prevCpbFinalAT : X265_MAX(m_prevCpbFinalAT, cpbEarliestAT);
}
-
+ int filler_bits = *filler ? (*filler - START_CODE_OVERHEAD * 8) : 0;
uint32_t cpbsizeUnscale = hrd->cpbSizeValue << (hrd->cpbSizeScale + CPB_SHIFT);
- rce->hrdTiming->cpbFinalAT = m_prevCpbFinalAT = rce->hrdTiming->cpbInitialAT + actualBits / cpbsizeUnscale;
+ rce->hrdTiming->cpbFinalAT = m_prevCpbFinalAT = rce->hrdTiming->cpbInitialAT + (actualBits + filler_bits)/ cpbsizeUnscale;
rce->hrdTiming->dpbOutputTime = (double)rce->picTimingSEI->m_picDpbOutputDelay * time->numUnitsInTick / time->timeScale + rce->hrdTiming->cpbRemovalTime;
}
}
diff -r 3737c70c3308 -r d1f6d9b8d6be source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Fri Jan 20 16:44:03 2017 +0530
+++ b/source/encoder/ratecontrol.h Fri Jan 20 10:27:41 2017 +0530
@@ -242,7 +242,7 @@
// to be called for each curFrame to process RateControl and set QP
int rateControlStart(Frame* curFrame, RateControlEntry* rce, Encoder* enc);
void rateControlUpdateStats(RateControlEntry* rce);
- int rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* rce);
+ int rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry* rce, int *filler);
int rowVbvRateControl(Frame* curFrame, uint32_t row, RateControlEntry* rce, double& qpVbv);
int rateControlSliceType(int frameNum);
bool cuTreeReadFor2Pass(Frame* curFrame);
@@ -269,7 +269,7 @@
void accumPQpUpdate();
int getPredictorType(int lowresSliceType, int sliceType);
- void updateVbv(int64_t bits, RateControlEntry* rce);
+ int updateVbv(int64_t bits, RateControlEntry* rce);
void updatePredictor(Predictor *p, double q, double var, double bits);
double clipQscale(Frame* pic, RateControlEntry* rce, double q);
void updateVbvPlan(Encoder* enc);
More information about the x265-devel
mailing list