<div dir="ltr"> since changed commit message - sending it as new patch. ignore the previous mail<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 13, 2013 at 4:51 PM, Sumalatha Polureddy <span dir="ltr"><<a href="mailto:sumalatha@multicorewareinc.com" target="_blank">sumalatha@multicorewareinc.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>modified according to comments in this thread<br></div><div class="im"><div><br></div><div><br></div>
<div><br></div><div># HG changeset patch</div><div># User sumalatha polureddy</div></div><div># Date 1379070966 -19800</div>
<div># Node ID 540be38baa71ba76e8502dbae8b8f4a4024cdb8d</div><div># Parent 64cde4a0b1759e2033d99bec709db6acfbe0f07a</div><div class="im"><div>ratecontrol: Tweak to better handle short term compensation</div><div>Increase the coefficient cplxrSum is adjusted by so that short term</div>
<div>compensation does not suffer as much.</div><div><br></div><div>Also, clip the QP for the first frame.</div><div><br></div><div>Overall improvement is about 5%.</div><div><br></div></div><div>diff -r 64cde4a0b175 -r 540be38baa71 source/encoder/ratecontrol.cpp</div>
<div>--- a/source/encoder/ratecontrol.cpp<span style="white-space:pre-wrap"> </span>Fri Sep 13 16:40:56 2013 +0530</div><div>+++ b/source/encoder/ratecontrol.cpp<span style="white-space:pre-wrap"> </span>Fri Sep 13 16:46:06 2013 +0530</div>
<div>@@ -72,11 +72,12 @@</div><div class="im"><div> shortTermCplxCount = 0;</div><div> if (rateControlMode == X265_RC_ABR)</div><div> {</div><div>- //TODO : confirm this value. obtained it from x264 when crf is disabled , abr enabled.</div>
<div>- //h->param.rc.i_rc_method == X264_RC_CRF ? h->param.rc.f_rf_constant : 24 -- can be tweaked for x265.</div><div>-#define ABR_INIT_QP (24 + QP_BD_OFFSET)</div><div>+ </div></div><div class="im">
<div>+ //introduced to margin QP for first frame to an optimum level in order to stabilize the quality.</div>
</div><div class="im"><div>+#define ABR_INIT_QP_MIN (24 + QP_BD_OFFSET)</div><div>+#define ABR_INIT_QP_MAX (38 + QP_BD_OFFSET)</div><div> accumPNorm = .01;</div></div><div>- accumPQp = (ABR_INIT_QP)*accumPNorm;</div>
<div>+ accumPQp = (ABR_INIT_QP_MIN) * accumPNorm;</div><div class="im">
<div> /* estimated ratio that produces a reasonable QP for the first I-frame */</div></div><div class="im"><div> cplxrSum = .01 * pow(7.0e5, qCompress) * pow(2 *ncu, 0.5);</div></div><div class="im"><div>
wantedBitsWindow = bitrate * frameDuration;</div>
</div><div class="im"><div>@@ -86,7 +87,7 @@</div><div> pbOffset = 6.0 * (float)(X265_LOG2(param->rc.pbFactor));</div><div> for (int i = 0; i < 3; i++)</div><div> {</div><div>- lastQScaleFor[i] = qp2qScale(ABR_INIT_QP);</div>
<div>+ lastQScaleFor[i] = qp2qScale(ABR_INIT_QP_MIN);</div><div> lmin[i] = qp2qScale(MIN_QP);</div><div> lmax[i] = qp2qScale(MAX_QP); </div><div> }</div></div><div>@@ -111,15 +112,15 @@</div><div>
switch (rateControlMode)</div>
<div> {</div><div> case X265_RC_ABR:</div><div>- {</div><div>- lastSatd = l->getEstimatedPictureCost(pic);</div><div>- double q = qScale2qp(rateEstimateQscale(rce));</div><div>- qp = Clip3(MIN_QP, MAX_QP, (int)(q + 0.5));</div>
<div>- rce->qpaRc = qpm = q; </div><div>- rce->newQp = qp;</div><div>- accumPQpUpdate();</div><div>- break;</div><div>- }</div><div>+ {</div><div>+ lastSatd = l->getEstimatedPictureCost(pic);</div>
<div>+ double q = qScale2qp(rateEstimateQscale(rce));</div><div>+ qp = Clip3(MIN_QP, MAX_QP, (int)(q + 0.5));</div><div>+ rce->qpaRc = qpm = q;</div><div>+ rce->newQp = qp;</div><div>+ accumPQpUpdate();</div>
<div>+ break;</div><div>+ }</div><div> </div><div> case X265_RC_CQP:</div><div> qp = qpConstant[frameType];</div><div class="im"><div>@@ -160,16 +161,19 @@</div><div> {</div><div> /* B-frames don't have independent rate control, but rather get the</div>
<div> * average QP of the two adjacent P-frames + an offset */</div><div>+ TComSlice* prevRefSlice = curFrame->getRefPic(REF_PIC_LIST_0, 0)->getSlice();</div><div>+ TComSlice* nextRefSlice = curFrame->getRefPic(REF_PIC_LIST_1, 0)->getSlice();</div>
<div>+ bool i0 = prevRefSlice->getSliceType() == I_SLICE;</div><div>+ bool i1 = nextRefSlice->getSliceType() == I_SLICE;</div><div>+ int dt0 = abs(curFrame->getPOC() - prevRefSlice->getPOC());</div>
<div>+ int dt1 = abs(curFrame->getPOC() - nextRefSlice->getPOC());</div><div>+ double q0 = prevRefSlice->getSliceQp();</div><div>+ double q1 = nextRefSlice->getSliceQp();</div><div> </div>
<div>- int i0 = curFrame->getRefPic(REF_PIC_LIST_0, 0)->getSlice()->getSliceType() == I_SLICE;</div><div>- int i1 = curFrame->getRefPic(REF_PIC_LIST_1, 0)->getSlice()->getSliceType() == I_SLICE;</div>
<div>- int dt0 = abs(curFrame->getPOC() - curFrame->getRefPic(REF_PIC_LIST_0, 0)->getPOC());</div><div>- int dt1 = abs(curFrame->getPOC() - curFrame->getRefPic(REF_PIC_LIST_1, 0)->getPOC());</div>
<div>-</div><div>- //TODO:need to figure out this</div><div>- double q0 = curFrame->getRefPic(REF_PIC_LIST_0, 0)->getSlice()->getSliceQp();</div><div>- double q1 = curFrame->getRefPic(REF_PIC_LIST_1, 0)->getSlice()->getSliceQp();</div>
<div>-</div></div><div class="im"><div>+ if (prevRefSlice->getSliceType() == B_SLICE && prevRefSlice->isReferenced())</div><div>+ q0 -= pbOffset / 2;</div><div>+ if (nextRefSlice->getSliceType() == B_SLICE && nextRefSlice->isReferenced())</div>
<div>+ q1 -= pbOffset / 2;</div></div><div class="im"><div> if (i0 && i1)</div><div> q = (q0 + q1) / 2 + ipOffset;</div><div> else if (i0)</div><div>@@ -183,12 +187,8 @@</div>
<div> q += pbOffset / 2;</div>
<div> else</div><div> q += pbOffset;</div></div><div class="im"><div>- </div><div>- double qScale = qp2qScale(q);</div><div> </div><div>- lastQScaleFor[P_SLICE] = lastQScale = qScale/pbFactor;</div>
<div>
-</div><div>- return qScale;</div><div>+ return qp2qScale(q);</div><div> }</div></div><div> else</div><div> {</div><div>@@ -242,21 +242,32 @@</div><div class="im"><div> q = qp2qScale(accumPQp / accumPNorm);</div>
<div> q /= fabs(ipFactor);</div><div> }</div><div>- else if (curFrame->getPOC() > 0)</div><div>+ if (rateControlMode != X265_RC_CRF)</div><div> {</div><div>- if (rateControlMode != X265_RC_CRF)</div>
<div>+ double lqmin = 0, lqmax = 0;</div><div>+</div><div>+ /* Clip the qp of 1st frame to ensure it doesnt detoriate the quality */</div><div>+ if (curFrame->getPOC() == 0)</div><div>
{</div>
<div>- /* Asymmetric clipping, because symmetric would prevent</div><div>- * overflow control in areas of rapidly oscillating complexity */</div><div>- double lqmin = lastQScaleFor[pictType] / lstep;</div>
<div>- double lqmax = lastQScaleFor[pictType] * lstep;</div><div>- if (overflow > 1.1 && curFrame->getPOC() > 3)</div><div>- lqmax *= lstep;</div><div>- else if (overflow < 0.9)</div>
<div>- lqmin /= lstep;</div><div>+ lqmin = qp2qScale(ABR_INIT_QP_MIN) / lstep;</div><div>+ lqmax = qp2qScale(ABR_INIT_QP_MAX) * lstep;</div></div><div>+ double l1 = qScale2qp(lqmin);</div>
<div>+ double l2 = qScale2qp(lqmax);</div><div>+ l1=l2;</div><div class="im"><div>+ }</div><div>+ /* Asymmetric clipping, because symmetric would prevent</div><div>
+ * overflow control in areas of rapidly oscillating complexity */</div>
<div>+ else if (curFrame->getPOC() > 0)</div><div>+ {</div><div>+ lqmin = lastQScaleFor[pictType] / lstep;</div><div>+ lqmax = lastQScaleFor[pictType] * lstep;</div>
<div>+ }</div><div>+ if (overflow > 1.1 && curFrame->getPOC() > 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>+ q = Clip3(lqmin, lqmax, q);</div><div> }</div><div> </div><div> //FIXME use get_diff_limited_q() ?</div>
</div><div>@@ -300,16 +311,18 @@</div><div class="im"><div> if (rateControlMode == X265_RC_ABR)</div><div> {</div><div> if (frameType != B_SLICE)</div><div>- cplxrSum += 1.1 *bits * qp2qScale(rce->qpaRc) / rce->lastRceq;</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>+ cplxrSum += 1.5 *bits * qp2qScale(rce->qpaRc) / rce->lastRceq;</div>
<div> else</div><div> {</div><div> /* Depends on the fact that B-frame's QP is an offset from the following P-frame's.</div><div> * Not perfectly accurate with B-refs, but good enough. */</div>
<div>- cplxrSum += bits * qp2qScale(rce->qpaRc) / (rce->lastRceq * fabs(0.5 * pbFactor));</div><div>+ cplxrSum += bits * qp2qScale(rce->qpaRc) / (rce->lastRceq * fabs(pbFactor));</div><div>
}</div><div> cplxrSum *= cbrDecay;</div><div> wantedBitsWindow += frameDuration * bitrate;</div></div><div>- wantedBitsWindow *= cbrDecay; </div><div>+ wantedBitsWindow *= cbrDecay;</div>
<div> rce = NULL;</div><div> }</div><div> totalBits += bits;</div><div><br></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Sep 13, 2013 at 4:23 PM, Derek Buitenhuis <span dir="ltr"><<a href="mailto:derek.buitenhuis@gmail.com" target="_blank">derek.buitenhuis@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On 9/13/2013 11:50 AM, Aarthi Priya Thirumalai wrote:<br>
> The qscale values are clipped(for P frames) depending on the lastQScaleFor[] at the end to ensure qps dont increase too high/low. they are updated in rateEstimateQScale for non B frames. The above change was introduced so that qp for P frames can adapt based on the qp of preceding B frames too - to see if its improves RateControl. Since it didnt give any big improvements, removing the change.<br>
<br>
</div>Ah, OK then.<br>
<div><div><br>
- Derek<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>