From aa51bb3d2756ed912ee40645efccf5f4a9609696 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Sat, 4 Mar 2017 23:57:43 +0000 Subject: [PATCH] hwcontext_qsv: Support derivation from child devices --- 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 3409e9b976..46636ef9eb 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,