Message ID | 1567611642-11353-1-git-send-email-zhong.li@intel.com |
---|---|
State | New |
Headers | show |
> -----Original Message----- > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf > Of Zhong Li > Sent: Wednesday, September 4, 2019 23:41 > To: ffmpeg-devel@ffmpeg.org > Cc: Li, Zhong <zhong.li@intel.com> > Subject: [FFmpeg-devel] [PATCH 1/2] 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> > --- > 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; > + } 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 > + > +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, > const char *load_plugins) > { > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > @@ -357,18 +429,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 I think one "#ifdef" check may be good enough for ff_qsv_set_display_handle, but current version is also ok. Patch LGTM referring to commit 1f26a23. And also verified it works on both Linux and Windows. - linjie
> From: Fu, Linjie > Sent: Thursday, September 5, 2019 10:54 AM > To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> > Cc: Li, Zhong <zhong.li@intel.com> > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK initialization failure > in system memory mode > > > -----Original Message----- > > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf > > Of Zhong Li > > Sent: Wednesday, September 4, 2019 23:41 > > To: ffmpeg-devel@ffmpeg.org > > Cc: Li, Zhong <zhong.li@intel.com> > > Subject: [FFmpeg-devel] [PATCH 1/2] 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> > > --- > > 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; > > + } 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 > > + > > +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession > > +*qs, > > const char *load_plugins) { > > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > > @@ -357,18 +429,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 > > I think one "#ifdef" check may be good enough for ff_qsv_set_display_handle, but > current version is also ok. If I understand your point, you mean that: #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) ... #endif ret = ff_qsv_set_display_handle(avctx, qs); if (ret < 0) return ret; Right? If so, it will definitely cause compile error on Windows since ff_qsv_set_display_handle is not defined. > Patch LGTM referring to commit 1f26a23. > And also verified it works on both Linux and Windows. Great! Thanks > > - linjie
> -----Original Message----- > From: Li, Zhong > Sent: Thursday, September 5, 2019 11:14 > To: Fu, Linjie <linjie.fu@intel.com>; FFmpeg development discussions and > patches <ffmpeg-devel@ffmpeg.org> > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK initialization > failure in system memory mode > > > From: Fu, Linjie > > Sent: Thursday, September 5, 2019 10:54 AM > > To: FFmpeg development discussions and patches <ffmpeg- > devel@ffmpeg.org> > > Cc: Li, Zhong <zhong.li@intel.com> > > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK initialization > failure > > in system memory mode > > > > > -----Original Message----- > > > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On > Behalf > > > Of Zhong Li > > > Sent: Wednesday, September 4, 2019 23:41 > > > To: ffmpeg-devel@ffmpeg.org > > > Cc: Li, Zhong <zhong.li@intel.com> > > > Subject: [FFmpeg-devel] [PATCH 1/2] 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> > > > --- > > > 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; > > > + } 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 > > > + > > > +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession > > > +*qs, > > > const char *load_plugins) { > > > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > > > @@ -357,18 +429,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 > > > > I think one "#ifdef" check may be good enough for > ff_qsv_set_display_handle, but > > current version is also ok. > > If I understand your point, you mean that: > > #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE static int > ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession > *qs) > ... > #endif > > ret = ff_qsv_set_display_handle(avctx, qs); > if (ret < 0) > return ret; > > Right? > If so, it will definitely cause compile error on Windows since > ff_qsv_set_display_handle is not defined. > Not really, how about check inside the function: Static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) { #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE ... #endif return 0; } ret = ff_qsv_set_display_handle(avctx, qs); if (ret < 0) return ret; - linjie
> From: Fu, Linjie > Sent: Thursday, September 5, 2019 12:07 PM > To: Li, Zhong <zhong.li@intel.com>; FFmpeg development discussions and patches > <ffmpeg-devel@ffmpeg.org> > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK initialization failure > in system memory mode > > > -----Original Message----- > > From: Li, Zhong > > Sent: Thursday, September 5, 2019 11:14 > > To: Fu, Linjie <linjie.fu@intel.com>; FFmpeg development discussions > > and patches <ffmpeg-devel@ffmpeg.org> > > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK > > initialization failure in system memory mode > > > > > From: Fu, Linjie > > > Sent: Thursday, September 5, 2019 10:54 AM > > > To: FFmpeg development discussions and patches <ffmpeg- > > devel@ffmpeg.org> > > > Cc: Li, Zhong <zhong.li@intel.com> > > > Subject: RE: [FFmpeg-devel] [PATCH 1/2] lavc/qsv: Fix MSDK > > > initialization > > failure > > > in system memory mode > > > > > > > -----Original Message----- > > > > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On > > Behalf > > > > Of Zhong Li > > > > Sent: Wednesday, September 4, 2019 23:41 > > > > To: ffmpeg-devel@ffmpeg.org > > > > Cc: Li, Zhong <zhong.li@intel.com> > > > > Subject: [FFmpeg-devel] [PATCH 1/2] 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> > > > > --- > > > > 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; > > > > + } 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 > > > > + > > > > +int ff_qsv_init_internal_session(AVCodecContext *avctx, > > > > +QSVSession *qs, > > > > const char *load_plugins) { > > > > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > > > > @@ -357,18 +429,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 > > > > > > I think one "#ifdef" check may be good enough for > > ff_qsv_set_display_handle, but > > > current version is also ok. > > > > If I understand your point, you mean that: > > > > #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE static int > > ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession > > *qs) > > ... > > #endif > > > > ret = ff_qsv_set_display_handle(avctx, qs); if (ret < 0) return ret; > > > > Right? > > If so, it will definitely cause compile error on Windows since > > ff_qsv_set_display_handle is not defined. > > > > Not really, how about check inside the function: > > Static int ff_qsv_set_display_handle(AVCodecContext *avctx, QSVSession *qs) > { #ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE ... > #endif This is not efficient for Windows, ff_qsv_set_display_handle will be called but do nothing, thus why I use current way.
> From: Li, Zhong > Sent: Wednesday, September 4, 2019 11:41 PM > To: ffmpeg-devel@ffmpeg.org > Cc: Li, Zhong <zhong.li@intel.com> > Subject: [PATCH 1/2] 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> > --- > 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; > + } 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 > + > +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, > const char *load_plugins) { > mfxIMPL impl = MFX_IMPL_AUTO_ANY; > @@ -357,18 +429,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 +836,22 @@ 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_display) { > + vaTerminate(qs->va_display); > + qs->va_display = NULL; > + } > + if (qs->fd_display > 0) { > + close(qs->fd_display); > + qs->fd_display = -1; > + } > +#endif > + return 0; > +} > diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index > c50e9c7..7678114 100644 > --- a/libavcodec/qsv_internal.h > +++ b/libavcodec/qsv_internal.h > @@ -21,6 +21,21 @@ > #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 <stdio.h> #include > +<string.h> #if HAVE_UNISTD_H #include <unistd.h> #endif #include > +<fcntl.h> #include <va/va.h> #include <va/va_drm.h> #endif > + > #include <mfx/mfxvideo.h> > > #include "libavutil/frame.h" > @@ -64,6 +79,14 @@ typedef struct QSVFrame { > struct QSVFrame *next; > } QSVFrame; > > +typedef struct QSVSession { > + mfxSession session; > +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE > + int fd_display; > + VADisplay va_display; > +#endif > +} QSVSession; > + > typedef struct QSVFramesContext { > AVBufferRef *hw_frames_ctx; > void *logctx; > @@ -99,9 +122,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 eef4fe7..2fce478 > 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 c057bc6..64dc8d2 > 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 9bf8574..207cdc1 > 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 f2f4d38..ec8b541 > 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; > -- > 2.7.4 Will apply if no objection.
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@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
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; + } 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 + +int ff_qsv_init_internal_session(AVCodecContext *avctx, QSVSession *qs, const char *load_plugins) { mfxIMPL impl = MFX_IMPL_AUTO_ANY; @@ -357,18 +429,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 +836,22 @@ 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_display) { + vaTerminate(qs->va_display); + qs->va_display = NULL; + } + if (qs->fd_display > 0) { + close(qs->fd_display); + qs->fd_display = -1; + } +#endif + return 0; +} diff --git a/libavcodec/qsv_internal.h b/libavcodec/qsv_internal.h index c50e9c7..7678114 100644 --- a/libavcodec/qsv_internal.h +++ b/libavcodec/qsv_internal.h @@ -21,6 +21,21 @@ #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 <stdio.h> +#include <string.h> +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <fcntl.h> +#include <va/va.h> +#include <va/va_drm.h> +#endif + #include <mfx/mfxvideo.h> #include "libavutil/frame.h" @@ -64,6 +79,14 @@ typedef struct QSVFrame { struct QSVFrame *next; } QSVFrame; +typedef struct QSVSession { + mfxSession session; +#ifdef AVCODEC_QSV_LINUX_SESSION_HANDLE + int fd_display; + VADisplay va_display; +#endif +} QSVSession; + typedef struct QSVFramesContext { AVBufferRef *hw_frames_ctx; void *logctx; @@ -99,9 +122,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 eef4fe7..2fce478 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 c057bc6..64dc8d2 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 9bf8574..207cdc1 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 f2f4d38..ec8b541 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;
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> --- 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(-)