[vlc-commits] avcodec: vaapi: add direct rendering support

Thomas Guillem git at videolan.org
Fri Jun 16 16:48:49 CEST 2017


vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | 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 ()



More information about the vlc-commits mailing list