[FFmpeg-devel] [PATCH 17/24] hwcontext_qsv: Support derivation from child devices

Mark Thompson sw at jkqxz.net
Tue Jun 13 01:40:34 EEST 2017


(cherry picked from commit aa51bb3d2756ed912ee40645efccf5f4a9609696)
---
 libavutil/hwcontext_qsv.c | 113 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 84 insertions(+), 29 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 5550ffe143..505a8e709d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -792,21 +792,96 @@ static mfxIMPL choose_implementation(const char *device)
     return impl;
 }
 
-static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
-                             AVDictionary *opts, int flags)
+static int qsv_device_derive_from_child(AVHWDeviceContext *ctx,
+                                        mfxIMPL implementation,
+                                        AVHWDeviceContext *child_device_ctx,
+                                        int flags)
 {
     AVQSVDeviceContext *hwctx = ctx->hwctx;
-    QSVDevicePriv *priv;
-    enum AVHWDeviceType child_device_type;
-    AVDictionaryEntry *e;
+    QSVDeviceContext       *s = ctx->internal->priv;
 
     mfxVersion    ver = { { 3, 1 } };
-    mfxIMPL       impl;
     mfxHDL        handle;
     mfxHandleType handle_type;
     mfxStatus     err;
     int ret;
 
+    switch (child_device_ctx->type) {
+#if CONFIG_VAAPI
+    case AV_HWDEVICE_TYPE_VAAPI:
+        {
+            AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+            handle_type = MFX_HANDLE_VA_DISPLAY;
+            handle = (mfxHDL)child_device_hwctx->display;
+        }
+        break;
+#endif
+#if CONFIG_DXVA2
+    case AV_HWDEVICE_TYPE_DXVA2:
+        {
+            AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
+            handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
+            handle = (mfxHDL)child_device_hwctx->devmgr;
+        }
+        break;
+#endif
+    default:
+        ret = AVERROR(ENOSYS);
+        goto fail;
+    }
+
+    err = MFXInit(implementation, &ver, &hwctx->session);
+    if (err != MFX_ERR_NONE) {
+        av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session: "
+               "%d.\n", err);
+        ret = AVERROR_UNKNOWN;
+        goto fail;
+    }
+
+    err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
+    if (err != MFX_ERR_NONE) {
+        av_log(ctx, AV_LOG_ERROR, "Error setting child device handle: "
+               "%d\n", err);
+        ret = AVERROR_UNKNOWN;
+        goto fail;
+    }
+
+    ret = qsv_device_init(ctx);
+    if (ret < 0)
+        goto fail;
+    if (s->handle_type != handle_type) {
+        av_log(ctx, AV_LOG_ERROR, "Error in child device handle setup: "
+               "type mismatch (%d != %d).\n", s->handle_type, handle_type);
+        err = AVERROR_UNKNOWN;
+        goto fail;
+    }
+
+    return 0;
+
+fail:
+    if (hwctx->session)
+        MFXClose(hwctx->session);
+    return ret;
+}
+
+static int qsv_device_derive(AVHWDeviceContext *ctx,
+                             AVHWDeviceContext *child_device_ctx, int flags)
+{
+    return qsv_device_derive_from_child(ctx, MFX_IMPL_HARDWARE_ANY,
+                                        child_device_ctx, flags);
+}
+
+static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
+                             AVDictionary *opts, int flags)
+{
+    QSVDevicePriv *priv;
+    enum AVHWDeviceType child_device_type;
+    AVHWDeviceContext *child_device;
+    AVDictionaryEntry *e;
+
+    mfxIMPL impl;
+    int ret;
+
     priv = av_mallocz(sizeof(*priv));
     if (!priv)
         return AVERROR(ENOMEM);
@@ -830,32 +905,11 @@ static int qsv_device_create(AVHWDeviceContext *ctx, const char *device,
     if (ret < 0)
         return ret;
 
-    {
-        AVHWDeviceContext      *child_device_ctx = (AVHWDeviceContext*)priv->child_device_ctx->data;
-#if CONFIG_VAAPI
-        AVVAAPIDeviceContext *child_device_hwctx = child_device_ctx->hwctx;
-        handle_type = MFX_HANDLE_VA_DISPLAY;
-        handle = (mfxHDL)child_device_hwctx->display;
-#elif CONFIG_DXVA2
-        AVDXVA2DeviceContext *child_device_hwctx = child_device_ctx->hwctx;
-        handle_type = MFX_HANDLE_D3D9_DEVICE_MANAGER;
-        handle = (mfxHDL)child_device_hwctx->devmgr;
-#endif
-    }
+    child_device = (AVHWDeviceContext*)priv->child_device_ctx->data;
 
     impl = choose_implementation(device);
 
-    err = MFXInit(impl, &ver, &hwctx->session);
-    if (err != MFX_ERR_NONE) {
-        av_log(ctx, AV_LOG_ERROR, "Error initializing an MFX session\n");
-        return AVERROR_UNKNOWN;
-    }
-
-    err = MFXVideoCORE_SetHandle(hwctx->session, handle_type, handle);
-    if (err != MFX_ERR_NONE)
-        return AVERROR_UNKNOWN;
-
-    return 0;
+    return qsv_device_derive_from_child(ctx, impl, child_device, 0);
 }
 
 const HWContextType ff_hwcontext_type_qsv = {
@@ -868,6 +922,7 @@ const HWContextType ff_hwcontext_type_qsv = {
     .frames_priv_size       = sizeof(QSVFramesContext),
 
     .device_create          = qsv_device_create,
+    .device_derive          = qsv_device_derive,
     .device_init            = qsv_device_init,
     .frames_get_constraints = qsv_frames_get_constraints,
     .frames_init            = qsv_frames_init,
-- 
2.11.0



More information about the ffmpeg-devel mailing list