---
 libavutil/hwcontext_qsv.c | 122 +++++++++++++++++++++++++++++++++++-----------
 1 file changed, 93 insertions(+), 29 deletions(-)

diff --git a/libavutil/hwcontext_qsv.c b/libavutil/hwcontext_qsv.c
index 3409e9b97..2d202017d 100644
--- a/libavutil/hwcontext_qsv.c
+++ b/libavutil/hwcontext_qsv.c
@@ -792,19 +792,103 @@ 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;
+    enum AVPixelFormat child_pix_fmt;
+    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;
+            child_pix_fmt = AV_PIX_FMT_VAAPI;
+        }
+        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;
+            child_pix_fmt = AV_PIX_FMT_DXVA2_VLD;
+        }
+        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;
+    }
+
+    s->handle            = handle;
+    s->handle_type       = handle_type;
+    s->child_device_type = child_device_ctx->type;
+    s->child_pix_fmt     = child_pix_fmt;
+
+    err = MFXQueryIMPL(hwctx->session, &s->impl);
+    if (err == MFX_ERR_NONE)
+        err = MFXQueryVersion(hwctx->session, &s->ver);
+    if (err != MFX_ERR_NONE) {
+        av_log(ctx, AV_LOG_ERROR, "Error querying the session attributes: "
+               "%d\n", err);
+        ret = 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));
@@ -830,32 +914,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 +931,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

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to