summaryrefslogtreecommitdiff
path: root/libavcodec/qsv.c
diff options
context:
space:
mode:
authorZhong Li <zhong.li@intel.com>2019-09-20 04:45:26 +0800
committerZhong Li <zhong.li@intel.com>2019-09-26 13:44:02 +0800
commit74007dd86a87289a075926704fae5bd8ef313bb5 (patch)
treea54016ed4d1874245c468d89bb92594477bd7206 /libavcodec/qsv.c
parentb6be2be765b3f9104ca5bc9f608a934db0fc012a (diff)
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 <zhong.li@intel.com>
Diffstat (limited to 'libavcodec/qsv.c')
-rw-r--r--libavcodec/qsv.c62
1 files changed, 58 insertions, 4 deletions
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;
+}