<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 18, 2017 at 3:17 PM, Divya Manivannan <span dir="ltr"><<a href="mailto:divya@multicorewareinc.com" target="_blank">divya@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Divya Manivannan <<a href="mailto:divya@multicorewareinc.com">divya@multicorewareinc.com</a>><br>
# Date 1499954857 -19800<br>
#      Thu Jul 13 19:37:37 2017 +0530<br>
# Node ID a80bf309ef01171a7982d0fe7dfb12<wbr>ce1fb9d10f<br>
# Parent  3f6841d271e36dc324936f09846d1f<wbr>2cb77c63e5<br>
Add force-flush param option<br></blockquote><div><br></div><div>Pushed to default branch</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
This option will force the encoder to flush all frames without waiting for<br>
all input pictures to arrive.<br>
<br>
diff -r 3f6841d271e3 -r a80bf309ef01 doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst  Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/doc/reST/cli.rst  Thu Jul 13 19:37:37 2017 +0530<br>
@@ -1405,6 +1405,16 @@<br>
 .. option:: --b-pyramid, --no-b-pyramid<br>
<br>
        Use B-frames as references, when possible. Default enabled<br>
+<br>
+.. option:: --force-flush <integer><br>
+<br>
+       Force the encoder to flush frames. Default is 0.<br>
+<br>
+       Values:<br>
+       0 - flush the encoder only when all the input pictures are over.<br>
+       1 - flush all the frames even when the input is not over.<br>
+           slicetype decision may change with this option.<br>
+       2 - flush the slicetype decided frames only.<br>
<br>
 Quality, rate control and rate distortion options<br>
 ==============================<wbr>===================<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt     Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/CMakeLists.txt     Thu Jul 13 19:37:37 2017 +0530<br>
@@ -29,7 +29,7 @@<br>
 option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
 # X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 130)<br>
+set(X265_BUILD 131)<br>
 configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
                "${PROJECT_BINARY_DIR}/x265.<wbr>def")<br>
 configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/common/param.cpp<br>
--- a/source/common/param.cpp   Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/common/param.cpp   Thu Jul 13 19:37:37 2017 +0530<br>
@@ -285,6 +285,7 @@<br>
     param->mvRefine = 0;<br>
     param->bUseAnalysisFile = 1;<br>
     param->csvfpt = NULL;<br>
+    param->forceFlush = 0;<br>
 }<br>
<br>
 int x265_param_default_preset(<wbr>x265_param* param, const char* preset, const char* tune)<br>
@@ -973,6 +974,7 @@<br>
         OPT("refine-intra")p-><wbr>intraRefine = atoi(value);<br>
         OPT("refine-inter")p-><wbr>interRefine = atobool(value);<br>
         OPT("refine-mv")p->mvRefine = atobool(value);<br>
+        OPT("force-flush")p-><wbr>forceFlush = atoi(value);<br>
         else<br>
             return X265_PARAM_BAD_NAME;<br>
     }<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/encoder/api.cpp<br>
--- a/source/encoder/api.cpp    Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/encoder/api.cpp    Thu Jul 13 19:37:37 2017 +0530<br>
@@ -188,6 +188,8 @@<br>
<br>
     x265_param save;<br>
     Encoder* encoder = static_cast<Encoder*>(enc);<br>
+    if (encoder->m_latestParam-><wbr>forceFlush != param_in->forceFlush)<br>
+        return encoder->reconfigureParam(<wbr>encoder->m_latestParam, param_in);<br>
     bool isReconfigureRc = encoder->isReconfigureRc(<wbr>encoder->m_latestParam, param_in);<br>
     if (encoder->m_reconfigure && !isReconfigureRc || encoder->m_reconfigureRc && isReconfigureRc) /* Reconfigure in progress */<br>
         return 1;<br>
@@ -255,7 +257,7 @@<br>
     {<br>
         numEncoded = encoder->encode(pic_in, pic_out);<br>
     }<br>
-    while (numEncoded == 0 && !pic_in && encoder->m_numDelayedPic);<br>
+    while (numEncoded == 0 && !pic_in && encoder->m_numDelayedPic && !encoder->m_latestParam-><wbr>forceFlush);<br>
<br>
     // do not allow reuse of these buffers for more than one picture. The<br>
     // encoder now owns these analysisData buffers.<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/encoder/encoder.cpp        Thu Jul 13 19:37:37 2017 +0530<br>
@@ -603,6 +603,17 @@<br>
     }<br>
     if (pic_in)<br>
     {<br>
+        if (m_latestParam->forceFlush == 1)<br>
+        {<br>
+            m_lookahead-><wbr>setLookaheadQueue();<br>
+            m_latestParam->forceFlush = 0;<br>
+        }<br>
+        if (m_latestParam->forceFlush == 2)<br>
+        {<br>
+            m_lookahead->m_filled = false;<br>
+            m_latestParam->forceFlush = 0;<br>
+        }<br>
+<br>
         x265_sei_payload toneMap;<br>
         toneMap.payload = NULL;<br>
 #if ENABLE_HDR10_PLUS<br>
@@ -804,6 +815,8 @@<br>
         m_lookahead->addPicture(*<wbr>inFrame, sliceType);<br>
         m_numDelayedPic++;<br>
     }<br>
+    else if (m_latestParam->forceFlush == 2)<br>
+        m_lookahead->m_filled = true;<br>
     else<br>
         m_lookahead->flush();<br>
<br>
@@ -1172,6 +1185,7 @@<br>
         if (param->scalingLists && !encParam->scalingLists)<br>
             encParam->scalingLists = strdup(param->scalingLists);<br>
     }<br>
+    encParam->forceFlush = param->forceFlush;<br>
     /* To add: Loop Filter/deblocking controls, transform skip, signhide require PPS to be resent */<br>
     /* To add: SAO, temporal MVP, AMP, TU depths require SPS to be resent, at every CVS boundary */<br>
     return x265_check_params(encParam);<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp      Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/encoder/slicetype.cpp      Thu Jul 13 19:37:37 2017 +0530<br>
@@ -588,6 +588,7 @@<br>
     m_filled   = false;<br>
     m_outputSignalRequired = false;<br>
     m_isActive = true;<br>
+    m_inputCount = 0;<br>
<br>
     m_8x8Height = ((m_param->sourceHeight / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;<br>
     m_8x8Width = ((m_param->sourceWidth / 2) + X265_LOWRES_CU_SIZE - 1) >> X265_LOWRES_CU_BITS;<br>
@@ -741,23 +742,9 @@<br>
 /* Called by API thread */<br>
 void Lookahead::addPicture(Frame& curFrame, int sliceType)<br>
 {<br>
+    checkLookaheadQueue(m_<wbr>inputCount);<br>
     curFrame.m_lowres.sliceType = sliceType;<br>
-<br>
-    /* determine if the lookahead is (over) filled enough for frames to begin to<br>
-     * be consumed by frame encoders */<br>
-    if (!m_filled)<br>
-    {<br>
-        if (!m_param->bframes & !m_param->lookaheadDepth)<br>
-            m_filled = true; /* zero-latency */<br>
-        else if (curFrame.m_poc >= m_param->lookaheadDepth + 2 + m_param->bframes)<br>
-            m_filled = true; /* full capacity plus mini-gop lag */<br>
-    }<br>
-<br>
-    m_inputLock.acquire();<br>
-    m_inputQueue.pushBack(<wbr>curFrame);<br>
-    if (m_pool && m_inputQueue.size() >= m_fullQueueSize)<br>
-        tryWakeOne();<br>
-    m_inputLock.release();<br>
+    addPicture(curFrame);<br>
 }<br>
<br>
 void Lookahead::addPicture(Frame& curFrame)<br>
@@ -765,6 +752,7 @@<br>
     m_inputLock.acquire();<br>
     m_inputQueue.pushBack(<wbr>curFrame);<br>
     m_inputLock.release();<br>
+    m_inputCount++;<br>
 }<br>
<br>
 void Lookahead::<wbr>checkLookaheadQueue(int &frameCnt)<br>
@@ -793,6 +781,12 @@<br>
     m_filled = true;<br>
 }<br>
<br>
+void Lookahead::setLookaheadQueue()<br>
+{<br>
+    m_filled = false;<br>
+    m_fullQueueSize = X265_MAX(1, m_param->lookaheadDepth);<br>
+}<br>
+<br>
 void Lookahead::findJob(int /*workerThreadID*/)<br>
 {<br>
     bool doDecide;<br>
@@ -832,7 +826,10 @@<br>
         m_outputLock.release();<br>
<br>
         if (out)<br>
+        {<br>
+            m_inputCount--;<br>
             return out;<br>
+        }<br>
<br>
         findJob(-1); /* run slicetypeDecide() if necessary */<br>
<br>
@@ -843,7 +840,10 @@<br>
         if (wait)<br>
             m_outputSignal.wait();<br>
<br>
-        return m_outputQueue.popFront();<br>
+        out = m_outputQueue.popFront();<br>
+        if (out)<br>
+            m_inputCount--;<br>
+        return out;<br>
     }<br>
     else<br>
         return NULL;<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/encoder/slicetype.h<br>
--- a/source/encoder/slicetype.h        Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/encoder/slicetype.h        Thu Jul 13 19:37:37 2017 +0530<br>
@@ -120,6 +120,7 @@<br>
     int           m_cuCount;<br>
     int           m_numCoopSlices;<br>
     int           m_numRowsPerSlice;<br>
+    int           m_inputCount;<br>
     double        m_cuTreeStrength;<br>
<br>
     bool          m_isActive;<br>
@@ -151,7 +152,7 @@<br>
     Frame*  getDecidedPicture();<br>
<br>
     void    getEstimatedPictureCost(Frame *pic);<br>
-<br>
+    void    setLookaheadQueue();<br>
<br>
 protected:<br>
<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/x265.h<br>
--- a/source/x265.h     Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/x265.h     Thu Jul 13 19:37:37 2017 +0530<br>
@@ -1479,6 +1479,9 @@<br>
<br>
     /* File pointer for csv log */<br>
     FILE*     csvfpt;<br>
+<br>
+    /* Force flushing the frames from encoder */<br>
+    int       forceFlush;<br>
 } x265_param;<br>
<br>
 /* x265_param_alloc:<br>
diff -r 3f6841d271e3 -r a80bf309ef01 source/x265cli.h<br>
--- a/source/x265cli.h  Wed Jun 28 10:44:19 2017 +0530<br>
+++ b/source/x265cli.h  Thu Jul 13 19:37:37 2017 +0530<br>
@@ -280,6 +280,7 @@<br>
     { "no-dhdr10-opt",        no_argument, NULL, 0},<br>
     { "refine-mv",            no_argument, NULL, 0 },<br>
     { "no-refine-mv",         no_argument, NULL, 0 },<br>
+    { "force-flush",    required_argument, NULL, 0 },<br>
     { 0, 0, 0, 0 },<br>
     { 0, 0, 0, 0 },<br>
     { 0, 0, 0, 0 },<br>
@@ -423,6 +424,10 @@<br>
     H1("                                 Format of each line: framenumber frametype QP\n");<br>
     H1("                                 QP is optional (none lets x265 choose). Frametypes: I,i,K,P,B,b.\n");<br>
     H1("                                 QPs are restricted by qpmin/qpmax.\n");<br>
+    H1("   --force-flush <integer>       Force the encoder to flush frames. Default %d\n", param->forceFlush);<br>
+    H1("                                 0 - flush the encoder only when all the input pictures are over.\n");<br>
+    H1("                                 1 - flush all the frames even when the input is not over. Slicetype decision may change with this option.\n");<br>
+    H1("                                 2 - flush the slicetype decided frames only.\n");<br>
     H0("\nRate control, Adaptive Quantization:\n");<br>
     H0("   --bitrate <integer>           Target bitrate (kbps) for ABR (implied). Default %d\n", param->rc.bitrate);<br>
     H1("-q/--qp <integer>                QP for P slices in CQP mode (implied). --ipratio and --pbration determine other slice QPs\n");<br>
<br>______________________________<wbr>_________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/<wbr>listinfo/x265-devel</a><br>
<br></blockquote></div><br></div></div>