[vlc-commits] qsv: enqueue the QSV output packets using a FIFO

Steve Lhomme git at videolan.org
Wed Apr 4 18:28:27 CEST 2018


vlc | branch: master | Steve Lhomme <robux4 at videolabs.io> | Mon Sep  4 14:15:30 2017 +0200| [e77bbf19e48acaf853de3a6f1482867be6e2face] | committer: Steve Lhomme

qsv: enqueue the QSV output packets using a FIFO

Now we push the frame to encode first and then look in the output FIFO
for an encoded block_t ready to be used.
This is the same order of processing as ffmpeg.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=e77bbf19e48acaf853de3a6f1482867be6e2face
---

 modules/codec/qsv.c | 52 +++++++++++++++++++++++-----------------------------
 1 file changed, 23 insertions(+), 29 deletions(-)

diff --git a/modules/codec/qsv.c b/modules/codec/qsv.c
index 1774e0d45d..6808e578f7 100644
--- a/modules/codec/qsv.c
+++ b/modules/codec/qsv.c
@@ -33,6 +33,8 @@
 #include <vlc_picture.h>
 #include <vlc_codec.h>
 
+#include <vlc_fifo_helper.h>
+
 #include <mfx/mfxvideo.h>
 
 #define SOUT_CFG_PREFIX     "sout-qsv-"
@@ -269,11 +271,14 @@ typedef struct qsv_frame_pool_t
 
 typedef struct async_task_t
 {
+    fifo_item_t      fifo;
     mfxBitstream     bs;                  // Intel's bitstream structure.
     mfxSyncPoint     *syncp;              // Async Task Sync Point.
     block_t          *block;              // VLC's block structure to be returned by Encode.
 } async_task_t;
 
+TYPED_FIFO(async_task_t, async_task_t)
+
 struct encoder_sys_t
 {
     mfxSession       session;             // Intel Media SDK Session.
@@ -282,8 +287,7 @@ struct encoder_sys_t
     uint64_t         dts_warn_counter;    // DTS warning counter for rate-limiting of msg;
     uint64_t         busy_warn_counter;   // Device Busy warning counter for rate-limiting of msg;
     uint64_t         async_depth;         // Number of parallel encoding operations.
-    uint64_t         first_task;          // The next sync point to be synchronized.
-    async_task_t     *tasks;              // The async encoding tasks.
+    fifo_t           packets;             // FIFO of queued packets
     mtime_t          offset_pts;          // The pts of the first frame, to avoid conversion overflow.
     mtime_t          last_dts;            // The dts of the last frame, to interpolate over buggy dts
 };
@@ -636,9 +640,7 @@ static int Open(vlc_object_t *this)
     enc->fmt_out.i_extra = i_extra;
 
     sys->async_depth = sys->params.AsyncDepth;
-    sys->tasks = calloc(sys->async_depth, sizeof(async_task_t));
-    if (unlikely(!sys->tasks))
-        goto nomem;
+    async_task_t_fifo_Init(&sys->packets);
 
     /* Vlc module configuration */
     enc->fmt_in.i_codec                = VLC_CODEC_NV12; // Intel Media SDK requirement
@@ -670,8 +672,7 @@ static void Close(vlc_object_t *this)
     /*     free(enc->fmt_out.p_extra); */
     if (sys->frames.size)
         qsv_frame_pool_Destroy(&sys->frames);
-    if (sys->tasks)
-        free(sys->tasks);
+    async_task_t_fifo_Release(&sys->packets);
     free(sys);
 }
 
@@ -808,6 +809,8 @@ static void qsv_queue_encode_picture(encoder_t *enc, async_task_t *task,
             msg_Dbg(enc, "Encoder feeding phase, more data is needed.");
         else
             msg_Dbg(enc, "Encoder is empty");
+    else if (sts == MFX_ERR_NONE)
+        async_task_t_fifo_Put(&sys->packets, task);
     else if (sts < MFX_ERR_NONE) {
         msg_Err(enc, "Encoder not ready or error (%d), trying a reset...", sts);
         MFXVideoENCODE_Reset(sys->session, &sys->params);
@@ -828,29 +831,20 @@ static block_t *Encode(encoder_t *this, picture_t *pic)
     async_task_t  *task = NULL;
     block_t       *block = NULL;
 
-    if (pic) {
-        /* Finds an available SyncPoint */
-        for (size_t i = 0; i < sys->async_depth; i++)
-            if ((sys->tasks + (i + sys->first_task) % sys->async_depth)->syncp == 0) {
-                task = sys->tasks + (i + sys->first_task) % sys->async_depth;
-                break;
-            }
-    } else
-        /* If !pic, we are emptying encoder and tasks, so we force the SyncOperation */
-        msg_Dbg(enc, "Emptying encoder");
-
-    /* There is no available task, we need to synchronize */
-    if (!task) {
-        task = sys->tasks + sys->first_task;
-
-        block = qsv_synchronize_block( enc, task );
-
-        /* Reset the task now it has been synchronized and advances first_task pointer */
-        task->syncp = 0;
-        sys->first_task = (sys->first_task + 1) % sys->async_depth;
+    task = calloc(1, sizeof(*task));
+    if (likely(task != NULL))
+    {
+        qsv_queue_encode_picture( enc, task, pic );
+
+        if ( async_task_t_fifo_GetCount(&sys->packets) == sys->async_depth ||
+             (!pic && async_task_t_fifo_GetCount(&sys->packets)))
+        {
+            assert(async_task_t_fifo_Show(&sys->packets)->syncp != 0);
+            task = async_task_t_fifo_Get(&sys->packets);
+            block = qsv_synchronize_block( enc, task );
+            free(task);
+        }
     }
 
-    qsv_queue_encode_picture( enc, task, pic );
-
     return block;
 }



More information about the vlc-commits mailing list