[x265] [PATCH] Add force-flush param option

Divya Manivannan divya at multicorewareinc.com
Tue Jul 18 11:47:49 CEST 2017


# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1499954857 -19800
#      Thu Jul 13 19:37:37 2017 +0530
# Node ID a80bf309ef01171a7982d0fe7dfb12ce1fb9d10f
# Parent  3f6841d271e36dc324936f09846d1f2cb77c63e5
Add force-flush param option

This option will force the encoder to flush all frames without waiting for
all input pictures to arrive.

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


More information about the x265-devel mailing list