[FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK initialization failure in system memory mode
Mark Thompson
sw at jkqxz.net
Wed Sep 11 01:58:26 EEST 2019
On 04/09/2019 16:40, Zhong Li wrote:
> 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
Huh. I think I see the problem - the standalone dispatcher does try to create a VA connection to fix common cases on simple devices (<https://github.com/lu-zero/mfx_dispatch/blob/master/src/mfx_va_glue.c>), but that seems to have been lost in the full open source media SDK.
Given that the D3D code does find a device automatically it's tempting to suggest that this should be fixed on the media SDK side instead for consistency, but I don't really mind.
> Signed-off-by: Zhong Li <zhong.li at intel.com>
> ---
> libavcodec/qsv.c | 105 ++++++++++++++++++++++++++++++++++++++++++++--
> libavcodec/qsv_internal.h | 27 +++++++++++-
> libavcodec/qsvdec.c | 29 +++++++------
> libavcodec/qsvdec.h | 2 +-
> libavcodec/qsvenc.c | 17 ++++----
> libavcodec/qsvenc.h | 2 +-
> 6 files changed, 151 insertions(+), 31 deletions(-)
>
> diff --git a/libavcodec/qsv.c b/libavcodec/qsv.c
> index 65ad070..126182b 100644
> --- a/libavcodec/qsv.c
> +++ b/libavcodec/qsv.c
> @@ -348,7 +348,79 @@ 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.
> +//For releases of Media Server Studio >= 2015 R4 the
> +//render nodes interface is preferred (/dev/dri/renderD).
> +//Using Media Server Studio 2015 R4 or newer is recommended
> +//but the older /dev/dri/card interface is also searched for broader compatibility.
> +
> +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE
> +static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs)
> +{
> + // VAAPI display handle
> + int ret = 0;
> + VADisplay va_dpy = NULL;
> + VAStatus va_res = VA_STATUS_SUCCESS;
> + int major_version = 0, minor_version = 0;
> + int fd = -1;
> + char adapterpath[256];
> + int adapter_num;
> +
> + qs->fd_display = -1;
> + qs->va_display = NULL;
> +
> + //search for valid graphics device
> + for (adapter_num = 0;adapter_num < 6;adapter_num++) {
> +
> + if (adapter_num<3) {
> + snprintf(adapterpath,sizeof(adapterpath),
> + "/dev/dri/renderD%d", adapter_num+128);
> + } else {
> + snprintf(adapterpath,sizeof(adapterpath),
> + "/dev/dri/card%d", adapter_num-3);
> + }
> +
> + fd = open(adapterpath, O_RDWR);
> + if (fd < 0) {
> + av_log(avctx, AV_LOG_ERROR,
> + "mfx init: %s fd open failed\n", adapterpath);
> + continue;
> + }
> +
> + va_dpy = vaGetDisplayDRM(fd);
> + if (!va_dpy) {
> + av_log(avctx, AV_LOG_ERROR,
> + "mfx init: %s vaGetDisplayDRM failed\n", adapterpath);
> + close(fd);
> + continue;
> + }
> +
> + va_res = vaInitialize(va_dpy, &major_version, &minor_version);
> + if (VA_STATUS_SUCCESS != va_res) {
> + av_log(avctx, AV_LOG_ERROR,
> + "mfx init: %s vaInitialize failed\n", adapterpath);
> + close(fd);
> + fd = -1;
> + continue;
Just call av_hwdevice_ctx_create(VAAPI, { "kernel_driver": "i915", "driver": "iHD" }) like hwcontext_qsv does rather than writing an incomplete copy.
> + } else {
> + av_log(avctx, AV_LOG_VERBOSE,
> + "mfx initialization: %s vaInitialize successful\n",adapterpath);
> + qs->fd_display = fd;
> + qs->va_display = va_dpy;
> + ret = MFXVideoCORE_SetHandle(qs->session,
> + (mfxHandleType)MFX_HANDLE_VA_DISPLAY, (mfxHDL)va_dpy);
> + if (ret < 0) {
> + return ff_qsv_print_error(avctx, ret, "Error %d during set display handle\n");
> + }
> + break;
> + }
> + }
> + return 0;
> +}
> +#endif //AVCODEC_QSV_LINUX_SESSION_HANDLE
> +
> ...
For the rest, probably ok?
All of the session setup stuff is rather horrible, though - it would be nice if we could push more of it into hwcontext_qsv instead of messing with the sessions like this in lavc. Can we turn the no-device-provided case into approximately the same as an hw_device_ctx case by just calling av_hwdevice_ctx_create() early on? (That would avoid this code entirely, since hwcontext_qsv always creates a subdevice.)
- Mark
More information about the ffmpeg-devel
mailing list