From 74007dd86a87289a075926704fae5bd8ef313bb5 Mon Sep 17 00:00:00 2001 From: Zhong Li Date: Fri, 20 Sep 2019 04:45:26 +0800 Subject: lavc/qsv: Fix MSDK initialization failure in system memory mode MSDK does not create internal acceleration device on Linux, So MFXVideoCORE_SetHandle() is necessary. It has been added for ff_qsv_init_session_device(). But missed for ff_qsv_init_internal_session() due to commit 1f26a23 overwrited commit db89f45 Fix #7030 Signed-off-by: Zhong Li --- libavcodec/qsv.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) (limited to 'libavcodec/qsv.c') diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 65ad070e1f..c4aef70b1e 100644 --- a/libavcodec/qsv.c +++ b/libavcodec/qsv.c @@ -348,7 +348,41 @@ load_plugin_fail: } -int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, +//This code is only required for Linux since a display handle is required. +//For Windows the session is complete and ready to use. + +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE +static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) +{ + AVDictionary *child_device_opts = NULL; + AVVAAPIDeviceContext *hwctx; + int ret; + + av_dict_set(&child_device_opts, "kernel_driver", "i915", 0); + av_dict_set(&child_device_opts, "driver", "iHD", 0); + + ret = av_hwdevice_ctx_create(&qs->va_device_ref, AV_HWDEVICE_TYPE_VAAPI, NULL, child_device_opts, 0); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Failed to create a VAAPI device.\n"); + return ret; + } else { + qs->va_device_ctx = (AVHWDeviceContext*)qs->va_device_ref->data; + hwctx = qs->va_device_ctx->hwctx; + + ret = MFXVideoCORE_SetHandle(qs->session, + (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)hwctx->display); + if (ret < 0) { + return ff_qsv_print_error(avctx, ret, "Error during set display handle\n"); + } + } + + av_dict_free(&child_device_opts); + + return 0; +} +#endif //AVCODEC_QSV_LINUX_SESSION_HANDLE + +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins) { mfxIMPL impl = MFX_IMPL_AUTO_ANY; @@ -357,18 +391,24 @@ int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, const char *desc; int ret; - ret = MFXInit(impl, &ver, session); + ret = MFXInit(impl, &ver, &qs->session); if (ret < 0) return ff_qsv_print_error(avctx, ret, "Error initializing an internal MFX session"); - ret = qsv_load_plugins(*session, load_plugins, avctx); +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE + ret = ff_qsv_set_display_handle(avctx, qs); + if (ret < 0) + return ret; +#endif + + ret = qsv_load_plugins(qs->session, load_plugins, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error loading plugins\n"); return ret; } - MFXQueryIMPL(*session, &impl); + MFXQueryIMPL(qs->session, &impl); switch (MFX_IMPL_BASETYPE(impl)) { case MFX_IMPL_SOFTWARE: @@ -758,3 +798,17 @@ int ff_qsv_init_session_frames(AVCodecContext *avctx, mfxSession *psession, *psession = session; return 0; } + +int ff_qsv_close_internal_session(QSVSession *qs) +{ + if (qs->session) { + MFXClose(qs->session); + qs->session = NULL; + } +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE + if (qs->va_device_ctx) { + qs->va_device_ctx->free(qs->va_device_ctx); + } +#endif + return 0; +} -- cgit v1.2.3