<div dir="ltr"><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 0 of 6 ] introduce cu level vbv ratecontrol</div><div>
Message-Id: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:20 +0530</div>
<div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div><div><br></div><div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div>
<div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 1 of 6] vbv: Introduce states to hold row data for row level</div><div> VBV ratecontrol</div><div>X-Mercurial-Node: 39efc006d3efa89df765b3d62e810854b41fe401</div>
<div>Message-Id: <<a href="mailto:39efc006d3efa89df765.1392901341@Aarthi-PC.router186658.com">39efc006d3efa89df765.1392901341@Aarthi-PC.router186658.com</a>></div><div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:21 +0530</div>
<div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div><div><br></div><div># HG changeset patch</div>
<div># User Aarthi Thirumalai</div><div># Date 1392895417 -19800</div><div># Thu Feb 20 16:53:37 2014 +0530</div><div># Node ID 39efc006d3efa89df765b3d62e810854b41fe401</div><div># Parent fec3cab870437c101b409425b6c2d6c403bd0efa</div>
<div>vbv: Introduce states to hold row data for row level VBV ratecontrol.</div><div><br></div><div>diff -r fec3cab87043 -r 39efc006d3ef source/Lib/TLibCommon/TComDataCU.cpp</div><div>--- a/source/Lib/TLibCommon/TComDataCU.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/Lib/TLibCommon/TComDataCU.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -99,6 +99,7 @@</div><div> m_mvpIdx[0] = NULL;</div><div> m_mvpIdx[1] = NULL;</div>
<div> m_chromaFormat = 0;</div><div>+ m_baseQp = 0;</div><div> }</div><div> </div><div> TComDataCU::~TComDataCU()</div><div>@@ -235,6 +236,7 @@</div><div> m_totalBits = 0;</div><div> m_numPartitions = pic->getNumPartInCU();</div>
<div> int qp = pic->m_lowres.invQscaleFactor ? pic->getCU(getAddr())->getQP(0) : m_slice->getSliceQp();</div><div>+ m_baseQp = pic->getCU(getAddr())->m_baseQp;</div><div> for (int i = 0; i < 4; i++)</div>
<div> {</div><div> m_avgCost[i] = 0;</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/Lib/TLibCommon/TComDataCU.h</div><div>--- a/source/Lib/TLibCommon/TComDataCU.h<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/Lib/TLibCommon/TComDataCU.h<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -179,6 +179,7 @@</div><div> uint64_t m_avgCost[4]; // stores the avg cost of CU's in frame for each depth</div>
<div> uint32_t m_count[4];</div><div> uint64_t m_sa8dCost;</div><div>+ double m_baseQp; //Qp of Cu set from RateControl/Vbv.</div><div> </div><div> // -------------------------------------------------------------------------------------------------------------------</div>
<div> // create / destroy / initialize / copy</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/Lib/TLibCommon/TComPic.cpp</div><div>--- a/source/Lib/TLibCommon/TComPic.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/Lib/TLibCommon/TComPic.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -56,6 +56,13 @@</div><div> , m_bUsedByCurr(false)</div><div> , m_bIsLongTerm(false)</div>
<div> , m_bCheckLTMSB(false)</div><div>+ , m_rowDiagQp(NULL)</div><div>+ , m_rowDiagQScale(NULL)</div><div>+ , m_rowDiagSatd(NULL)</div><div>+ , m_rowSatdForVbv(NULL)</div><div>+ , m_cuCostsForVbv(NULL)</div>
<div>+ , m_rowEncodedBits(NULL)</div><div>+ , m_numEncodedCusPerRow(NULL)</div><div> {</div><div> m_reconRowCount = 0;</div><div> m_countRefEncoders = 0;</div><div>@@ -69,6 +76,9 @@</div><div> m_ssimCnt = 0;</div>
<div> m_frameTime = 0.0;</div><div> m_elapsedCompressTime = 0.0;</div><div>+ m_qpaAq = 0;</div><div>+ m_qpaRc = 0;</div><div>+ m_avgQpRc = 0;</div><div> m_bChromaPlanesExtended = false;</div><div> }</div>
<div> </div><div>@@ -94,7 +104,46 @@</div><div> ok &= m_origPicYuv->create(cfg->param.sourceWidth, cfg->param.sourceHeight, cfg->param.internalCsp, g_maxCUWidth, g_maxCUHeight, g_maxCUDepth);</div><div>
ok &= m_reconPicYuv->create(cfg->param.sourceWidth, cfg->param.sourceHeight, cfg->param.internalCsp, g_maxCUWidth, g_maxCUHeight, g_maxCUDepth);</div><div> ok &= m_lowres.create(m_origPicYuv, cfg->param.bframes, &cfg->param.rc.aqMode);</div>
<div>+</div><div>+ if (ok && cfg->param.rc.vbvBufferSize > 0 && cfg->param.rc.vbvMaxBitrate > 0)</div><div>+ {</div><div>+ int numRows = m_picSym->getFrameHeightInCU();</div><div>
+ int numCols = m_picSym->getFrameWidthInCU();</div><div>+ CHECKED_MALLOC(m_rowDiagQp, double, numRows);</div><div>+ CHECKED_MALLOC(m_rowDiagQScale, double, numRows);</div><div>+ CHECKED_MALLOC(m_rowDiagSatd, uint32_t, numRows);</div>
<div>+ CHECKED_MALLOC(m_rowEncodedBits, uint32_t, numRows);</div><div>+ CHECKED_MALLOC(m_numEncodedCusPerRow, uint32_t, numRows);</div><div>+ CHECKED_MALLOC(m_rowSatdForVbv, uint32_t, numRows);</div><div>
+ CHECKED_MALLOC(m_cuCostsForVbv, uint32_t, numRows * numCols);</div><div>+ CHECKED_MALLOC(m_qpaRc, double, numRows);</div><div>+ CHECKED_MALLOC(m_qpaAq, int, numRows);</div><div>+ reInit(cfg);</div>
<div>+ }</div><div>+</div><div> return ok;</div><div>+</div><div>+fail :</div><div>+ ok = false;</div><div>+ return ok;</div><div>+}</div><div>+</div><div>+void TComPic::reInit(TEncCfg* cfg)</div><div>+{</div>
<div>+ if (cfg->param.rc.vbvBufferSize > 0 && cfg->param.rc.vbvMaxBitrate > 0)</div><div>+ {</div><div>+ int numRows = m_picSym->getFrameHeightInCU();</div><div>+ int numCols = m_picSym->getFrameWidthInCU();</div>
<div>+ memset(m_rowDiagQp, 0, numRows * sizeof(double));</div><div>+ memset(m_rowDiagQScale, 0, numRows * sizeof(double));</div><div>+ memset(m_rowDiagSatd, 0, numRows * sizeof(uint32_t));</div><div>+ memset(m_rowEncodedBits, 0, numRows * sizeof(uint32_t));</div>
<div>+ memset(m_numEncodedCusPerRow, 0, numRows * sizeof(uint32_t));</div><div>+ memset(m_rowSatdForVbv, 0, numRows * sizeof(uint32_t));</div><div>+ memset(m_cuCostsForVbv, 0, numRows * numCols * sizeof(uint32_t));</div>
<div>+ memset(m_qpaRc, 0, numRows * sizeof(double));</div><div>+ memset(m_qpaAq, 0, numRows * sizeof(uint32_t));</div><div>+ }</div><div> }</div><div> </div><div> void TComPic::destroy(int bframes)</div><div>
@@ -121,6 +170,16 @@</div><div> }</div><div> </div><div> m_lowres.destroy(bframes);</div><div>+</div><div>+ X265_FREE(m_rowDiagQp);</div><div>+ X265_FREE(m_rowDiagQScale);</div><div>+ X265_FREE(m_rowDiagSatd);</div>
<div>+ X265_FREE(m_rowEncodedBits);</div><div>+ X265_FREE(m_numEncodedCusPerRow);</div><div>+ X265_FREE(m_rowSatdForVbv);</div><div>+ X265_FREE(m_cuCostsForVbv);</div><div>+ X265_FREE(m_qpaAq);</div><div>+ X265_FREE(m_qpaRc);</div>
<div> }</div><div> </div><div> //! \}</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/Lib/TLibCommon/TComPic.h</div><div>--- a/source/Lib/TLibCommon/TComPic.h<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/Lib/TLibCommon/TComPic.h<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -104,6 +104,16 @@</div><div> uint32_t m_checksum[3];</div><div> </div><div>
bool m_bChromaPlanesExtended; // orig chroma planes motion extended for weightp analysis</div><div>+ double* m_rowDiagQp;</div><div>+ double* m_rowDiagQScale;</div><div>
+ uint32_t* m_rowDiagSatd;</div><div>+ uint32_t* m_rowEncodedBits;</div><div>+ uint32_t* m_numEncodedCusPerRow;</div><div>+ uint32_t* m_rowSatdForVbv;</div><div>
+ uint32_t* m_cuCostsForVbv;</div><div>+ int* m_qpaAq;</div><div>+ double* m_qpaRc;</div><div>+ double m_avgQpRc;</div><div> </div><div> TComPic();</div>
<div> virtual ~TComPic();</div><div>@@ -112,6 +122,8 @@</div><div> </div><div> virtual void destroy(int bframes);</div><div> </div><div>+ void reInit(TEncCfg* cfg);</div><div>+</div><div> bool getUsedByCurr() { return m_bUsedByCurr; }</div>
<div> </div><div> void setUsedByCurr(bool bUsed) { m_bUsedByCurr = bUsed; }</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/common/lowres.h</div><div>--- a/source/common/lowres.h<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/common/lowres.h<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -117,6 +117,7 @@</div><div> int intraMbs[X265_BFRAME_MAX + 2];</div><div> int32_t* intraCost;</div>
<div> int64_t satdCost;</div><div>+ uint16_t* lowresCostForRc;</div><div> uint16_t(*lowresCosts[X265_BFRAME_MAX + 2][X265_BFRAME_MAX + 2]);</div><div> int32_t* lowresMvCosts[2][X265_BFRAME_MAX + 1];</div>
<div> MV* lowresMvs[2][X265_BFRAME_MAX + 1];</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/encoder/encoder.cpp</div><div>--- a/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -280,6 +280,7 @@</div><div> </div><div> /* Copy input picture into a TComPic, send to lookahead */</div>
<div> pic->getSlice()->setPOC(++m_pocLast);</div><div>+ pic->reInit(this);</div><div> pic->getPicYuvOrg()->copyFromPicture(*pic_in, m_pad);</div><div> pic->m_userData = pic_in->userData;</div>
<div> pic->m_pts = pic_in->pts;</div><div>diff -r fec3cab87043 -r 39efc006d3ef source/encoder/encoder.h</div><div>--- a/source/encoder/encoder.h<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div>
<div>+++ b/source/encoder/encoder.h<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>@@ -84,7 +84,6 @@</div><div> Lookahead* m_lookahead;</div><div> FrameEncoder* m_frameEncoder;</div>
<div> DPB* m_dpb;</div><div>- RateControl* m_rateControl;</div><div> </div><div> /* frame parallelism */</div><div> int m_curEncoder;</div><div>@@ -145,6 +144,8 @@</div><div>
</div><div> void signalReconRowCompleted(int poc);</div><div> </div><div>+ RateControl* m_rateControl;</div><div>+</div><div> protected:</div><div> </div><div> // Returns total number of bits for encoded pic</div>
<div>diff -r fec3cab87043 -r 39efc006d3ef source/x265.h</div><div>--- a/source/x265.h<span class="" style="white-space:pre"> </span>Thu Feb 20 15:54:52 2014 +0530</div><div>+++ b/source/x265.h<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div>
<div>@@ -801,6 +801,8 @@</div><div> * across frames and assigns more bits to these CUs. Improves encode efficiency.</div><div> * Default: OFF (0) */</div><div> int cuTree;</div><div>+ /* In CRF mode, maximum CRF as caused by VBV */</div>
<div>+ double rfConstantMax;</div><div> } rc;</div><div> } x265_param;</div><div> </div><div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div>
<div>Subject: [PATCH 2 of 6] vbv: enable vbvLookahead for Keyframes;</div><div> accumulate frame rowSatds from lowres rowSatds</div><div>X-Mercurial-Node: 1c037c64274dce2f39db348967259d7d623c1b18</div><div>Message-Id: <<a href="mailto:1c037c64274dce2f39db.1392901342@Aarthi-PC.router186658.com">1c037c64274dce2f39db.1392901342@Aarthi-PC.router186658.com</a>></div>
<div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:22 +0530</div><div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div>
<div><br></div><div># HG changeset patch</div><div># User Aarthi Thirumalai</div><div># Date 1392896018 -19800</div><div># Thu Feb 20 17:03:38 2014 +0530</div><div># Node ID 1c037c64274dce2f39db348967259d7d623c1b18</div>
<div># Parent 39efc006d3efa89df765b3d62e810854b41fe401</div><div>vbv: enable vbvLookahead for Keyframes; accumulate frame rowSatds from lowres rowSatds.</div><div><br></div><div>diff -r 39efc006d3ef -r 1c037c64274d source/encoder/slicetype.cpp</div>
<div>--- a/source/encoder/slicetype.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 16:53:37 2014 +0530</div><div>+++ b/source/encoder/slicetype.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:03:38 2014 +0530</div>
<div>@@ -173,11 +173,39 @@</div><div> }</div><div> </div><div> if (cfg->param.rc.cuTree)</div><div>+ {</div><div> pic->m_lowres.satdCost = frameCostRecalculate(frames, p0, p1, b);</div><div>+ if (b && cfg->param.rc.vbvBufferSize)</div>
<div>+ frameCostRecalculate(frames,b, b, b);</div><div>+ }</div><div>+</div><div> else if (cfg->param.rc.aqMode)</div><div> pic->m_lowres.satdCost = pic->m_lowres.costEstAq[b - p0][p1 - b];</div>
<div> else</div><div> pic->m_lowres.satdCost = pic->m_lowres.costEst[b - p0][p1 - b];</div><div>+</div><div>+ if (cfg->param.rc.vbvBufferSize > 0 && cfg->param.rc.vbvMaxBitrate > 0)</div>
<div>+ {</div><div>+ pic->m_lowres.lowresCostForRc = pic->m_lowres.lowresCosts[b - p0][p1 - b];</div><div>+ uint32_t lowresRow = 0 , lowresCol = 0, lowresCuIdx = 0, sum = 0;</div><div>+ uint32_t scale = cfg->param.maxCUSize / (2 * X265_LOWRES_CU_SIZE);</div>
<div>+ uint32_t widthInLowresCu = (uint32_t)widthInCU, heightInLowresCu = (uint32_t)heightInCU;</div><div>+</div><div>+ for (uint32_t row = 0; row < pic->getFrameHeightInCU(); row++)</div><div>+ {</div>
<div>+ lowresRow = row * scale;</div><div>+ for (uint32_t cnt = 0 ; cnt < scale && lowresRow < heightInLowresCu; lowresRow++, cnt++)</div><div>+ {</div><div>+ sum = 0;</div>
<div>+ lowresCuIdx = lowresRow * widthInLowresCu ;</div><div>+ for (lowresCol = 0; lowresCol < widthInLowresCu; lowresCol++, lowresCuIdx++)</div><div>+ {</div><div>+ sum += pic->m_lowres.lowresCostForRc[lowresCuIdx];</div>
<div>+ }</div><div>+ pic->m_rowSatdForVbv[row] += sum;</div><div>+ }</div><div>+ }</div><div>+ }</div><div> return pic->m_lowres.satdCost;</div><div> }</div>
<div> </div><div>@@ -186,6 +214,7 @@</div><div> Lowres *frames[X265_LOOKAHEAD_MAX];</div><div> TComPic *list[X265_LOOKAHEAD_MAX];</div><div> TComPic *ipic = inputQueue.first();</div><div>+ bool isKeyFrameAnalyse = (cfg->param.rc.cuTree || (cfg->param.rc.vbvBufferSize && cfg->param.lookaheadDepth));</div>
<div> </div><div> if (!est.rows && ipic)</div><div> est.init(cfg, ipic);</div><div>@@ -371,6 +400,10 @@</div><div> outputQueue.pushBack(*list[i]);</div><div> }</div><div> }</div>
<div>+ if (isKeyFrameAnalyse && IS_X265_TYPE_I(lastNonB->sliceType))</div><div>+ {</div><div>+ slicetypeAnalyse(frames,true);</div><div>+ }</div><div> }</div><div> </div><div> void Lookahead::vbvLookahead(Lowres **frames, int numFrames, int keyframe)</div>
<div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 3 of 6] vbv: Add row predictors, rc states for vbv</div>
<div>X-Mercurial-Node: ebc23ec5ac1c5f8e2abe0d0b88414fabd2fdf1bb</div><div>Message-Id: <<a href="mailto:ebc23ec5ac1c5f8e2abe.1392901343@Aarthi-PC.router186658.com">ebc23ec5ac1c5f8e2abe.1392901343@Aarthi-PC.router186658.com</a>></div>
<div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:23 +0530</div><div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div>
<div><br></div><div># HG changeset patch</div><div># User Aarthi Thirumalai</div><div># Date 1392898673 -19800</div><div># Thu Feb 20 17:47:53 2014 +0530</div><div># Node ID ebc23ec5ac1c5f8e2abe0d0b88414fabd2fdf1bb</div>
<div># Parent 1c037c64274dce2f39db348967259d7d623c1b18</div><div>vbv: Add row predictors, rc states for vbv.</div><div><br></div><div>diff -r 1c037c64274d -r ebc23ec5ac1c source/encoder/encoder.cpp</div><div>--- a/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:03:38 2014 +0530</div>
<div>+++ b/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div><div>@@ -218,6 +218,7 @@</div><div> FrameEncoder *encoder = &m_frameEncoder[encIdx];</div>
<div> double bits;</div><div> bits = encoder->m_rce.frameSizePlanned;</div><div>+ bits = X265_MAX(bits, m_rateControl->frameSizeEstimated);</div><div> rc->bufferFill -= bits;</div><div>
rc->bufferFill = X265_MAX(rc->bufferFill, 0);</div><div> rc->bufferFill += encoder->m_rce.bufferRate;</div><div>diff -r 1c037c64274d -r ebc23ec5ac1c source/encoder/ratecontrol.cpp</div><div>--- a/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:03:38 2014 +0530</div>
<div>+++ b/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div><div>@@ -243,11 +243,12 @@</div><div> lastNonBPictType = I_SLICE;</div><div> isAbrReset = false;</div>
<div> lastAbrResetPoc = -1;</div><div>+ frameSizeEstimated = 0;</div><div> // vbv initialization</div><div> cfg->param.rc.vbvBufferSize = Clip3(0, 2000000, cfg->param.rc.vbvBufferSize);</div><div> cfg->param.rc.vbvMaxBitrate = Clip3(0, 2000000, cfg->param.rc.vbvMaxBitrate);</div>
<div> cfg->param.rc.vbvBufferInit = Clip3(0.0, 2000000.0, cfg->param.rc.vbvBufferInit);</div><div>-</div><div>+ vbvMinRate = 0;</div><div> if (cfg->param.rc.vbvBufferSize)</div><div> {</div><div> if (cfg->param.rc.rateControlMode == X265_RC_CQP)</div>
<div>@@ -318,6 +319,14 @@</div><div> pred[i].offset = 0.0;</div><div> }</div><div> </div><div>+ for (int i = 0; i < 4; i++)</div><div>+ {</div><div>+ rowPreds[i].coeff = 0.25;</div><div>+ rowPreds[i].count = 1.0;</div>
<div>+ rowPreds[i].decay = 0.5;</div><div>+ rowPreds[i].offset = 0.0;</div><div>+ }</div><div>+</div><div> predBfromP = pred[0];</div><div> bframes = cfg->param.bframes;</div><div> bframeBits = 0;</div>
<div>@@ -376,7 +385,11 @@</div><div> rce->poc = curSlice->getPOC();</div><div> </div><div> if (isVbv)</div><div>+ {</div><div>+ rowPred[0] = &rowPreds[sliceType];</div><div>+ rowPred[1] = &rowPreds[3];</div>
<div> updateVbvPlan(enc);</div><div>+ }</div><div> </div><div> if (isAbr) //ABR,CRF</div><div> {</div><div>@@ -385,9 +398,10 @@</div><div> rce->lastSatd = currentSatd; </div><div> double q = qScale2qp(rateEstimateQscale(pic, rce));</div>
<div> qp = Clip3(MIN_QP, MAX_MAX_QP, (int)(q + 0.5));</div><div>- rce->qpaRc = q;</div><div>+ rce->qpaRc = pic->m_avgQpRc = q;</div><div> /* copy value of lastRceq into thread local rce struct *to be used in RateControlEnd() */</div>
<div> rce->qRceq = lastRceq;</div><div>+ rce->qpNoVbv = qpNoVbv;</div><div> accumPQpUpdate();</div><div> }</div><div> else //CQP</div><div>@@ -399,7 +413,11 @@</div><div> }</div><div>
</div><div> if (sliceType != B_SLICE)</div><div>+ {</div><div> lastNonBPictType = sliceType;</div><div>+ leadingNoBSatd = currentSatd;</div><div>+ }</div><div>+ rce->leadingNoBSatd = leadingNoBSatd;</div>
<div> framesDone++;</div><div> /* set the final QP to slice structure */</div><div> curSlice->setSliceQp(qp);</div><div>@@ -462,9 +480,11 @@</div><div> else</div><div> q += pbOffset;</div>
<div> </div><div>- rce->frameSizePlanned = predictSize(&predBfromP, qp2qScale(q), leadingNoBSatd);</div><div>-</div><div>- return qp2qScale(q);</div><div>+ qpNoVbv = q;</div><div>+ double qScale = qp2qScale(qpNoVbv);</div>
<div>+ rce->frameSizePlanned = predictSize(&predBfromP, qScale, (double)leadingNoBSatd);</div><div>+ frameSizeEstimated = rce->frameSizePlanned;</div><div>+ return qScale;</div><div> }</div>
<div> else</div><div> {</div><div>@@ -555,7 +575,7 @@</div><div> if (qCompress != 1 && framesDone == 0)</div><div> q = qp2qScale(ABR_INIT_QP) / fabs(cfg->param.rc.ipFactor);</div>
<div> }</div><div>-</div><div>+ qpNoVbv = qScale2qp(q);</div><div> double lmin1 = lmin[sliceType];</div><div> double lmax1 = lmax[sliceType];</div><div> q = Clip3(lmin1, lmax1, q);</div>
<div>@@ -840,7 +860,7 @@</div><div> if (rce->bLastMiniGopBFrame)</div><div> {</div><div> if (rce->bframes != 0)</div><div>- updatePredictor(&predBfromP, qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bframeBits / rce->bframes);</div>
<div>+ updatePredictor(&predBfromP, qp2qScale(rce->qpaRc), (double)rce->leadingNoBSatd, (double)bframeBits / rce->bframes);</div><div> bframeBits = 0;</div><div> }</div>
<div> }</div><div>diff -r 1c037c64274d -r ebc23ec5ac1c source/encoder/ratecontrol.h</div><div>--- a/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 17:03:38 2014 +0530</div><div>
+++ b/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div><div>@@ -53,7 +53,7 @@</div><div> int mvBits;</div><div> int bframes;</div><div> int poc;</div>
<div>-</div><div>+ int64_t leadingNoBSatd;</div><div> bool bLastMiniGopBFrame;</div><div> double blurredComplexity;</div><div> double qpaRc;</div><div>@@ -61,6 +61,7 @@</div><div> double frameSizePlanned;</div>
<div> double bufferRate;</div><div> double movingAvgSum;</div><div>+ double qpNoVbv;</div><div> };</div><div> </div><div> struct Predictor</div><div>@@ -94,9 +95,10 @@</div><div> bool isVbv;</div><div> Predictor pred[5];</div>
<div> Predictor predBfromP;</div><div>+ Predictor rowPreds[4];</div><div>+ Predictor *rowPred[2];</div><div> int bframes;</div><div> int bframeBits;</div><div>- double leadingNoBSatd;</div><div> bool isAbrReset;</div>
<div> int lastAbrResetPoc;</div><div> int64_t currentSatd;</div><div>@@ -106,6 +108,7 @@</div><div> double ipOffset;</div><div> double pbOffset;</div><div> int lastNonBPictType;</div><div>+ int64_t leadingNoBSatd;</div>
<div> double accumPQp; /* for determining I-frame quant */</div><div> double accumPNorm;</div><div> double lastQScaleFor[3]; /* last qscale for a specific pict type, used for max_diff & ipb factor stuff */</div>
<div>@@ -118,6 +121,8 @@</div><div> double lastRceq;</div><div> int framesDone; /* framesDone keeps track of # of frames passed through RateCotrol already */</div><div> double qCompress;</div><div>+ double qpNoVbv; /* QP for the current frame if 1-pass VBV was disabled. */</div>
<div>+ double frameSizeEstimated; /* hold synched frameSize, updated from cu level vbv rc */</div><div> RateControl(TEncCfg * _cfg);</div><div> </div><div> // to be called for each frame to process RateControl and set QP</div>
<div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 4 of 6] vbv: fix bugs in vbv flow with single pass ABR</div>
<div>X-Mercurial-Node: c5c07a3ee7fcf0f331f06f83b7b3bc0b1bcc1668</div><div>Message-Id: <<a href="mailto:c5c07a3ee7fcf0f331f0.1392901344@Aarthi-PC.router186658.com">c5c07a3ee7fcf0f331f0.1392901344@Aarthi-PC.router186658.com</a>></div>
<div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:24 +0530</div><div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div>
<div><br></div><div># HG changeset patch</div><div># User Aarthi Thirumalai</div><div># Date 1392899993 -19800</div><div># Thu Feb 20 18:09:53 2014 +0530</div><div># Node ID c5c07a3ee7fcf0f331f06f83b7b3bc0b1bcc1668</div>
<div># Parent ebc23ec5ac1c5f8e2abe0d0b88414fabd2fdf1bb</div><div>vbv: fix bugs in vbv flow with single pass ABR</div><div><br></div><div>diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/encoder.cpp</div><div>--- a/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div>
<div>+++ b/source/encoder/encoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:09:53 2014 +0530</div><div>@@ -367,7 +367,7 @@</div><div> // Allow this frame to be recycled if no frame encoders are using it for reference</div>
<div> ATOMIC_DEC(&out->m_countRefEncoders);</div><div> </div><div>- m_rateControl->rateControlEnd(bits, &(curEncoder->m_rce));</div><div>+ m_rateControl->rateControlEnd(out, bits, &(curEncoder->m_rce));</div>
<div> </div><div> m_dpb->recycleUnreferenced(m_freeList);</div><div> </div><div>diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/ratecontrol.cpp</div><div>--- a/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div>
<div>+++ b/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:09:53 2014 +0530</div><div>@@ -207,7 +207,9 @@</div><div> RateControl::RateControl(TEncCfg * _cfg)</div><div> {</div><div>
this->cfg = _cfg;</div><div>- ncu = (int)((cfg->param.sourceHeight * cfg->param.sourceWidth) / pow((int)16, 2.0));</div><div>+ int lowresCuWidth = ((cfg->param.sourceWidth/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;</div>
<div>+ int lowresCuHeight = ((cfg->param.sourceHeight/2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;</div><div>+ ncu = lowresCuWidth * lowresCuHeight;</div><div> </div><div> if (cfg->param.rc.cuTree)</div>
<div> {</div><div>@@ -445,12 +447,12 @@</div><div> * average QP of the two adjacent P-frames + an offset */</div><div> TComSlice* prevRefSlice = curSlice->getRefPic(REF_PIC_LIST_0, 0)->getSlice();</div>
<div> TComSlice* nextRefSlice = curSlice->getRefPic(REF_PIC_LIST_1, 0)->getSlice();</div><div>+ double q0 = curSlice->getRefPic(REF_PIC_LIST_0, 0)->m_avgQpRc;</div><div>+ double q1 = curSlice->getRefPic(REF_PIC_LIST_1, 0)->m_avgQpRc;</div>
<div> bool i0 = prevRefSlice->getSliceType() == I_SLICE;</div><div> bool i1 = nextRefSlice->getSliceType() == I_SLICE;</div><div> int dt0 = abs(curSlice->getPOC() - prevRefSlice->getPOC());</div>
<div> int dt1 = abs(curSlice->getPOC() - nextRefSlice->getPOC());</div><div>- double q0 = prevRefSlice->m_avgQpRc;</div><div>- double q1 = nextRefSlice->m_avgQpRc;</div><div> </div><div> // Skip taking a reference frame before the Scenecut if ABR has been reset.</div>
<div> if (lastAbrResetPoc >= 0 && !isVbv)</div><div>@@ -522,7 +524,7 @@</div><div> {</div><div> if (!isVbv)</div><div> {</div><div>- checkAndResetABR(rce);</div>
<div>+ checkAndResetABR(pic, rce);</div><div> }</div><div> q = getQScale(rce, wantedBitsWindow / cplxrSum);</div><div> </div><div>@@ -552,23 +554,22 @@</div><div> if (cfg->param.rc.rateControlMode != X265_RC_CRF)</div>
<div> {</div><div> double lqmin = 0, lqmax = 0;</div><div>- if (totalBits == 0)</div><div>+ if (totalBits == 0 && !isVbv)</div><div> {</div><div> lqmin = qp2qScale(ABR_INIT_QP_MIN) / lstep;</div>
<div> lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;</div><div>+ q = Clip3(lqmin, lqmax, q);</div><div> }</div><div>- else</div><div>+ else if(totalBits > 0 || (isVbv && rce->poc > 0 ))</div>
<div> {</div><div> lqmin = lastQScaleFor[sliceType] / lstep;</div><div> lqmax = lastQScaleFor[sliceType] * lstep;</div><div>+ if (overflow > 1.1 && framesDone > 3)</div>
<div>+ lqmax *= lstep;</div><div>+ else if (overflow < 0.9)</div><div>+ lqmin /= lstep;</div><div>+ q = Clip3(lqmin, lqmax, q);</div><div> }</div>
<div>-</div><div>- if (overflow > 1.1 && framesDone > 3)</div><div>- lqmax *= lstep;</div><div>- else if (overflow < 0.9)</div><div>- lqmin /= lstep;</div>
<div>-</div><div>- q = Clip3(lqmin, lqmax, q);</div><div> }</div><div> else</div><div> {</div><div>@@ -593,7 +594,7 @@</div><div> }</div><div> }</div><div> </div><div>-void RateControl::checkAndResetABR(RateControlEntry* rce)</div>
<div>+void RateControl::checkAndResetABR(TComPic* pic, RateControlEntry* rce)</div><div> {</div><div> double abrBuffer = 2 * cfg->param.rc.rateTolerance * bitrate;</div><div> </div><div>@@ -604,7 +605,7 @@</div><div>
{</div><div> // Reset ABR if prev frames are blank to prevent further sudden overflows/ high bit rate spikes.</div><div> double underflow = 1.0 + (totalBits - wantedBitsWindow) / abrBuffer;</div>
<div>- if (underflow < 1 && curSlice->m_avgQpRc == 0)</div><div>+ if (underflow < 1 && pic->m_avgQpRc == 0)</div><div> {</div><div> totalBits = 0;</div>
<div> framesDone = 0;</div><div>@@ -659,9 +660,9 @@</div><div> double bufferFillCur = bufferFill - curBits;</div><div> double targetFill;</div><div> double totalDuration = 0;</div>
<div>- frameQ[0] = sliceType == I_SLICE ? q * cfg->param.rc.ipFactor : q;</div><div>- frameQ[1] = frameQ[0] * cfg->param.rc.pbFactor;</div><div>- frameQ[2] = frameQ[0] / cfg->param.rc.ipFactor;</div>
<div>+ frameQ[P_SLICE] = sliceType == I_SLICE ? q * cfg->param.rc.ipFactor : q;</div><div>+ frameQ[B_SLICE] = frameQ[P_SLICE] * cfg->param.rc.pbFactor;</div><div>+ frameQ[I_SLICE] = frameQ[P_SLICE] / cfg->param.rc.ipFactor;</div>
<div> </div><div> /* Loop over the planned future frames. */</div><div> for (int j = 0; bufferFillCur >= 0 && bufferFillCur <= bufferSize; j++)</div><div>@@ -807,9 +808,8 @@</div>
<div> </div><div> void RateControl::updateVbv(int64_t bits, RateControlEntry* rce)</div><div> {</div><div>- int mbCount = (int)((cfg->param.sourceHeight * cfg->param.sourceWidth) / pow((int)16, 2.0));</div><div> </div>
<div>- if (rce->lastSatd >= mbCount)</div><div>+ if (rce->lastSatd >= ncu)</div><div> updatePredictor(&pred[rce->sliceType], qp2qScale(rce->qpaRc), (double)rce->lastSatd, (double)bits);</div>
<div> </div><div> if (!isVbv)</div><div>@@ -826,17 +826,27 @@</div><div> }</div><div> </div><div> /* After encoding one frame, update rate control state */</div><div>-int RateControl::rateControlEnd(int64_t bits, RateControlEntry* rce)</div>
<div>+int RateControl::rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce)</div><div> {</div><div> if (isAbr)</div><div> {</div><div> if (!isVbv && cfg->param.rc.rateControlMode == X265_RC_ABR)</div>
<div> {</div><div>- checkAndResetABR(rce);</div><div>+ checkAndResetABR(pic, rce);</div><div> }</div><div> </div><div> if (!isAbrReset)</div><div> {</div><div>+ if (pic->m_qpaRc)</div>
<div>+ {</div><div>+ for (uint32_t i = 0; i < pic->getFrameHeightInCU(); i++)</div><div>+ {</div><div>+ pic->m_avgQpRc += pic->m_qpaRc[i];</div><div>
+ }</div><div>+ pic->m_avgQpRc /= (pic->getFrameHeightInCU() * pic->getFrameWidthInCU());</div><div>+ rce->qpaRc = pic->m_avgQpRc;</div><div>+ }</div>
<div>+</div><div> if (rce->sliceType != B_SLICE)</div><div> /* The factor 1.5 is to tune up the actual bits, otherwise the cplxrSum is scaled too low</div><div> * to improve short term compensation for next frame. */</div>
<div>diff -r ebc23ec5ac1c -r c5c07a3ee7fc source/encoder/ratecontrol.h</div><div>--- a/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 17:47:53 2014 +0530</div><div>+++ b/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 18:09:53 2014 +0530</div>
<div>@@ -128,7 +128,7 @@</div><div> // to be called for each frame to process RateControl and set QP</div><div> void rateControlStart(TComPic* pic, Lookahead *, RateControlEntry* rce, Encoder* enc);</div><div> void calcAdaptiveQuantFrame(TComPic *pic);</div>
<div>- int rateControlEnd(int64_t bits, RateControlEntry* rce);</div><div>+ int rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce);</div><div> </div><div> protected:</div><div> </div><div>@@ -142,7 +142,7 @@</div>
<div> double clipQscale(TComPic* pic, double q);</div><div> void updateVbvPlan(Encoder* enc);</div><div> double predictSize(Predictor *p, double q, double var);</div><div>- void checkAndResetABR(RateControlEntry* rce);</div>
<div>+ void checkAndResetABR(TComPic* pic, RateControlEntry* rce);</div><div> };</div><div> }</div><div> </div><div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div>
<div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 5 of 6] vbv: implement row wise vbvRateControl at each row</div><div> diagonal</div><div>X-Mercurial-Node: 49b90667f050a7dd9c28b5017f389f5c29a1c191</div><div>
Message-Id: <<a href="mailto:49b90667f050a7dd9c28.1392901345@Aarthi-PC.router186658.com">49b90667f050a7dd9c28.1392901345@Aarthi-PC.router186658.com</a>></div><div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:25 +0530</div>
<div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div><div><br></div><div># HG changeset patch</div>
<div># User Aarthi Thirumalai</div><div># Date 1392900828 -19800</div><div># Thu Feb 20 18:23:48 2014 +0530</div><div># Node ID 49b90667f050a7dd9c28b5017f389f5c29a1c191</div><div># Parent c5c07a3ee7fcf0f331f06f83b7b3bc0b1bcc1668</div>
<div>vbv: implement row wise vbvRateControl at each row diagonal.</div><div><br></div><div>diff -r c5c07a3ee7fc -r 49b90667f050 source/encoder/ratecontrol.cpp</div><div>--- a/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:09:53 2014 +0530</div>
<div>+++ b/source/encoder/ratecontrol.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:23:48 2014 +0530</div><div>@@ -221,6 +221,10 @@</div><div> </div><div> // validate for cfg->param.rc, maybe it is need to add a function like x265_parameters_valiate()</div>
<div> cfg->param.rc.rfConstant = Clip3((double)-QP_BD_OFFSET, (double)51, cfg->param.rc.rfConstant);</div><div>+ cfg->param.rc.rfConstantMax = Clip3((double)-QP_BD_OFFSET, (double)51, cfg->param.rc.rfConstantMax);</div>
<div>+ rateFactorMaxIncrement = 0;</div><div>+ vbvMinRate = 0;</div><div>+</div><div> if (cfg->param.rc.rateControlMode == X265_RC_CRF)</div><div> {</div><div> cfg->param.rc.qp = (int)cfg->param.rc.rfConstant + QP_BD_OFFSET;</div>
<div>@@ -230,6 +234,15 @@</div><div> double mbtree_offset = cfg->param.rc.cuTree ? (1.0 - cfg->param.rc.qCompress) * 13.5 : 0;</div><div> rateFactorConstant = pow(baseCplx, 1 - qCompress) /</div><div>
qp2qScale(cfg->param.rc.rfConstant + mbtree_offset + QP_BD_OFFSET);</div><div>+ if (cfg->param.rc.rfConstantMax)</div><div>+ {</div><div>+ rateFactorMaxIncrement = cfg->param.rc.rfConstantMax - cfg->param.rc.rfConstant;</div>
<div>+ if (rateFactorMaxIncrement <= 0)</div><div>+ {</div><div>+ x265_log(&cfg->param, X265_LOG_WARNING, "CRF max must be greater than CRF\n");</div><div>+ rateFactorMaxIncrement = 0;</div>
<div>+ }</div><div>+ }</div><div> }</div><div> </div><div> isAbr = cfg->param.rc.rateControlMode != X265_RC_CQP; // later add 2pass option</div><div>@@ -760,6 +773,181 @@</div><div> return Clip3(lmin1, lmax1, q);</div>
<div> }</div><div> </div><div>+ double RateControl::predictRowsSizeSum(TComPic* pic, double qpVbv, int32_t & encodedBitsSoFar)</div><div>+{</div><div>+ uint32_t rowSatdCostSoFar = 0 ,totalSatdBits = 0;</div><div>+ encodedBitsSoFar = 0;</div>
<div>+ double qScale = qp2qScale(qpVbv);</div><div>+ int sliceType = pic->getSlice()->getSliceType();</div><div>+ TComPic* refPic = pic->getSlice()->getRefPic(REF_PIC_LIST_0, 0);</div><div>+ int maxRows = pic->getPicSym()->getFrameHeightInCU();</div>
<div>+ for (int row = 0 ; row < maxRows; row++)</div><div>+ {</div><div>+ encodedBitsSoFar += pic->m_rowEncodedBits[row];</div><div>+ rowSatdCostSoFar = pic->m_rowDiagSatd[row];</div><div>+ uint32_t satdCostForPendingCus = pic->m_rowSatdForVbv[row] - rowSatdCostSoFar;</div>
<div>+ if (satdCostForPendingCus > 0)</div><div>+ {</div><div>+ double pred_s = predictSize(rowPred[0], qScale, satdCostForPendingCus);</div><div>+ uint32_t refRowSatdCost= 0 , refRowBits = 0;</div>
<div>+ double refQScale=0;</div><div>+</div><div>+ if (sliceType != I_SLICE)</div><div>+ {</div><div>+ for (uint32_t cuAddr = pic->m_numEncodedCusPerRow[row] + 1; cuAddr < pic->getPicSym()->getFrameWidthInCU() * (row + 1); cuAddr++)</div>
<div>+ {</div><div>+ refRowSatdCost += refPic->m_cuCostsForVbv[cuAddr];</div><div>+ refRowBits = refPic->getCU(cuAddr)->m_totalBits;</div><div>+ }</div>
<div>+ refQScale = row == maxRows - 1 ? refPic->m_rowDiagQScale[row] : refPic->m_rowDiagQScale[row + 1];</div><div>+ }</div><div>+ </div><div>+ if (sliceType == I_SLICE || qScale >= refQScale)</div>
<div>+ {</div><div>+ if (sliceType == P_SLICE</div><div>+ && refPic->getSlice()->getSliceType() == sliceType</div><div>+ && refQScale > 0</div>
<div>+ && refRowSatdCost > 0)</div><div>+ {</div><div>+ if (abs(int32_t(refRowSatdCost - satdCostForPendingCus)) < (int32_t)satdCostForPendingCus / 2)</div>
<div>+ {</div><div>+ double pred_t = refRowBits * satdCostForPendingCus / refRowSatdCost</div><div>+ * refQScale / qScale;</div><div>+ totalSatdBits += int32_t((pred_s + pred_t) * 0.5);</div>
<div>+ }</div><div>+ }</div><div>+</div><div>+ else</div><div>+ totalSatdBits += int32_t(pred_s);</div><div>+ }</div><div>+ else</div>
<div>+ {</div><div>+ /* Our QP is lower than the reference! */</div><div>+ double pred_intra = predictSize(rowPred[1], qScale, refRowSatdCost);</div><div>+ /* Sum: better to overestimate than underestimate by using only one of the two predictors. */</div>
<div>+ totalSatdBits += int32_t(pred_intra + pred_s);</div><div>+ }</div><div>+ }</div><div>+ }</div><div>+ return totalSatdBits + encodedBitsSoFar;</div><div>+ }</div><div>+</div><div>
+int RateControl::rowDiagonalVbvRateControl(TComPic* pic, uint32_t row, RateControlEntry* rce, double& qpVbv)</div><div>+{</div><div>+ fprintf(fp,"\n poc :%d , type : %d , slice Qp : %d , row : %d , startvbv : %f ", pic->getPOC(), rce->sliceType, pic->getSlice()->getSliceQp(), row, qpVbv);</div>
<div>+ if (rce->poc == 24)</div><div>+ {</div><div>+ int i=0; i++;</div><div>+ }</div><div>+ double qScaleVbv = qp2qScale(qpVbv);</div><div>+ pic->m_rowDiagQp[row] = qpVbv;</div><div>+ pic->m_rowDiagQScale[row] = qScaleVbv;</div>
<div>+ //TODO : check whther we gotto update prodictor using whole Row Satd or only satd of blocks upto the diagonal in row.</div><div>+ updatePredictor(rowPred[0], qScaleVbv, (double)pic->m_rowDiagSatd[row], (double)pic->m_rowEncodedBits[row]);</div>
<div>+ if (pic->getSlice()->getSliceType() == P_SLICE)</div><div>+ {</div><div>+ TComPic* refSlice = pic->getSlice()->getRefPic(REF_PIC_LIST_0, 0);</div><div>+ if (qpVbv < refSlice->m_rowDiagQp[row])</div>
<div>+ {</div><div>+ updatePredictor(rowPred[1], qScaleVbv, refSlice->m_rowDiagSatd[row], refSlice->m_rowEncodedBits[row]);</div><div>+ }</div><div>+ }</div><div>+</div><div>+ int canReencodeRow = 1;</div>
<div>+ /* tweak quality based on difference from predicted size */</div><div>+ double prevRowQp = qpVbv;</div><div>+ double qpAbsoluteMax = MAX_MAX_QP;</div><div>+ if (rateFactorMaxIncrement)</div><div>+ qpAbsoluteMax = X265_MIN(qpAbsoluteMax, rce->qpNoVbv + rateFactorMaxIncrement);</div>
<div>+ double qpMax = X265_MIN(prevRowQp + cfg->param.rc.qpStep, qpAbsoluteMax );</div><div>+ double qpMin = X265_MAX(prevRowQp - cfg->param.rc.qpStep, MIN_QP );</div><div>+ double stepSize = 0.5;</div><div>
+ double bufferLeftPlanned = bufferFill - rce->frameSizePlanned;</div><div>+ if (bufferLeftPlanned < 0 )</div><div>+ { int i=0; i ++;</div><div>+ }</div><div>+ double maxFrameError = X265_MAX(0.05, 1.0 / pic->getFrameHeightInCU());</div>
<div>+</div><div>+ if (row < pic->getPicSym()->getFrameHeightInCU() - 1)</div><div>+ {</div><div>+ /* B-frames shouldn't use lower QP than their reference frames. */</div><div>+ if (rce->sliceType == B_SLICE)</div>
<div>+ {</div><div>+ TComPic* refSlice1 = pic->getSlice()->getRefPic(REF_PIC_LIST_0, 0);</div><div>+ TComPic* refSlice2 = pic->getSlice()->getRefPic(REF_PIC_LIST_1, 0);</div><div>+ qpMin = X265_MAX(qpMin, X265_MAX(refSlice1->m_rowDiagQp[row], refSlice2->m_rowDiagQp[row]));</div>
<div>+ qpVbv = X265_MAX(qpVbv, qpMin);</div><div>+ }</div><div>+ /* More threads means we have to be more cautious in letting ratecontrol use up extra bits. */</div><div>+ double rcTol = bufferLeftPlanned / cfg->param.frameNumThreads * cfg->param.rc.rateTolerance;</div>
<div>+ int32_t encodedBitsSoFar = 0;</div><div>+ double b1 = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);</div><div>+</div><div>+ /* Don't increase the row QPs until a sufficent amount of the bits of the frame have been processed, in case a flat */</div>
<div>+ /* area at the top of the frame was measured inaccurately. */</div><div>+ if (encodedBitsSoFar < 0.05f * rce->frameSizePlanned)</div><div>+ qpMax = qpAbsoluteMax = prevRowQp;</div><div>
+</div><div>+ if (rce->sliceType != I_SLICE)</div><div>+ rcTol *= 0.5;</div><div>+</div><div>+ if (!vbvMinRate)</div><div>+ qpMin = X265_MAX(qpMin, rce->qpNoVbv);</div><div>+</div>
<div>+ while (qpVbv < qpMax</div><div>+ && ((b1 > rce->frameSizePlanned + rcTol) ||</div><div>+ (bufferFill - b1 < bufferLeftPlanned * 0.5) ||</div><div>+ (b1 > rce->frameSizePlanned && qpVbv < rce->qpNoVbv)))</div>
<div>+ {</div><div>+ qpVbv += stepSize;</div><div>+ b1 = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);</div><div>+ }</div><div>+ </div><div>+ while (qpVbv > qpMin</div>
<div>+ && (qpVbv > pic->m_rowDiagQp[0] || singleFrameVbv)</div><div>+ && ((b1 < rce->frameSizePlanned * 0.8f && qpVbv <= prevRowQp)</div><div>+ || b1 < (bufferFill - bufferSize + bufferRate) * 1.1))</div>
<div>+ {</div><div>+ qpVbv -= stepSize;</div><div>+ b1 = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);</div><div>+ } </div><div>+ /* avoid VBV underflow */</div><div>+ while ((qpVbv < qpAbsoluteMax)</div>
<div>+ && (bufferFill - b1 < bufferRate * maxFrameError))</div><div>+ {</div><div>+ qpVbv += stepSize;</div><div>+ b1 = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);</div>
<div>+ }</div><div>+ frameSizeEstimated = b1;</div><div>+</div><div>+ /* If the current row was large enough to cause a large QP jump, try re-encoding it. */</div><div>+ if (qpVbv > qpMax && prevRowQp < qpMax && canReencodeRow)</div>
<div>+ {</div><div>+ /* Bump QP to halfway in between... close enough. */</div><div>+ qpVbv = Clip3(prevRowQp + 1.0f, qpMax, (prevRowQp + qpVbv)*0.5);</div><div>+ fprintf(fp,", endvbv : %f ", qpVbv);</div>
<div>+ return -1;</div><div>+ }</div><div>+ }</div><div>+ else</div><div>+ {</div><div>+ int32_t encodedBitsSoFar = 0;</div><div>+ frameSizeEstimated = predictRowsSizeSum(pic, qpVbv, encodedBitsSoFar);</div>
<div>+ /* Last-ditch attempt: if the last row of the frame underflowed the VBV,</div><div>+ * try again. */</div><div>+ if((frameSizeEstimated > (bufferFill - bufferRate * maxFrameError) &&</div>
<div>+ qpVbv < qpMax && canReencodeRow))</div><div>+ {</div><div>+ qpVbv = qpMax;</div><div>+ fprintf(fp,", endvbv : %f ", qpVbv);</div><div>+ return -1;</div>
<div>+ }</div><div>+ }</div><div>+ fprintf(fp,", endvbv : %f ", qpVbv);</div><div>+ return 0;</div><div>+}</div><div>+</div><div>+</div><div> /* modify the bitrate curve from pass1 for one frame */</div>
<div> double RateControl::getQScale(RateControlEntry *rce, double rateFactor)</div><div> {</div><div>diff -r c5c07a3ee7fc -r 49b90667f050 source/encoder/ratecontrol.h</div><div>--- a/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 18:09:53 2014 +0530</div>
<div>+++ b/source/encoder/ratecontrol.h<span class="" style="white-space:pre"> </span>Thu Feb 20 18:23:48 2014 +0530</div><div>@@ -92,6 +92,7 @@</div><div> double vbvMaxRate; /* in kbps */</div><div> double vbvMinRate; /* in kbps */</div>
<div> bool singleFrameVbv;</div><div>+ double rateFactorMaxIncrement; /* Don't allow RF above (CRF + this value). */</div><div> bool isVbv;</div><div> Predictor pred[5];</div><div> Predictor predBfromP;</div>
<div>@@ -129,6 +130,7 @@</div><div> void rateControlStart(TComPic* pic, Lookahead *, RateControlEntry* rce, Encoder* enc);</div><div> void calcAdaptiveQuantFrame(TComPic *pic);</div><div> int rateControlEnd(TComPic* pic, int64_t bits, RateControlEntry* rce);</div>
<div>+ int rowDiagonalVbvRateControl(TComPic* pic, uint32_t row, RateControlEntry* rce, double& qpVbv);</div><div> </div><div> protected:</div><div> </div><div>@@ -143,6 +145,7 @@</div><div> void updateVbvPlan(Encoder* enc);</div>
<div> double predictSize(Predictor *p, double q, double var);</div><div> void checkAndResetABR(TComPic* pic, RateControlEntry* rce);</div><div>+ double predictRowsSizeSum(TComPic* pic, double qpm , int32_t& encodedBits);</div>
<div> };</div><div> }</div><div> </div><div><br></div><div>Content-Type: text/plain; charset="us-ascii"</div><div>MIME-Version: 1.0</div><div>Content-Transfer-Encoding: 7bit</div><div>Subject: [PATCH 6 of 6] vbv: integrate row level vbv ratecontrol at each major</div>
<div> row diagonal</div><div>X-Mercurial-Node: 650d5f835e417f45bd8a9f86465ca1909eaa9526</div><div>Message-Id: <<a href="mailto:650d5f835e417f45bd8a.1392901346@Aarthi-PC.router186658.com">650d5f835e417f45bd8a.1392901346@Aarthi-PC.router186658.com</a>></div>
<div>In-Reply-To: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div><div>References: <<a href="mailto:patchbomb.1392901340@Aarthi-PC.router186658.com">patchbomb.1392901340@Aarthi-PC.router186658.com</a>></div>
<div>User-Agent: Mercurial-patchbomb/2.7.1</div><div>Date: Thu, 20 Feb 2014 18:32:26 +0530</div><div>From: <a href="mailto:aarthi@multicorewareinc.com">aarthi@multicorewareinc.com</a></div><div>To: <a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a></div>
<div><br></div><div># HG changeset patch</div><div># User Aarthi Thirumalai</div><div># Date 1392901254 -19800</div><div># Thu Feb 20 18:30:54 2014 +0530</div><div># Node ID 650d5f835e417f45bd8a9f86465ca1909eaa9526</div>
<div># Parent 49b90667f050a7dd9c28b5017f389f5c29a1c191</div><div>vbv: integrate row level vbv ratecontrol at each major row diagonal.</div><div><br></div><div>diff -r 49b90667f050 -r 650d5f835e41 source/encoder/frameencoder.cpp</div>
<div>--- a/source/encoder/frameencoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:23:48 2014 +0530</div><div>+++ b/source/encoder/frameencoder.cpp<span class="" style="white-space:pre"> </span>Thu Feb 20 18:30:54 2014 +0530</div>
<div>@@ -1057,6 +1057,7 @@</div><div> CTURow& codeRow = m_rows[m_cfg->param.bEnableWavefront ? row : 0];</div><div> const uint32_t numCols = m_pic->getPicSym()->getFrameWidthInCU();</div><div> const uint32_t lineStartCUAddr = row * numCols;</div>
<div>+ double qpBase = m_pic->m_avgQpRc;</div><div> for (uint32_t col = curRow.m_completed; col < numCols; col++)</div><div> {</div><div> const uint32_t cuAddr = lineStartCUAddr + col;</div><div>@@ -1067,24 +1068,42 @@</div>
<div> codeRow.m_entropyCoder.resetEntropy();</div><div> </div><div> TEncSbac *bufSbac = (m_cfg->param.bEnableWavefront && col == 0 && row > 0) ? &m_rows[row - 1].m_bufferSbacCoder : NULL;</div>
<div>- if (m_cfg->param.rc.aqMode)</div><div>+</div><div>+ if ((uint32_t)row >= col && (row !=0))</div><div>+ qpBase = m_pic->getCU(cuAddr - numCols + 1)->m_baseQp;</div><div>+</div>
<div>+ if (m_cfg->param.rc.aqMode || (m_cfg->param.rc.vbvBufferSize >0 && m_cfg->param.rc.vbvMaxBitrate >0))</div><div> {</div><div>- int qp = calcQpForCu(m_pic, cuAddr);</div>
<div>+ int qp = calcQpForCu(m_pic, cuAddr , qpBase);</div><div> setLambda(qp, row);</div><div>- if (qp > MAX_QP)</div><div>- qp = MAX_QP;</div><div>- cu->setQP(0, (char)qp);</div>
<div>+ qp = X265_MIN(qp, MAX_QP);</div><div>+ cu->setQP(0,char(qp));</div><div>+ cu->m_baseQp = qpBase;</div><div> }</div><div> codeRow.processCU(cu, m_pic->getSlice(), bufSbac, m_cfg->param.bEnableWavefront && col == 1);</div>
<div> </div><div>- // TODO: Keep atomic running totals for rate control?</div><div>- // cu->m_totalBits;</div><div>- // cu->m_totalCost;</div><div>- // cu->m_totalDistortion;</div><div>
+ if (m_cfg->param.rc.vbvBufferSize && m_cfg->param.rc.vbvMaxBitrate)</div><div>+ {</div><div>+ // Update encoded bits, satdCost, baseQP for each CU</div><div>+ m_pic->m_rowDiagSatd[row] += m_pic->m_cuCostsForVbv[cuAddr];</div>
<div>+ m_pic->m_rowEncodedBits[row] += cu->m_totalBits;</div><div>+ m_pic->m_numEncodedCusPerRow[row] = cuAddr;</div><div>+ m_pic->m_qpaAq[row] += cu->getQP(0);</div><div>+ m_pic->m_qpaRc[row] += cu->m_baseQp;</div>
<div>+</div><div>+ if ((uint32_t)row == col)</div><div>+ m_pic->m_rowDiagQp[row] = qpBase;</div><div>+</div><div>+ // If current block is at row diagonal checkpoint, call vbv ratecontrol.</div>
<div>+ if ((uint32_t)row == col && row != 0 )</div><div>+ {</div><div>+ m_top->m_rateControl->rowDiagonalVbvRateControl(m_pic, row, &m_rce, qpBase);</div><div>+ qpBase = Clip3((double)MIN_QP, (double)MAX_MAX_QP, qpBase);</div>
<div>+ }</div><div>+ }</div><div> </div><div> // Completed CU processing</div><div> m_rows[row].m_completed++;</div><div>-</div><div> if (m_rows[row].m_completed >= 2 && row < m_numRows - 1)</div>
<div> {</div><div> ScopedLock below(m_rows[row + 1].m_lock);</div><div>@@ -1128,34 +1147,43 @@</div><div> curRow.m_busy = false;</div><div> }</div><div> </div><div>-int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr)</div>
<div>+int FrameEncoder::calcQpForCu(TComPic *pic, uint32_t cuAddr, double baseQp)</div><div> {</div><div> x265_emms();</div><div>- double qp = pic->getSlice()->m_avgQpRc;</div><div>- if (m_cfg->param.rc.aqMode)</div>
<div>+ double qp = baseQp;</div><div>+</div><div>+ /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */</div><div>+ double qp_offset = 0;</div><div>+ int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;</div>
<div>+ int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;</div><div>+ int noOfBlocks = g_maxCUWidth / 16;</div><div>+ int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;</div>
<div>+ int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();</div><div>+</div><div>+ double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;</div>
<div>+ int cnt = 0, idx =0;</div><div>+ for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)</div><div> {</div><div>- /* Derive qpOffet for each CU by averaging offsets for all 16x16 blocks in the cu. */</div>
<div>- double qp_offset = 0;</div><div>- int maxBlockCols = (pic->getPicYuvOrg()->getWidth() + (16 - 1)) / 16;</div><div>- int maxBlockRows = (pic->getPicYuvOrg()->getHeight() + (16 - 1)) / 16;</div>
<div>- int noOfBlocks = g_maxCUWidth / 16;</div><div>- int block_y = (cuAddr / pic->getPicSym()->getFrameWidthInCU()) * noOfBlocks;</div><div>- int block_x = (cuAddr * noOfBlocks) - block_y * pic->getPicSym()->getFrameWidthInCU();</div>
<div>+ for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)</div><div>+ {</div><div>+ idx = block_x + w + (block_y * maxBlockCols);</div><div>+ if (m_cfg->param.rc.aqMode)</div>
<div>+ qp_offset += qpoffs[idx];</div><div> </div><div>- double *qpoffs = (pic->getSlice()->isReferenced() && m_cfg->param.rc.cuTree) ? pic->m_lowres.qpOffset : pic->m_lowres.qpAqOffset;</div>
<div>- int cnt = 0;</div><div>- for (int h = 0; h < noOfBlocks && block_y < maxBlockRows; h++, block_y++)</div><div>- {</div><div>- for (int w = 0; w < noOfBlocks && (block_x + w) < maxBlockCols; w++)</div>
<div>+ if (m_cfg->param.rc.vbvBufferSize > 0 && m_cfg->param.rc.vbvMaxBitrate > 0)</div><div> {</div><div>- qp_offset += qpoffs[block_x + w + (block_y * maxBlockCols)];</div>
<div>- cnt++;</div><div>+ m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.lowresCostForRc[idx];</div><div>+ if (!m_cfg->param.rc.cuTree)</div><div>+ m_pic->m_cuCostsForVbv[cuAddr] += m_pic->m_lowres.intraCost[idx];</div>
<div> }</div><div>+ cnt++;</div><div> }</div><div>+ }</div><div> </div><div>- qp_offset /= cnt;</div><div>- qp += qp_offset;</div><div>- }</div><div>+ qp_offset /= cnt;</div>
<div>+ qp += qp_offset;</div><div>+</div><div>+</div><div> return Clip3(MIN_QP, MAX_MAX_QP, (int)(qp + 0.5));</div><div> }</div><div> </div><div>diff -r 49b90667f050 -r 650d5f835e41 source/encoder/frameencoder.h</div>
<div>--- a/source/encoder/frameencoder.h<span class="" style="white-space:pre"> </span>Thu Feb 20 18:23:48 2014 +0530</div><div>+++ b/source/encoder/frameencoder.h<span class="" style="white-space:pre"> </span>Thu Feb 20 18:30:54 2014 +0530</div>
<div>@@ -173,7 +173,7 @@</div><div> protected:</div><div> </div><div> void determineSliceBounds();</div><div>- int calcQpForCu(TComPic *pic, uint32_t cuAddr);</div><div>+ int calcQpForCu (TComPic *pic, uint32_t cuAddr, double baseQp);</div>
<div> Encoder* m_top;</div><div> TEncCfg* m_cfg;</div><div> </div><div><br></div></div>