[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