<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">---------- Forwarded message ---------<br>From: <strong class="gmail_sendername" dir="auto">Liwei Wang</strong> <span dir="auto"><<a href="mailto:liwei@multicorewareinc.com">liwei@multicorewareinc.com</a>></span><br>Date: Sun, Sep 26, 2021 at 11:44 AM<br>Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2 pass<br>To: Dakshinya T R S <<a href="mailto:dakshinya@multicorewareinc.com">dakshinya@multicorewareinc.com</a>><br>Cc: Mahesh Pittala <<a href="mailto:mahesh@multicorewareinc.com">mahesh@multicorewareinc.com</a>><br></div><br><br><div dir="ltr"><div><div style="color:rgb(80,0,80)"><div dir="ltr" class="gmail_attr">On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S <<a href="mailto:dakshinya@multicorewareinc.com" target="_blank">dakshinya@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001<br>From: lwWang <<a href="mailto:liwei@multicorewareinc.com" target="_blank">liwei@multicorewareinc.com</a>><br>Date: Wed, 15 Sep 2021 10:39:51 +0800<br>Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass<br><br>---<br> source/common/frame.h          |   1 +<br> source/common/framedata.cpp    |   2 +-<br> source/common/param.cpp        |   1 +<br> source/encoder/encoder.cpp     |   1 +<br> source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++---------------<br> source/encoder/ratecontrol.h   |   3 +<br> source/x265.h                  |   3 +<br> 7 files changed, 138 insertions(+), 113 deletions(-)<br><br>diff --git a/source/common/frame.h b/source/common/frame.h<br>index dc5bbacf7..ac1185e81 100644<br>--- a/source/common/frame.h<br>+++ b/source/common/frame.h<br>@@ -70,6 +70,7 @@ struct RcStats<br>     double   count[4];<br>     double   offset[4];<br>     double   bufferFillFinal;<br>+    int64_t  currentSatd;<br> };<br> <br> class Frame<br>diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp<br>index c77b017a8..70af8a248 100644<br>--- a/source/common/framedata.cpp<br>+++ b/source/common/framedata.cpp<br>@@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const SPS& sps, int csp)<br>     }<br>     else<br>         return false;<br>-    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame);<br>+    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1);<br></div></blockquote></div></div><div>[AM] What is the significance of this additional memory? </div><div><i><font color="#ff0000" style="background-color:rgb(0,0,255)">[LW] to fix the random crush issue(heap corruption)</font></i></div><div><div style="margin:5px 0px"><div id="m_-3691424108770081550gmail-q_108" aria-label="Hide expanded content" aria-expanded="true" style="background-color:rgb(232,234,237);border:none;clear:both;line-height:6px;outline:none;width:24px;color:rgb(80,0,80);font-size:11px;border-radius:5.5px"><div style="background:url("https://www.gstatic.com/images/icons/material/system_gm/1x/more_horiz_black_20dp.png") 50% 50%/20px no-repeat;height:11px;opacity:0.71;width:24px"></div></div></div><div style="color:rgb(80,0,80)"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">     CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight);<br>     reinit(sps);<br>     <br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index 6751e0aa7..2c1583d93 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -282,6 +282,7 @@ void x265_param_default(x265_param* param)<br>     param->rc.bStatRead = 0;<br>     param->rc.bStatWrite = 0;<br>     param->rc.statFileName = NULL;<br>+    param->rc.bEncFocusedFramesOnly = 0;<br>     param->rc.complexityBlur = 20;<br>     param->rc.qblur = 0.5;<br>     param->rc.zoneCount = 0;<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index dee8fd85d..cc014a740 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>                 outFrame->m_rcData->iCuCount = outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu;<br>                 outFrame->m_rcData->pCuCount = outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu;<br>                 outFrame->m_rcData->skipCuCount = outFrame->m_encData->m_frameStats.percent8x8Skip  * m_rateControl->m_ncu;<br>+                outFrame->m_rcData->currentSatd = curEncoder->m_rce.coeffBits;<br>             }<br> <br>             /* Allow this frame to be recycled if no frame encoders are using it for reference */<br>diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp<br>index a4756de39..2c211022d 100644<br>--- a/source/encoder/ratecontrol.cpp<br>+++ b/source/encoder/ratecontrol.cpp<br>@@ -1002,123 +1002,106 @@ bool RateControl::initPass2()<br>     uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);<br>     int startIndex, framesCount, endIndex;<br>     int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5));<br>+    int distance = fps << 1;<br>+    distance = distance > m_param->keyframeMax ? (m_param->keyframeMax << 1) : m_param->keyframeMax;<br>     startIndex = endIndex = framesCount = 0;<br>-    int diffQp = 0;<br>     double targetBits = 0;<br>     double expectedBits = 0;<br>-    for (startIndex = m_start, endIndex = m_start; endIndex < m_numEntries; endIndex++)<br>+    double targetBits2 = 0;<br>+    double expectedBits2 = 0;<br>+    double cpxSum = 0;<br>+    double cpxSum2 = 0;<br>+<br>+    if (m_param->rc.rateControlMode == X265_RC_ABR)<br>     {<br>-        allConstBits += m_rce2Pass[endIndex].miscBits;<br>-        allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;<br>-        if (m_param->rc.rateControlMode == X265_RC_CRF)<br>+        for (startIndex = m_start, endIndex = m_start; endIndex < m_numEntries; endIndex++)<br>         {<br>-            framesCount = endIndex - startIndex + 1;<br>-            diffQp += int (m_rce2Pass[endIndex].qpaRc - m_rce2Pass[endIndex].qpNoVbv);<br>-            if (framesCount > fps)<br>-                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - m_rce2Pass[endIndex - fps].qpNoVbv);<br>-            if (framesCount >= fps)<br>-            {<br>-                if (diffQp >= 1)<br>-                {<br>-                    if (!m_isQpModified && endIndex > fps)<br>-                    {<br>-                        double factor = 2;<br>-                        double step = 0;<br>-                        if (endIndex + fps >= m_numEntries)<br>-                        {<br>-                            m_start = endIndex - (endIndex % fps);<br>-                            return true;<br>-                        }<br>-                        for (int start = endIndex + 1; start <= endIndex + fps && start < m_numEntries; start++)<br>-                        {<br>-                            RateControlEntry *rce = &m_rce2Pass[start];<br>-                            targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>-                            expectedBits += qScale2bits(rce, rce->qScale);<br>-                        }<br>-                        if (expectedBits < 0.95 * targetBits)<br>-                        {<br>-                            m_isQpModified = true;<br>-                            m_isGopReEncoded = true;<br>-                            while (endIndex + fps < m_numEntries)<br>-                            {<br>-                                step = pow(2, factor / 6.0);<br>-                                expectedBits = 0;<br>-                                for (int start = endIndex + 1; start <= endIndex + fps; start++)<br>-                                {<br>-                                    RateControlEntry *rce = &m_rce2Pass[start];<br>-                                    rce->newQScale = rce->qScale / step;<br>-                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>-                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>-                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>-                                }<br>-                                if (expectedBits >= targetBits && step > 1)<br>-                                    factor *= 0.90;<br>-                                else<br>-                                    break;<br>-                            }<br>-<br>-                            if (m_isVbv && endIndex + fps < m_numEntries)<br>-                                if (!vbv2Pass((uint64_t)targetBits, endIndex + fps, endIndex + 1))<br>-                                    return false;<br>-<br>-                            targetBits = 0;<br>-                            expectedBits = 0;<br>-<br>-                            for (int start = endIndex - fps + 1; start <= endIndex; start++)<br>-                            {<br>-                                RateControlEntry *rce = &m_rce2Pass[start];<br>-                                targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>-                            }<br>-                            while (1)<br>-                            {<br>-                                step = pow(2, factor / 6.0);<br>-                                expectedBits = 0;<br>-                                for (int start = endIndex - fps + 1; start <= endIndex; start++)<br>-                                {<br>-                                    RateControlEntry *rce = &m_rce2Pass[start];<br>-                                    rce->newQScale = rce->qScale * step;<br>-                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>-                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>-                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>-                                }<br>-                                if (expectedBits > targetBits && step > 1)<br>-                                    factor *= 1.1;<br>-                                else<br>-                                     break;<br>-                            }<br>-                            if (m_isVbv)<br>-                                if (!vbv2Pass((uint64_t)targetBits, endIndex, endIndex - fps + 1))<br>-                                    return false;<br>-                            diffQp = 0;<br>-                            m_reencode = endIndex - fps + 1;<br>-                            endIndex = endIndex + fps;<br>-                            startIndex = endIndex + 1;<br>-                            m_start = startIndex;<br>-                            targetBits = expectedBits = 0;<br>-                        }<br>-                        else<br>-                            targetBits = expectedBits = 0;<br>-                    }<br>-                }<br>-                else<br>-                    m_isQpModified = false;<br>-            }<br>+            allConstBits += m_rce2Pass[endIndex].miscBits;<br>+            allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;<br>         }<br>-    }<br> <br>-    if (m_param->rc.rateControlMode == X265_RC_ABR)<br>-    {<br>         if (allAvailableBits < allConstBits)<br>         {<br>             x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",<br>-                     (int)(allConstBits * m_fps / framesCount * 1000.));<br>+                (int)(allConstBits * m_fps / framesCount * 1000.));<br>             return false;<br>         }<br>         if (!analyseABR2Pass(allAvailableBits))<br>             return false;<br>+<br>+        return true;<br>+    }<br>+<br>+    if (m_param->rc.rateControlMode != X265_RC_CRF)<br>+    {<br></div></blockquote></div></div><div>[AM] This condition will never hit. Please clarify why this is required.</div><div><i style="background-color:rgb(0,0,255)">[LW] Yeah, you're right. It will never hit. I will remove this check.Thanks</i></div><span style="color:rgb(80,0,80)"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">+        return true;<br>     }</div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"> <br>-    m_start = X265_MAX(m_start, endIndex - fps);<br>+    if (m_isQpModified)<br>+    {<br></div></blockquote></span><div>[AM] This condition will always hit. Please clarify why this check is required. </div><div><i style="background-color:rgb(0,0,255)">[LW] m_isQpModified may be false.  And in the uhdkit, the cappedvbr would modify its value.</i></div><div><div style="margin:5px 0px"><div id="m_-3691424108770081550gmail-q_104" style="background-color:rgb(232,234,237);border:none;clear:both;line-height:6px;outline:none;width:24px;color:rgb(80,0,80);font-size:11px;border-radius:5.5px"><div style="background:url("https://www.gstatic.com/images/icons/material/system_gm/1x/more_horiz_black_20dp.png") 50% 50%/20px no-repeat;height:11px;opacity:0.71;width:24px"></div></div></div></div><div>[AM] Please include a conformance check in Encoder::configure() to disable m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled. </div><div>[<i style="background-color:rgb(0,0,255)">LW] OK. I will add it. By the way, </i><i style="background-color:rgb(0,0,255)">bEncFocusedFramesOnly has been set to be false by default in the x265_param_default()</i></div><div><div style="margin:5px 0px"><div id="m_-3691424108770081550gmail-q_102" style="background-color:rgb(232,234,237);border:none;clear:both;line-height:6px;outline:none;width:24px;color:rgb(80,0,80);font-size:11px;border-radius:5.5px"><div style="background:url("https://www.gstatic.com/images/icons/material/system_gm/1x/more_horiz_black_20dp.png") 50% 50%/20px no-repeat;height:11px;opacity:0.71;width:24px"></div></div></div></div><div>[AM] Update X265_BUILD, add help document, and add an entry for the new param in info SEI. </div><div>Is this a param?API only option? If so, clarify that in the document. Else, add a test CLI.</div><div><i><span style="background-color:rgb(0,0,255)">[LW] OK. However, </span></i><i style="background-color:rgb(0,0,255)">bEncFocusedFramesOnly would only be used together with cappedvbr in uhdkit. It could not be used alone in x25. So maybe it is better to move it from the x265_param to the encoder or rateontrol?</i></div><span style="color:rgb(80,0,80)"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">         /* temporally blur quants */<br>         double    qblur;<br></div></blockquote></span></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 24, 2021 at 5:02 PM Dakshinya T R S <<a href="mailto:dakshinya@multicorewareinc.com" target="_blank">dakshinya@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">---------- Forwarded message ---------<br>From: <strong class="gmail_sendername" dir="auto">Aruna Matheswaran</strong> <span dir="auto"><<a href="mailto:aruna@multicorewareinc.com" target="_blank">aruna@multicorewareinc.com</a>></span><br>Date: Fri, Sep 24, 2021 at 2:26 PM<br>Subject: Re: [x265] [PATCH] encoding only the focused frames in the crf 2 pass<br>To: Development for x265 <<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a>><br></div><br><br><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 24, 2021 at 1:34 PM Dakshinya T R S <<a href="mailto:dakshinya@multicorewareinc.com" target="_blank">dakshinya@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">From d4ac086b18c41e6d146cd70524c581138b1186ec Mon Sep 17 00:00:00 2001<br>From: lwWang <<a href="mailto:liwei@multicorewareinc.com" target="_blank">liwei@multicorewareinc.com</a>><br>Date: Wed, 15 Sep 2021 10:39:51 +0800<br>Subject: [PATCH 1/2] encoding only the focused frames in the crf 2 pass<br><br>---<br> source/common/frame.h          |   1 +<br> source/common/framedata.cpp    |   2 +-<br> source/common/param.cpp        |   1 +<br> source/encoder/encoder.cpp     |   1 +<br> source/encoder/ratecontrol.cpp | 240 ++++++++++++++++++---------------<br> source/encoder/ratecontrol.h   |   3 +<br> source/x265.h                  |   3 +<br> 7 files changed, 138 insertions(+), 113 deletions(-)<br><br>diff --git a/source/common/frame.h b/source/common/frame.h<br>index dc5bbacf7..ac1185e81 100644<br>--- a/source/common/frame.h<br>+++ b/source/common/frame.h<br>@@ -70,6 +70,7 @@ struct RcStats<br>     double   count[4];<br>     double   offset[4];<br>     double   bufferFillFinal;<br>+    int64_t  currentSatd;<br> };<br> <br> class Frame<br>diff --git a/source/common/framedata.cpp b/source/common/framedata.cpp<br>index c77b017a8..70af8a248 100644<br>--- a/source/common/framedata.cpp<br>+++ b/source/common/framedata.cpp<br>@@ -62,7 +62,7 @@ bool FrameData::create(const x265_param& param, const SPS& sps, int csp)<br>     }<br>     else<br>         return false;<br>-    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame);<br>+    CHECKED_MALLOC_ZERO(m_cuStat, RCStatCU, sps.numCUsInFrame + 1);<br></div></blockquote><div>[AM] What is the significance of this additional memory? </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">     CHECKED_MALLOC(m_rowStat, RCStatRow, sps.numCuInHeight);<br>     reinit(sps);<br>     <br>diff --git a/source/common/param.cpp b/source/common/param.cpp<br>index 6751e0aa7..2c1583d93 100755<br>--- a/source/common/param.cpp<br>+++ b/source/common/param.cpp<br>@@ -282,6 +282,7 @@ void x265_param_default(x265_param* param)<br>     param->rc.bStatRead = 0;<br>     param->rc.bStatWrite = 0;<br>     param->rc.statFileName = NULL;<br>+    param->rc.bEncFocusedFramesOnly = 0;<br>     param->rc.complexityBlur = 20;<br>     param->rc.qblur = 0.5;<br>     param->rc.zoneCount = 0;<br>diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>index dee8fd85d..cc014a740 100644<br>--- a/source/encoder/encoder.cpp<br>+++ b/source/encoder/encoder.cpp<br>@@ -2249,6 +2249,7 @@ int Encoder::encode(const x265_picture* pic_in, x265_picture* pic_out)<br>                 outFrame->m_rcData->iCuCount = outFrame->m_encData->m_frameStats.percent8x8Intra * m_rateControl->m_ncu;<br>                 outFrame->m_rcData->pCuCount = outFrame->m_encData->m_frameStats.percent8x8Inter * m_rateControl->m_ncu;<br>                 outFrame->m_rcData->skipCuCount = outFrame->m_encData->m_frameStats.percent8x8Skip  * m_rateControl->m_ncu;<br>+                outFrame->m_rcData->currentSatd = curEncoder->m_rce.coeffBits;<br>             }<br> <br>             /* Allow this frame to be recycled if no frame encoders are using it for reference */<br>diff --git a/source/encoder/ratecontrol.cpp b/source/encoder/ratecontrol.cpp<br>index a4756de39..2c211022d 100644<br>--- a/source/encoder/ratecontrol.cpp<br>+++ b/source/encoder/ratecontrol.cpp<br>@@ -1002,123 +1002,106 @@ bool RateControl::initPass2()<br>     uint64_t allAvailableBits = uint64_t(m_param->rc.bitrate * 1000. * m_numEntries * m_frameDuration);<br>     int startIndex, framesCount, endIndex;<br>     int fps = X265_MIN(m_param->keyframeMax, (int)(m_fps + 0.5));<br>+    int distance = fps << 1;<br>+    distance = distance > m_param->keyframeMax ? (m_param->keyframeMax << 1) : m_param->keyframeMax;<br>     startIndex = endIndex = framesCount = 0;<br>-    int diffQp = 0;<br>     double targetBits = 0;<br>     double expectedBits = 0;<br>-    for (startIndex = m_start, endIndex = m_start; endIndex < m_numEntries; endIndex++)<br>+    double targetBits2 = 0;<br>+    double expectedBits2 = 0;<br>+    double cpxSum = 0;<br>+    double cpxSum2 = 0;<br>+<br>+    if (m_param->rc.rateControlMode == X265_RC_ABR)<br>     {<br>-        allConstBits += m_rce2Pass[endIndex].miscBits;<br>-        allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;<br>-        if (m_param->rc.rateControlMode == X265_RC_CRF)<br>+        for (startIndex = m_start, endIndex = m_start; endIndex < m_numEntries; endIndex++)<br>         {<br>-            framesCount = endIndex - startIndex + 1;<br>-            diffQp += int (m_rce2Pass[endIndex].qpaRc - m_rce2Pass[endIndex].qpNoVbv);<br>-            if (framesCount > fps)<br>-                diffQp -= int (m_rce2Pass[endIndex - fps].qpaRc - m_rce2Pass[endIndex - fps].qpNoVbv);<br>-            if (framesCount >= fps)<br>-            {<br>-                if (diffQp >= 1)<br>-                {<br>-                    if (!m_isQpModified && endIndex > fps)<br>-                    {<br>-                        double factor = 2;<br>-                        double step = 0;<br>-                        if (endIndex + fps >= m_numEntries)<br>-                        {<br>-                            m_start = endIndex - (endIndex % fps);<br>-                            return true;<br>-                        }<br>-                        for (int start = endIndex + 1; start <= endIndex + fps && start < m_numEntries; start++)<br>-                        {<br>-                            RateControlEntry *rce = &m_rce2Pass[start];<br>-                            targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>-                            expectedBits += qScale2bits(rce, rce->qScale);<br>-                        }<br>-                        if (expectedBits < 0.95 * targetBits)<br>-                        {<br>-                            m_isQpModified = true;<br>-                            m_isGopReEncoded = true;<br>-                            while (endIndex + fps < m_numEntries)<br>-                            {<br>-                                step = pow(2, factor / 6.0);<br>-                                expectedBits = 0;<br>-                                for (int start = endIndex + 1; start <= endIndex + fps; start++)<br>-                                {<br>-                                    RateControlEntry *rce = &m_rce2Pass[start];<br>-                                    rce->newQScale = rce->qScale / step;<br>-                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>-                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>-                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>-                                }<br>-                                if (expectedBits >= targetBits && step > 1)<br>-                                    factor *= 0.90;<br>-                                else<br>-                                    break;<br>-                            }<br>-<br>-                            if (m_isVbv && endIndex + fps < m_numEntries)<br>-                                if (!vbv2Pass((uint64_t)targetBits, endIndex + fps, endIndex + 1))<br>-                                    return false;<br>-<br>-                            targetBits = 0;<br>-                            expectedBits = 0;<br>-<br>-                            for (int start = endIndex - fps + 1; start <= endIndex; start++)<br>-                            {<br>-                                RateControlEntry *rce = &m_rce2Pass[start];<br>-                                targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>-                            }<br>-                            while (1)<br>-                            {<br>-                                step = pow(2, factor / 6.0);<br>-                                expectedBits = 0;<br>-                                for (int start = endIndex - fps + 1; start <= endIndex; start++)<br>-                                {<br>-                                    RateControlEntry *rce = &m_rce2Pass[start];<br>-                                    rce->newQScale = rce->qScale * step;<br>-                                    X265_CHECK(rce->newQScale >= 0, "new Qscale is negative\n");<br>-                                    expectedBits += qScale2bits(rce, rce->newQScale);<br>-                                    rce->newQp = x265_qScale2qp(rce->newQScale);<br>-                                }<br>-                                if (expectedBits > targetBits && step > 1)<br>-                                    factor *= 1.1;<br>-                                else<br>-                                     break;<br>-                            }<br>-                            if (m_isVbv)<br>-                                if (!vbv2Pass((uint64_t)targetBits, endIndex, endIndex - fps + 1))<br>-                                    return false;<br>-                            diffQp = 0;<br>-                            m_reencode = endIndex - fps + 1;<br>-                            endIndex = endIndex + fps;<br>-                            startIndex = endIndex + 1;<br>-                            m_start = startIndex;<br>-                            targetBits = expectedBits = 0;<br>-                        }<br>-                        else<br>-                            targetBits = expectedBits = 0;<br>-                    }<br>-                }<br>-                else<br>-                    m_isQpModified = false;<br>-            }<br>+            allConstBits += m_rce2Pass[endIndex].miscBits;<br>+            allCodedBits += m_rce2Pass[endIndex].coeffBits + m_rce2Pass[endIndex].mvBits;<br>         }<br>-    }<br> <br>-    if (m_param->rc.rateControlMode == X265_RC_ABR)<br>-    {<br>         if (allAvailableBits < allConstBits)<br>         {<br>             x265_log(m_param, X265_LOG_ERROR, "requested bitrate is too low. estimated minimum is %d kbps\n",<br>-                     (int)(allConstBits * m_fps / framesCount * 1000.));<br>+                (int)(allConstBits * m_fps / framesCount * 1000.));<br>             return false;<br>         }<br>         if (!analyseABR2Pass(allAvailableBits))<br>             return false;<br>+<br>+        return true;<br>+    }<br>+<br>+    if (m_param->rc.rateControlMode != X265_RC_CRF)<br>+    {<br></div></blockquote><div>[AM] This condition will never hit. Please clarify why this is required.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">+        return true;<br>     }</div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"> <br>-    m_start = X265_MAX(m_start, endIndex - fps);<br>+    if (m_isQpModified)<br>+    {<br></div></blockquote><div>[AM] This condition will always hit. Please clarify why this check is required. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">+        return true;<br>+    }<br>+<br>+    if (m_start + (fps << 1) > m_numEntries)<br>+    {<br>+        return true;<br>+    }<br>+<br>+    for (startIndex = m_start, endIndex = m_numEntries - 1; startIndex < endIndex; startIndex++, endIndex--)<br>+    {<br>+        cpxSum += m_rce2Pass[startIndex].qScale / m_rce2Pass[startIndex].coeffBits;<br>+        cpxSum2 += m_rce2Pass[endIndex].qScale / m_rce2Pass[endIndex].coeffBits;<br>+<br>+        RateControlEntry *rce = &m_rce2Pass[startIndex];<br>+        targetBits += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>+        expectedBits += qScale2bits(rce, rce->qScale);<br>+<br>+        rce = &m_rce2Pass[endIndex];<br>+        targetBits2 += qScale2bits(rce, x265_qp2qScale(rce->qpNoVbv));<br>+        expectedBits2 += qScale2bits(rce, rce->qScale);<br>+    }<br>+<br>+    if (expectedBits < 0.95 * targetBits || expectedBits2 < 0.95 * targetBits2)<br>+    {<br>+        if (cpxSum / cpxSum2 < 0.95 || cpxSum2 / cpxSum < 0.95)<br>+        {<br>+            m_isQpModified = true;<br>+            m_isGopReEncoded = true;<br>+<br>+            m_shortTermCplxSum = 0;<br>+            m_shortTermCplxCount = 0;<br>+            m_framesDone = m_start;<br>+<br>+            for (startIndex = m_start; startIndex < m_numEntries; startIndex++)<br>+            {<br>+                m_shortTermCplxSum *= 0.5;<br>+                m_shortTermCplxCount *= 0.5;<br>+                m_shortTermCplxSum += m_rce2Pass[startIndex].currentSatd / (CLIP_DURATION(m_frameDuration) / BASE_FRAME_DURATION);<br>+                m_shortTermCplxCount++;<br>+            }<br>+<br>+            m_bufferFill = m_rce2Pass[m_start - 1].bufferFill;<br>+            m_bufferFillFinal = m_rce2Pass[m_start - 1].bufferFillFinal;<br>+            m_bufferFillActual = m_rce2Pass[m_start - 1].bufferFillActual;<br>+<br>+            m_reencode = m_start;<br>+            m_start = m_numEntries;<br>+        }<br>+        else<br>+        {<br>+<br>+            m_isQpModified = false;<br>+            m_isGopReEncoded = false;<br>+        }<br>+    }<br>+    else<br>+    {<br>+<br>+        m_isQpModified = false;<br>+        m_isGopReEncoded = false;<br>+    }<br>+<br>+    m_start = X265_MAX(m_start, m_numEntries - distance + m_param->keyframeMax);<br> <br>     return true;<br> }<br>@@ -1391,15 +1374,47 @@ int RateControl::rateControlStart(Frame* curFrame, RateControlEntry* rce, Encode<br>             rce->frameSizeMaximum *= m_param->maxAUSizeFactor;<br>         }<br>     }<br>+<br>+    ///< regenerate the qp<br>     if (!m_isAbr && m_2pass && m_param->rc.rateControlMode == X265_RC_CRF)<br>     {<br>-        rce->qpPrev = x265_qScale2qp(rce->qScale);<br>-        rce->qScale = rce->newQScale;<br>-        rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = x265_qScale2qp(rce->newQScale);<br>-        m_qp = int(rce->qpaRc + 0.5);<br>-        rce->frameSizePlanned = qScale2bits(rce, rce->qScale);<br>-        m_framesDone++;<br>-        return m_qp;<br>+        if (!m_param->rc.bEncFocusedFramesOnly)<br>+        {<br>+            rce->qpPrev = x265_qScale2qp(rce->qScale);<br>+            rce->qScale = rce->newQScale;<br>+            rce->qpaRc = curEncData.m_avgQpRc = curEncData.m_avgQpAq = x265_qScale2qp(rce->newQScale);<br>+            m_qp = int(rce->qpaRc + 0.5);<br>+            rce->frameSizePlanned = qScale2bits(rce, rce->qScale);<br>+            m_framesDone++;<br>+            return m_qp;<br>+        }<br>+        else<br>+        { <br>+            int index = m_encOrder[rce->poc];<br>+            index++;<br>+            double totalDuration = m_frameDuration;<br>+            for (int j = 0; totalDuration < 1.0 && index < m_numEntries; j++)<br>+            {<br>+                switch (m_rce2Pass[index].sliceType)<br>+                {<br>+                case B_SLICE:<br>+                    curFrame->m_lowres.plannedType[j] = m_rce2Pass[index].keptAsRef ? X265_TYPE_BREF : X265_TYPE_B;<br>+                    break;<br>+                case P_SLICE:<br>+                    curFrame->m_lowres.plannedType[j] = X265_TYPE_P;<br>+                    break;<br>+                case I_SLICE:<br>+                    curFrame->m_lowres.plannedType[j] = m_param->bOpenGOP ? X265_TYPE_I : X265_TYPE_IDR;<br>+                    break;<br>+                default:<br>+                    break;<br>+                }<br>+<br>+                curFrame->m_lowres.plannedSatd[j] = m_rce2Pass[index].currentSatd;<br>+                totalDuration += m_frameDuration;<br>+                index++;<br>+            }<br>+        }<br>     }<br> <br>     if (m_isAbr || m_2pass) // ABR,CRF<br>@@ -1890,7 +1905,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)<br>                 qScale = x265_clip3(lqmin, lqmax, qScale);<br>             }<br> <br>-            if (!m_2pass || m_param->bliveVBV2pass)<br>+            if (!m_2pass || m_param->bliveVBV2pass || (m_2pass && m_param->rc.rateControlMode == X265_RC_CRF && m_param->rc.bEncFocusedFramesOnly))<br>             {<br>                 /* clip qp to permissible range after vbv-lookahead estimation to avoid possible <br>                  * mispredictions by initial frame size predictors */<br>@@ -1927,7 +1942,7 @@ double RateControl::rateEstimateQscale(Frame* curFrame, RateControlEntry *rce)<br>     else<br>     {<br>         double abrBuffer = 2 * m_rateTolerance * m_bitrate;<br>-        if (m_2pass)<br>+        if (m_2pass && (m_param->rc.rateControlMode != X265_RC_CRF || !m_param->rc.bEncFocusedFramesOnly))<br>         {<br></div></blockquote><div>[AM] Please include a conformance check in Encoder::configure() to disable m_param->rc.bEncFocusedFramesOnly if either bStatRead or CRF is disabled. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">             double lmin = m_lmin[m_sliceType];<br>             double lmax = m_lmax[m_sliceType];<br>@@ -2828,7 +2843,7 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry*<br> <br>     if (m_param->rc.aqMode || m_isVbv || m_param->bAQMotion || bEnableDistOffset)<br>     {<br>-        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == X265_RC_CRF))<br>+        if (m_isVbv && !(m_2pass && m_param->rc.rateControlMode == X265_RC_CRF && !m_param->rc.bEncFocusedFramesOnly))<br>         {<br>             double avgQpRc = 0;<br>             /* determine avg QP decided by VBV rate control */<br>@@ -2862,8 +2877,9 @@ int RateControl::rateControlEnd(Frame* curFrame, int64_t bits, RateControlEntry*<br>     if (m_param->rc.rateControlMode == X265_RC_CRF)<br>     {<br>         double crfVal, qpRef = curEncData.m_avgQpRc;<br>+<br>         bool is2passCrfChange = false;<br>-        if (m_2pass)<br>+        if (m_2pass && !m_param->rc.bEncFocusedFramesOnly)<br>         {<br>             if (fabs(curEncData.m_avgQpRc - rce->qpPrev) > 0.1)<br>             {<br>diff --git a/source/encoder/ratecontrol.h b/source/encoder/ratecontrol.h<br>index 996465eeb..204bd71e1 100644<br>--- a/source/encoder/ratecontrol.h<br>+++ b/source/encoder/ratecontrol.h<br>@@ -73,6 +73,7 @@ struct RateControlEntry<br>     Predictor  rowPreds[3][2];<br>     Predictor* rowPred[2];<br> <br>+    int64_t currentSatd;<br>     int64_t lastSatd;      /* Contains the picture cost of the previous frame, required for resetAbr and VBV */<br>     int64_t leadingNoBSatd;<br>     int64_t rowTotalBits;  /* update cplxrsum and totalbits at the end of 2 rows */<br>@@ -87,6 +88,8 @@ struct RateControlEntry<br>     double  rowCplxrSum;<br>     double  qpNoVbv;<br>     double  bufferFill;<br>+    double  bufferFillFinal;<br>+    double  bufferFillActual;<br>     double  targetFill;<br>     bool    vbvEndAdj;<br>     double  frameDuration;<br>diff --git a/source/x265.h b/source/x265.h<br>index 3f3133536..6bb893c98 100644<br>--- a/source/x265.h<br>+++ b/source/x265.h<br>@@ -1443,6 +1443,9 @@ typedef struct x265_param<br>          * encoder will default to using x265_2pass.log */<br>         const char* statFileName;<br> <br>+        /* if only the focused frames would be re-encode or not */<br>+        int       bEncFocusedFramesOnly;<br>+<br></div></blockquote><div>[AM] Update X265_BUILD, add help document, and add an entry for the new param in info SEI. </div><div>Is this a param?API only option? If so, clarify that in the document. Else, add a test CLI.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">         /* temporally blur quants */<br>         double    qblur;<br> <br>-- <br>2.22.0.windows.1<br><br></div>
_______________________________________________<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" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><font face="georgia, serif">Regards,</font><div><b><font face="georgia, serif">Aruna Matheswaran,</font></b></div><div><font face="georgia, serif">Video Codec Engineer,</font></div><div><font face="georgia, serif">Media & AI analytics BU,</font></div><div><span><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><span style="border:none;display:inline-block;overflow:hidden;width:153px;height:58px"><img src="https://lh5.googleusercontent.com/gjX5cPNIZgwUrhfqkTwQUZWztIKmmo0qs3kbwvkS5H-bDVE2ftte9pMTVnFLSjOcjYWLtfc6_OGpxW4vraLg2r5QAIf1Q3MpldFDgWtzK_gXi8ptw5B3joIbsGL6mxj-JRdjHzT5" width="96" height="36" style="margin-left:0px;margin-top:0px"></span></span></span><font face="georgia, serif"><br></font></div><div><span><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;vertical-align:baseline;white-space:pre-wrap"><span style="border:none;display:inline-block;overflow:hidden;width:153px;height:58px"><img src="https://lh5.googleusercontent.com/gjX5cPNIZgwUrhfqkTwQUZWztIKmmo0qs3kbwvkS5H-bDVE2ftte9pMTVnFLSjOcjYWLtfc6_OGpxW4vraLg2r5QAIf1Q3MpldFDgWtzK_gXi8ptw5B3joIbsGL6mxj-JRdjHzT5" style="margin-left:0px;margin-top:0px"></span></span></span><font face="georgia, serif"><br></font></div><div><font face="georgia, serif"><br></font></div></div></div></div></div></div></div></div></div></div>
_______________________________________________<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" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</div></div>
</blockquote></div>
</div></div>