From patchwork Thu Sep 19 20:45:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhong Li X-Patchwork-Id: 15178 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 14C154470F3 for ; Fri, 20 Sep 2019 07:04:05 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id F1C8A68A0FC; Fri, 20 Sep 2019 07:04:04 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 34345689FB2 for ; Fri, 20 Sep 2019 07:03:58 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Sep 2019 21:03:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,527,1559545200"; d="scan'208";a="194584234" Received: from blue-kbl.sh.intel.com ([10.239.13.99]) by FMSMGA003.fm.intel.com with ESMTP; 19 Sep 2019 21:03:55 -0700 From: Zhong Li To: ffmpeg-devel@ffmpeg.org Date: Fri, 20 Sep 2019 04:45:26 +0800 Message-Id: <20190919204527.20194-2-zhong.li@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190919204527.20194-1-zhong.li@intel.com> References: <20190919204527.20194-1-zhong.li@intel.com> Subject: [FFmpeg-devel] [PATCH 2/3] lavc/qsv: Fix MSDK initialization failure in system memory mode X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Zhong Li MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 ++++++++++++++++++++++++++++++++++++--- libavcodec/qsv_internal.h | 28 +++++++++++++++++- libavcodec/qsvdec.c | 29 +++++++++--------- libavcodec/qsvdec.h | 2 +- libavcodec/qsvenc.c | 17 +++++------ libavcodec/qsvenc.h | 2 +- 6 files changed, 109 insertions(+), 31 deletions(-) diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c index 65ad070e1f..87ff694030 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; +} diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index c50e9c792c..62885134b1 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -21,6 +21,22 @@ #ifndef AVCODEC_QSV_INTERNAL_H #define AVCODEC_QSV_INTERNAL_H +#if CONFIG_VAAPI +#define AVCODEC_QSV_LINUX_SESSION_HANDLE +#endif //CONFIG_VAAPI + +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE +#include +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include "libavutil/hwcontext_vaapi.h" +#endif + #include #include "libavutil/frame.h" @@ -64,6 +80,14 @@ typedef struct QSVFrame { struct QSVFrame *next; } QSVFrame; +typedef struct QSVSession { + mfxSession session; +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE + AVBufferRef *va_device_ref; + AVHWDeviceContext *va_device_ctx; +#endif +} QSVSession; + typedef struct QSVFramesContext { AVBufferRef *hw_frames_ctx; void *logctx; @@ -99,9 +123,11 @@ enum AVPictureType ff_qsv_map_pictype(int mfx_pic_type); enum AVFieldOrder ff_qsv_map_picstruct(int mfx_pic_struct); -int ff_qsv_init_internal_session(AVCodecContext *avctx, mfxSession *session, +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins); +int ff_qsv_close_internal_session(QSVSession *qs); + int ff_qsv_init_session_device(AVCodecContext *avctx, mfxSession *psession, AVBufferRef *device_ref, const char *load_plugins); diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index eef4fe7138..2fce478d63 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -62,9 +62,9 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses if (session) { q->session = session; } else if (hw_frames_ref) { - if (q->internal_session) { - MFXClose(q->internal_session); - q->internal_session = NULL; + if (q->internal_qs.session) { + MFXClose(q->internal_qs.session); + q->internal_qs.session = NULL; } av_buffer_unref(&q->frames_ctx.hw_frames_ctx); @@ -72,7 +72,7 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses if (!q->frames_ctx.hw_frames_ctx) return AVERROR(ENOMEM); - ret = ff_qsv_init_session_frames(avctx, &q->internal_session, + ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, q->iopattern == MFX_IOPATTERN_OUT_OPAQUE_MEMORY); if (ret < 0) { @@ -80,28 +80,28 @@ static int qsv_init_session(AVCodecContext *avctx, QSVContext *q, mfxSession ses return ret; } - q->session = q->internal_session; + q->session = q->internal_qs.session; } else if (hw_device_ref) { - if (q->internal_session) { - MFXClose(q->internal_session); - q->internal_session = NULL; + if (q->internal_qs.session) { + MFXClose(q->internal_qs.session); + q->internal_qs.session = NULL; } - ret = ff_qsv_init_session_device(avctx, &q->internal_session, + ret = ff_qsv_init_session_device(avctx, &q->internal_qs.session, hw_device_ref, q->load_plugins); if (ret < 0) return ret; - q->session = q->internal_session; + q->session = q->internal_qs.session; } else { - if (!q->internal_session) { - ret = ff_qsv_init_internal_session(avctx, &q->internal_session, + if (!q->internal_qs.session) { + ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, q->load_plugins); if (ret < 0) return ret; } - q->session = q->internal_session; + q->session = q->internal_qs.session; } /* make sure the decoder is uninitialized */ @@ -529,8 +529,7 @@ int ff_qsv_decode_close(QSVContext *q) av_fifo_free(q->async_fifo); q->async_fifo = NULL; - if (q->internal_session) - MFXClose(q->internal_session); + ff_qsv_close_internal_session(&q->internal_qs); av_buffer_unref(&q->frames_ctx.hw_frames_ctx); av_buffer_unref(&q->frames_ctx.mids_buf); diff --git a/libavcodec/qsvdec.h b/libavcodec/qsvdec.h index c057bc6722..64dc8d2f47 100644 --- a/libavcodec/qsvdec.h +++ b/libavcodec/qsvdec.h @@ -42,7 +42,7 @@ typedef struct QSVContext { // the session we allocated internally, in case the caller did not provide // one - mfxSession internal_session; + QSVSession internal_qs; QSVFramesContext frames_ctx; diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index 9bf8574e30..207cdc1d61 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -954,7 +954,7 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) if (!q->frames_ctx.hw_frames_ctx) return AVERROR(ENOMEM); - ret = ff_qsv_init_session_frames(avctx, &q->internal_session, + ret = ff_qsv_init_session_frames(avctx, &q->internal_qs.session, &q->frames_ctx, q->load_plugins, q->param.IOPattern == MFX_IOPATTERN_IN_OPAQUE_MEMORY); if (ret < 0) { @@ -962,21 +962,21 @@ static int qsvenc_init_session(AVCodecContext *avctx, QSVEncContext *q) return ret; } - q->session = q->internal_session; + q->session = q->internal_qs.session; } else if (avctx->hw_device_ctx) { - ret = ff_qsv_init_session_device(avctx, &q->internal_session, + ret = ff_qsv_init_session_device(avctx, &q->internal_qs.session, avctx->hw_device_ctx, q->load_plugins); if (ret < 0) return ret; - q->session = q->internal_session; + q->session = q->internal_qs.session; } else { - ret = ff_qsv_init_internal_session(avctx, &q->internal_session, + ret = ff_qsv_init_internal_session(avctx, &q->internal_qs, q->load_plugins); if (ret < 0) return ret; - q->session = q->internal_session; + q->session = q->internal_qs.session; } return 0; @@ -1507,10 +1507,9 @@ int ff_qsv_enc_close(AVCodecContext *avctx, QSVEncContext *q) if (q->session) MFXVideoENCODE_Close(q->session); - if (q->internal_session) - MFXClose(q->internal_session); + q->session = NULL; - q->internal_session = NULL; + ff_qsv_close_internal_session(&q->internal_qs); av_buffer_unref(&q->frames_ctx.hw_frames_ctx); av_buffer_unref(&q->frames_ctx.mids_buf); diff --git a/libavcodec/qsvenc.h b/libavcodec/qsvenc.h index f2f4d38503..ec8b5419cb 100644 --- a/libavcodec/qsvenc.h +++ b/libavcodec/qsvenc.h @@ -102,7 +102,7 @@ typedef struct QSVEncContext { QSVFrame *work_frames; mfxSession session; - mfxSession internal_session; + QSVSession internal_qs; int packet_size; int width_align;