vlc | branch: master | Thomas Guillem <[email protected]> | Fri May 19 17:08:40 2017 +0200| [de5e1b946f9b66dcd00b38412fe0623beda07c13] | committer: Thomas Guillem
avcodec: vaapi: add direct rendering support > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=de5e1b946f9b66dcd00b38412fe0623beda07c13 --- modules/codec/Makefile.am | 6 +++ modules/codec/avcodec/vaapi.c | 116 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 120 insertions(+), 2 deletions(-) diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am index 8c4e86f8a9..27e0270fa3 100644 --- a/modules/codec/Makefile.am +++ b/modules/codec/Makefile.am @@ -387,6 +387,11 @@ libvaapi_x11_plugin_la_CFLAGS = $(AM_CFLAGS) \ $(LIBVA_X11_CFLAGS) $(X_CFLAGS) $(AVCODEC_CFLAGS) libvaapi_x11_plugin_la_LIBADD = $(LIBVA_X11_LIBS) $(X_LIBS) $(X_PRE_LIBS) \ -lX11 libvlc_vaapi_instance.la +libvaapi_dr_plugin_la_SOURCES = \ + codec/avcodec/vaapi.c hw/vaapi/vlc_vaapi.c hw/vaapi/vlc_vaapi.h +libvaapi_dr_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DVLC_VA_BACKEND_DR +libvaapi_dr_plugin_la_CFLAGS = $(AM_CFLAGS) $(AVCODEC_CFLAGS) +libvaapi_dr_plugin_la_LIBADD = $(LIBVA_LIBS) libvlc_vaapi_instance.la if HAVE_AVCODEC_VAAPI if HAVE_VAAPI_DRM codec_LTLIBRARIES += libvaapi_drm_plugin.la @@ -394,6 +399,7 @@ endif if HAVE_VAAPI_X11 codec_LTLIBRARIES += libvaapi_x11_plugin.la endif +codec_LTLIBRARIES += libvaapi_dr_plugin.la endif libdxva2_plugin_la_SOURCES = \ diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c index 2f0d045a05..871759a56f 100644 --- a/modules/codec/avcodec/vaapi.c +++ b/modules/codec/avcodec/vaapi.c @@ -62,7 +62,9 @@ struct vlc_va_sys_t #endif struct vaapi_context hw_ctx; +#ifndef VLC_VA_BACKEND_DR /* XLIB or DRM */ picture_pool_t *pool; +#endif }; static int GetVaProfile(AVCodecContext *ctx, VAProfile *va_profile, @@ -130,6 +132,109 @@ static int Extract(vlc_va_t *va, picture_t *pic, uint8_t *data) return VLC_SUCCESS; } +#ifdef VLC_VA_BACKEND_DR + +static int GetDR(vlc_va_t *va, picture_t *pic, uint8_t **data) +{ + (void) va; + + vlc_vaapi_PicAttachContext(pic); + *data = (void *) (uintptr_t) vlc_vaapi_PicGetSurface(pic); + + return VLC_SUCCESS; +} + +static void DeleteDR(vlc_va_t *va, AVCodecContext *avctx) +{ + vlc_va_sys_t *sys = va->sys; + vlc_object_t *o = VLC_OBJECT(va); + + (void) avctx; + + vlc_vaapi_DestroyContext(o, sys->hw_ctx.display, sys->hw_ctx.context_id); + vlc_vaapi_DestroyConfig(o, sys->hw_ctx.display, sys->hw_ctx.config_id); + vlc_vaapi_ReleaseInstance(sys->hw_ctx.display); + free(sys); +} + +static int CreateDR(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt, + const es_format_t *fmt, picture_sys_t *p_sys) +{ + if (pix_fmt != AV_PIX_FMT_VAAPI_VLD) + return VLC_EGENERIC; + + (void) fmt; + vlc_object_t *o = VLC_OBJECT(va); + + int ret = VLC_EGENERIC; + vlc_va_sys_t *sys = NULL; + + /* The picture must be allocated by the vout */ + VADisplay *va_dpy = vlc_vaapi_GetInstance(); + if (va_dpy == NULL) + return VLC_EGENERIC; + + VASurfaceID *render_targets; + unsigned num_render_targets = + vlc_vaapi_PicSysGetRenderTargets(p_sys, &render_targets); + if (num_render_targets == 0) + goto error; + + VAProfile i_profile; + unsigned count; + if (GetVaProfile(ctx, &i_profile, &count) != VLC_SUCCESS) + goto error; + + sys = malloc(sizeof *sys); + if (unlikely(sys == NULL)) + { + ret = VLC_ENOMEM; + goto error; + } + memset(sys, 0, sizeof (*sys)); + + /* */ + sys->hw_ctx.display = va_dpy; + sys->hw_ctx.config_id = VA_INVALID_ID; + sys->hw_ctx.context_id = VA_INVALID_ID; + + sys->hw_ctx.config_id = + vlc_vaapi_CreateConfigChecked(o, sys->hw_ctx.display, i_profile, + VAEntrypointVLD, VA_FOURCC_NV12); + if (sys->hw_ctx.config_id == VA_INVALID_ID) + goto error; + + /* Create a context */ + sys->hw_ctx.context_id = + vlc_vaapi_CreateContext(o, sys->hw_ctx.display, sys->hw_ctx.config_id, + ctx->coded_width, ctx->coded_height, VA_PROGRESSIVE, + render_targets, num_render_targets); + if (sys->hw_ctx.context_id == VA_INVALID_ID) + goto error; + + ctx->hwaccel_context = &sys->hw_ctx; + va->sys = sys; + va->description = vaQueryVendorString(sys->hw_ctx.display); + va->get = GetDR; + va->release = NULL; + va->extract = Extract; + return VLC_SUCCESS; + +error: + if (sys != NULL) + { + if (sys->hw_ctx.context_id != VA_INVALID_ID) + vlc_vaapi_DestroyContext(o, sys->hw_ctx.display, sys->hw_ctx.context_id); + if (sys->hw_ctx.config_id != VA_INVALID_ID) + vlc_vaapi_DestroyConfig(o, sys->hw_ctx.display, sys->hw_ctx.config_id); + free(sys); + } + vlc_vaapi_ReleaseInstance(va_dpy); + return ret; +} + +#else /* XLIB or DRM */ + static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data) { vlc_va_sys_t *sys = va->sys; @@ -308,16 +413,23 @@ error: free(sys); return VLC_EGENERIC; } +#endif vlc_module_begin () #if defined (VLC_VA_BACKEND_XLIB) set_description( N_("VA-API video decoder via X11") ) + set_capability( "hw decoder", 0 ) + set_callbacks( Create, Delete ) #elif defined (VLC_VA_BACKEND_DRM) set_description( N_("VA-API video decoder via DRM") ) -#endif set_capability( "hw decoder", 0 ) + set_callbacks( Create, Delete ) +#elif defined (VLC_VA_BACKEND_DR) + set_description( N_("VA-API direct video decoder") ) + set_capability( "hw decoder", 100 ) + set_callbacks( CreateDR, DeleteDR ) +#endif set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_VCODEC ) - set_callbacks( Create, Delete ) add_shortcut( "vaapi" ) vlc_module_end () _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
