[FFmpeg-devel] [PATCH] libavutil/hwcontext_qsv: Command line using hwaccel 'QSV' doesn't work

Huang, Zhengxu zhengxu.maxwell at gmail.com
Tue Jan 3 09:13:09 EET 2017


-------------- next part --------------
From 687ce9c804b2618f021100235c46a33b48fa522c Mon Sep 17 00:00:00 2001
From: Zhengxu <zhengxu.maxwell at gmail.com>
Date: Wed, 14 Dec 2016 11:55:31 +0800
Subject: [PATCH] libavutil/hwcontext_qsv: Command line using hwaccel 'QSV'
 doesn't work.

Command: ffmpeg -hwaccel qsv -c:v h264_qsv -i test.264 -c:v h264_qsv out.264

Reason: hwcontext_qsv will create a child hwcontext_vaapi. VAAPI will
 open X11 display ":0.0" defaultly. However, MSDK doesn't support X11 so
 far. This results in the failure of this command.

Fix: When using VAAPI, let VAAPI try to create DRM display handle by scanning
 device nodes under '/dev/dri/'.

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>
---
 libavutil/hwcontext_qsv.c | 44 +++++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 2dc9aca..2701b5a 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -707,12 +707,41 @@ static mfxIMPL choose_implementation(const char *device)
     return impl;
 }
 
+static int create_proper_child_device(AVBufferRef **ctx, const char *device, int flags)
+{
+    enum AVHWDeviceType child_device_type;
+    char adapter[256];
+    int  adapter_num;
+
+    if (CONFIG_VAAPI)
+        child_device_type = AV_HWDEVICE_TYPE_VAAPI;
+    else if (CONFIG_DXVA2)
+        child_device_type = AV_HWDEVICE_TYPE_DXVA2;
+    else
+        return AVERROR(ENOSYS);
+
+    if (device || CONFIG_DXVA2)
+        return av_hwdevice_ctx_create(ctx, child_device_type, device, NULL, flags);
+
+    for (adapter_num = 0; adapter_num < 6; adapter_num++) {
+        if (adapter_num < 3)
+            snprintf(adapter,sizeof(adapter),
+                "/dev/dri/renderD%d", adapter_num+128);
+        else
+            snprintf(adapter,sizeof(adapter),
+                "/dev/dri/card%d", adapter_num-3);
+        if (av_hwdevice_ctx_create(ctx, child_device_type, adapter, NULL, flags) == 0)
+            return 0;
+    }
+
+    return AVERROR(ENOSYS);
+}
+
 static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
                              AVDictionary *opts, int flags)
 {
     AVQSVDeviceContext *hwctx = ctx->hwctx;
     QSVDevicePriv *priv;
-    enum AVHWDeviceType child_device_type;
     AVDictionaryEntry *e;
 
     mfxVersion    ver = { { 3, 1 } };
@@ -730,18 +759,7 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
     ctx->free        = qsv_device_free;
 
     e = av_dict_get(opts, "child_device", NULL, 0);
-
-    if (CONFIG_VAAPI)
-        child_device_type = AV_HWDEVICE_TYPE_VAAPI;
-    else if (CONFIG_DXVA2)
-        child_device_type = AV_HWDEVICE_TYPE_DXVA2;
-    else {
-        av_log(ctx, AV_LOG_ERROR, "No supported child device type is enabled\n");
-        return AVERROR(ENOSYS);
-    }
-
-    ret = av_hwdevice_ctx_create(&priv->child_device_ctx, child_device_type,
-                                 e ? e->value : NULL, NULL, 0);
+    ret = create_proper_child_device(&priv->child_device_ctx, e ? e->value : NULL, 0);
     if (ret < 0)
         return ret;
 
-- 
1.8.3.1



More information about the ffmpeg-devel mailing list