<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>