[FFmpeg-devel] [PATCH 2/2] libavcodec/qsvenc: Fix the encode part hwaccle issue when using system memory

Huang, Zhengxu zhengxu.maxwell at gmail.com
Mon Jan 9 04:10:13 EET 2017


-------------- next part --------------
From 256dd95eded93894c01e67648eec41d05e35d64e Mon Sep 17 00:00:00 2001
From: Zhengxu <zhengxu.maxwell at gmail.com>
Date: Mon, 19 Dec 2016 03:39:39 -0500
Subject: [PATCH 2/2] libavcodec/qsvenc: Fix the encode part hwaccle issue when
 using system memory

Description: when using system memory the encode actually uses the
PARTIAL_ACCELERATION which means the SW encoder of MSDK. And the performance
will quite poor compared with the HW MSDK.
eg: ./ffmpeg -c:v h264 -i in -c:v h264_qsv  output.h264

Fix: Use the HWContext to get the vaDisplay and configure the encode to HW
mode. The performance will be improved significantly

Signed-off-by: ChaoX A Liu <chaox.a.liu at gmail.com>
Signed-off-by: Huang, Zhengxu <zhengxu.maxwell at gmail.com>
Signed-off-by: Andrew, Zhang <huazh407 at gmail.com>
---
 libavcodec/qsvenc.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 libavcodec/qsvenc.h |  2 +-
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c
index ac443c1..1ce2c3c 100644
--- a/libavcodec/qsvenc.c
+++ b/libavcodec/qsvenc.c
@@ -651,6 +651,56 @@ static int qsv_init_opaque_alloc(AVCodecContext *avctx, QSVEncContext *q)
     return 0;
 }
 
+static int qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session,
+                                 QSVEncContext *q, const char *load_plugins)
+{
+    mfxIMPL impl   = MFX_IMPL_AUTO_ANY;
+    const char *desc;
+    int ret;
+    AVHWDeviceContext *device_hw;
+    AVQSVDeviceContext *hwctx;
+    AVBufferRef *hw_device_ctx;
+
+    ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, NULL, 0);
+    if (ret < 0) {
+        av_log(NULL, AV_LOG_ERROR, "Failed to create a QSV device\n");
+        return ret;
+    }
+    device_hw = (AVHWDeviceContext*)hw_device_ctx->data;
+    hwctx = device_hw->hwctx;
+
+    *session = hwctx->session;
+
+    q->device_ctx.hw_device_ctx = hw_device_ctx;
+
+    ret = ff_qsv_load_plugins(*session, load_plugins, avctx);
+    if (ret < 0) {
+        av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n");
+        return ret;
+    }
+    MFXQueryIMPL(*session, &impl);
+
+    switch (MFX_IMPL_BASETYPE(impl)) {
+    case MFX_IMPL_SOFTWARE:
+        desc = "software";
+        break;
+    case MFX_IMPL_HARDWARE:
+    case MFX_IMPL_HARDWARE2:
+    case MFX_IMPL_HARDWARE3:
+    case MFX_IMPL_HARDWARE4:
+        desc = "hardware accelerated";
+        break;
+    default:
+        desc = "unknown";
+    }
+
+    av_log(avctx, AV_LOG_VERBOSE,
+           "Initialized an internal MFX session using %s implementation\n",
+           desc);
+
+    return 0;
+}
+
 static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
 {
     int ret;
@@ -673,12 +723,12 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q)
 
         q->session = q->internal_session;
     } else {
-        ret = ff_qsv_init_internal_session(avctx, &q->internal_session,
+        ret = qsv_init_internal_session(avctx, &q->session, q,
                                            q->load_plugins);
         if (ret < 0)
             return ret;
 
-        q->session = q->internal_session;
+       // q->session = q->internal_session;
     }
 
     return 0;
@@ -1088,6 +1138,7 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q)
     q->internal_session = NULL;
 
     av_buffer_unref(&q->frames_ctx.hw_frames_ctx);
+    av_buffer_unref(&q->device_ctx.hw_device_ctx);
     av_freep(&q->frames_ctx.mids);
     q->frames_ctx.nb_mids = 0;
 
diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h
index 361d933..d377ea4 100644
--- a/libavcodec/qsvenc.h
+++ b/libavcodec/qsvenc.h
@@ -105,7 +105,7 @@ typedef struct QSVEncContext {
     AVFifoBuffer *async_fifo;
 
     QSVFramesContext frames_ctx;
-
+    QSVDeviceContext device_ctx;
     // options set by the caller
     int async_depth;
     int idr_interval;
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list