[vlc-devel] [PATCH 2/2] vaapi: Use vlc_instance_holder instead of the instance shared library

Hugo Beauzée-Luyssen hugo at beauzee.fr
Sat Jul 1 11:22:26 CEST 2017


---
 modules/codec/avcodec/vaapi.c                 | 92 ++++++++++++++++++++------
 modules/hw/vaapi/Makefile.am                  | 11 +---
 modules/hw/vaapi/chroma.c                     | 13 ++--
 modules/hw/vaapi/filters.c                    |  9 ++-
 modules/hw/vaapi/instance.c                   | 93 ---------------------------
 modules/hw/vaapi/vlc_vaapi.c                  |  8 ++-
 modules/hw/vaapi/vlc_vaapi.h                  | 18 ++----
 modules/video_output/opengl/converter_vaapi.c | 87 +++++++++++++++++--------
 8 files changed, 161 insertions(+), 170 deletions(-)
 delete mode 100644 modules/hw/vaapi/instance.c

diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 4f46802400..f9ae5edff4 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -33,6 +33,7 @@
 #include <vlc_fourcc.h>
 #include <vlc_picture.h>
 #include <vlc_picture_pool.h>
+#include <vlc_instance_holder.h>
 
 #ifdef VLC_VA_BACKEND_XLIB
 # include <vlc_xlib.h>
@@ -67,6 +68,12 @@ struct vlc_va_sys_t
 #endif
 };
 
+typedef struct vlc_va_instance_ctx
+{
+    vlc_object_t* p_obj;
+    vlc_va_sys_t* p_sys;
+} vlc_va_instance_ctx;
+
 static int GetVaProfile(AVCodecContext *ctx, VAProfile *va_profile,
                         unsigned *pic_count)
 {
@@ -147,7 +154,7 @@ static void DeleteDR(vlc_va_t *va, void *hwctx)
 
     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);
+    vlc_instance_holder_release( VLC_OBJECT( va ), "vaapi-instance" );
     free(sys);
 }
 
@@ -164,7 +171,8 @@ static int CreateDR(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     vlc_va_sys_t *sys = NULL;
 
     /* The picture must be allocated by the vout */
-    VADisplay *va_dpy = vlc_vaapi_GetInstance();
+    VADisplay *va_dpy = vlc_instance_holder_get( VLC_OBJECT( va ),
+                                                          "vaapi-instance" );
     if (va_dpy == NULL)
         return VLC_EGENERIC;
 
@@ -221,7 +229,7 @@ error:
             vlc_vaapi_DestroyConfig(o, sys->hw_ctx.display, sys->hw_ctx.config_id);
         free(sys);
     }
-    vlc_vaapi_ReleaseInstance(va_dpy);
+    vlc_instance_holder_release( VLC_OBJECT( va ), "vaapi-instance" );
     return ret;
 }
 
@@ -254,7 +262,7 @@ static void Delete(vlc_va_t *va, void **hwctx)
     picture_pool_Release(sys->pool);
     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);
+    vlc_instance_holder_release( VLC_OBJECT( va ), "vaapi-instance" );
 #ifdef VLC_VA_BACKEND_XLIB
     XCloseDisplay(sys->p_display_x11);
 #endif
@@ -264,6 +272,49 @@ static void Delete(vlc_va_t *va, void **hwctx)
     free(sys);
 }
 
+static void* CreateVaDisplayInstance( VADisplay* p_display,
+                                      vlc_va_instance_ctx* p_ctx )
+{
+    if (p_display == NULL)
+    {
+        msg_Err(p_ctx->p_obj, "Could not get a VAAPI device");
+        return NULL;
+    }
+
+    if (vlc_vaapi_Initialize(p_ctx->p_obj, p_display))
+    {
+        msg_Err(p_ctx->p_obj, "Could not initialize VA display" );
+        vaTerminate( p_display );
+        return NULL;
+    }
+    return p_display;
+}
+
+#ifdef VLC_VA_BACKEND_XLIB
+static void* CreateVaDisplayInstanceX11( void* p_opaque )
+{
+    vlc_va_instance_ctx* p_ctx = (vlc_va_instance_ctx*)p_opaque;
+    return CreateVaDisplayInstance( vaGetDisplay( p_ctx->p_sys->p_display_x11),
+                                    p_ctx );
+}
+#endif
+
+#ifdef VLC_VA_BACKEND_DRM
+static void* CreateVaDisplayInstanceDRM( void* p_opaque )
+{
+    vlc_va_instance_ctx* p_ctx = (vlc_va_instance_ctx*)p_opaque;
+    return CreateVaDisplayInstance( vaGetDisplayDRM(p_ctx->p_sys->drm_fd ),
+                                    p_ctx );
+}
+#endif
+
+
+static void DestroyVaDisplayInstance( void* p_instance, void* p_ctx )
+{
+    vaTerminate( (VADisplay)p_instance );
+    free( p_ctx );
+}
+
 static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
                   const es_format_t *fmt, picture_sys_t *p_sys)
 {
@@ -300,6 +351,15 @@ static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     sys->hw_ctx.context_id = VA_INVALID_ID;
     sys->pool = NULL;
 
+    vlc_va_instance_ctx* p_ctx = malloc( sizeof( *p_ctx ) );
+    if ( unlikely( p_ctx == NULL ) )
+    {
+        free( sys );
+        return VLC_ENOMEM;
+    }
+    p_ctx->p_obj = VLC_OBJECT( va );
+    p_ctx->p_sys = sys;
+
     /* Create a VA display */
 #ifdef VLC_VA_BACKEND_XLIB
     sys->p_display_x11 = XOpenDisplay(NULL);
@@ -309,7 +369,9 @@ static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
         goto error;
     }
 
-    sys->hw_ctx.display = vaGetDisplay(sys->p_display_x11);
+    sys->hw_ctx.display = vlc_instance_holder_acquire(
+                VLC_OBJECT( va ), "vaapi-instance", &CreateVaDisplayInstanceX11,
+                &DestroyVaDisplayInstance, p_ctx );
 #endif
 #ifdef VLC_VA_BACKEND_DRM
     static const char drm_device_paths[][20] = {
@@ -323,7 +385,9 @@ static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
         if (sys->drm_fd < 0)
             continue;
 
-        sys->hw_ctx.display = vaGetDisplayDRM(sys->drm_fd);
+        sys->hw_ctx.display = vlc_instance_holder_acquire(
+                    VLC_OBJECT( va ),"vaapi-instance", &CreateVaDisplayInstanceDRM,
+                    &DestroyVaDisplayInstance, p_ctx );
         if (sys->hw_ctx.display)
             break;
 
@@ -337,19 +401,6 @@ static int Create(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
         goto error;
     }
 
-    if (vlc_vaapi_Initialize(o, sys->hw_ctx.display))
-    {
-        sys->hw_ctx.display = NULL;
-        goto error;
-    }
-
-    if (vlc_vaapi_SetInstance(sys->hw_ctx.display))
-    {
-        msg_Err(va, "VAAPI instance already in use");
-        sys->hw_ctx.display = NULL;
-        goto error;
-    }
-
     sys->hw_ctx.config_id =
         vlc_vaapi_CreateConfigChecked(o, sys->hw_ctx.display, i_profile,
                                       VAEntrypointVLD, 0);
@@ -392,7 +443,8 @@ error:
     if (sys->hw_ctx.config_id != VA_INVALID_ID)
         vlc_vaapi_DestroyConfig(o, sys->hw_ctx.display, sys->hw_ctx.config_id);
     if (sys->hw_ctx.display != NULL)
-        vlc_vaapi_ReleaseInstance(sys->hw_ctx.display);
+        vlc_instance_holder_release( VLC_OBJECT( va ),
+                                              "vaapi-instance" );
 #ifdef VLC_VA_BACKEND_XLIB
     if( sys->p_display_x11 != NULL)
         XCloseDisplay(sys->p_display_x11);
diff --git a/modules/hw/vaapi/Makefile.am b/modules/hw/vaapi/Makefile.am
index d0e595e7c6..563bad2844 100644
--- a/modules/hw/vaapi/Makefile.am
+++ b/modules/hw/vaapi/Makefile.am
@@ -1,23 +1,16 @@
 vaapidir = $(pluginsdir)/vaapi
 
-libvlc_vaapi_instance_la_SOURCES = hw/vaapi/instance.c hw/vaapi/vlc_vaapi.h
-libvlc_vaapi_instance_la_CFLAGS = $(LIBVA_CFLAGS)
-libvlc_vaapi_instance_la_LIBADD = $(LIBVA_LIBS) $(LIBPTHREAD)
-libvlc_vaapi_instance_la_LDFLAGS = -no-undefined	\
-				   -version-info 0:0:0
-
 libvaapi_chroma_plugin_la_SOURCES = hw/vaapi/chroma.c hw/vaapi/vlc_vaapi.c hw/vaapi/vlc_vaapi.h	\
 				    video_chroma/copy.c video_chroma/copy.h
 libvaapi_chroma_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS)
-libvaapi_chroma_plugin_la_LIBADD = $(AM_LIBADD) $(LIBVA_LIBS) libvlc_vaapi_instance.la
+libvaapi_chroma_plugin_la_LIBADD = $(AM_LIBADD) $(LIBVA_LIBS)
 
 libvaapi_filters_plugin_la_SOURCES = hw/vaapi/filters.c hw/vaapi/vlc_vaapi.c hw/vaapi/vlc_vaapi.h
 libvaapi_filters_plugin_la_CPPFLAGS = $(AM_CPPFLAGS)
 libvaapi_filters_plugin_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS)
-libvaapi_filters_plugin_la_LIBADD = $(AM_LIBADD) $(LIBVA_LIBS) libvlc_vaapi_instance.la
+libvaapi_filters_plugin_la_LIBADD = $(AM_LIBADD) $(LIBVA_LIBS)
 
 if HAVE_VAAPI
-pkglib_LTLIBRARIES += libvlc_vaapi_instance.la
 vaapi_LTLIBRARIES = libvaapi_chroma_plugin.la	\
 		    libvaapi_filters_plugin.la
 endif
diff --git a/modules/hw/vaapi/chroma.c b/modules/hw/vaapi/chroma.c
index 278ecf9e17..f952325c4a 100644
--- a/modules/hw/vaapi/chroma.c
+++ b/modules/hw/vaapi/chroma.c
@@ -31,6 +31,7 @@
 #include <vlc_common.h>
 #include <vlc_filter.h>
 #include <vlc_plugin.h>
+#include <vlc_instance_holder.h>
 
 #include "../../video_chroma/copy.h"
 #include "vlc_vaapi.h"
@@ -134,7 +135,8 @@ DownloadSurface(filter_t *filter, picture_t *src_pic)
     {
         /* Get the instance here since the instance may be not created by the
          * decoder from Open() */
-        va_dpy = filter_sys->dpy = vlc_vaapi_GetInstance();
+        va_dpy = filter_sys->dpy = vlc_instance_holder_get(
+                    VLC_OBJECT( filter ), "vaapi-instance" );
         assert(filter_sys->dpy);
     }
     else
@@ -313,7 +315,7 @@ static int Open(vlc_object_t *obj)
 
     if (is_upload)
     {
-        filter_sys->dpy = vlc_vaapi_GetInstance();
+        filter_sys->dpy = vlc_instance_holder_get( obj, "vaapi-instance" );
         if (filter_sys->dpy == NULL)
         {
             free(filter_sys);
@@ -327,7 +329,7 @@ static int Open(vlc_object_t *obj)
                               VA_FOURCC_NV12);
         if (!filter_sys->dest_pics)
         {
-            vlc_vaapi_ReleaseInstance(filter_sys->dpy);
+            vlc_instance_holder_release( obj, "vaapi-instance" );
             free(filter_sys);
             return VLC_EGENERIC;
         }
@@ -344,7 +346,8 @@ static int Open(vlc_object_t *obj)
         if (is_upload)
         {
             picture_pool_Release(filter_sys->dest_pics);
-            vlc_vaapi_ReleaseInstance(filter_sys->dpy);
+            vlc_instance_holder_release( VLC_OBJECT( filter ),
+                                                  "vaapi-instance" );
         }
         free(filter_sys);
         return VLC_EGENERIC;
@@ -366,7 +369,7 @@ Close(vlc_object_t *obj)
     if (filter_sys->dest_pics)
         picture_pool_Release(filter_sys->dest_pics);
     if (filter_sys->dpy != NULL)
-        vlc_vaapi_ReleaseInstance(filter_sys->dpy);
+        vlc_instance_holder_release( obj, "vaapi-instance" );
     CopyCleanCache(&filter_sys->cache);
 
     free(filter_sys);
diff --git a/modules/hw/vaapi/filters.c b/modules/hw/vaapi/filters.c
index 0af9c0548b..f778d155ed 100644
--- a/modules/hw/vaapi/filters.c
+++ b/modules/hw/vaapi/filters.c
@@ -31,6 +31,7 @@
 #include <vlc_filter.h>
 #include <vlc_plugin.h>
 #include "vlc_vaapi.h"
+#include <vlc_instance_holder.h>
 
 /********************************
  * Common structures and macros *
@@ -298,7 +299,8 @@ Open(filter_t * filter,
     filter_sys->va.conf = VA_INVALID_ID;
     filter_sys->va.ctx = VA_INVALID_ID;
     filter_sys->va.buf = VA_INVALID_ID;
-    filter_sys->va.dpy = vlc_vaapi_GetInstance();
+    filter_sys->va.dpy = vlc_instance_holder_get( VLC_OBJECT( filter ),
+                                                           "vaapi-instance" );
     if (!filter_sys->va.dpy)
         goto error;
 
@@ -377,7 +379,8 @@ error:
         vlc_vaapi_DestroyConfig(VLC_OBJECT(filter),
                                 filter_sys->va.dpy, filter_sys->va.conf);
     if (filter_sys->va.dpy)
-        vlc_vaapi_ReleaseInstance(filter_sys->va.dpy);
+        vlc_instance_holder_release( VLC_OBJECT( filter ),
+                                              "vaapi-instance" );
     free(filter_sys);
     return VLC_EGENERIC;
 }
@@ -389,7 +392,7 @@ Close(vlc_object_t * obj, filter_sys_t * filter_sys)
     vlc_vaapi_DestroyBuffer(obj, filter_sys->va.dpy, filter_sys->va.buf);
     vlc_vaapi_DestroyContext(obj, filter_sys->va.dpy, filter_sys->va.ctx);
     vlc_vaapi_DestroyConfig(obj, filter_sys->va.dpy, filter_sys->va.conf);
-    vlc_vaapi_ReleaseInstance(filter_sys->va.dpy);
+    vlc_instance_holder_release( obj, "vaapi-instance" );
     free(filter_sys);
 }
 
diff --git a/modules/hw/vaapi/instance.c b/modules/hw/vaapi/instance.c
deleted file mode 100644
index 3f70fe7ebc..0000000000
--- a/modules/hw/vaapi/instance.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*****************************************************************************
- * instance.c: VAAPI instance management for VLC
- *****************************************************************************
- * Copyright (C) 2017 VLC authors, VideoLAN and VideoLabs
- *
- * Author: Victorien Le Couviour--Tuffet <victorien.lecouviour.tuffet at gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <vlc_common.h>
-#include "vlc_vaapi.h"
-
-#pragma GCC visibility push(default)
-
-static struct
-{
-    pthread_mutex_t     lock;
-    VADisplay           dpy;
-    unsigned            refcount;
-} va_instance = { PTHREAD_MUTEX_INITIALIZER, NULL, 0 };
-
-/* Set the VA instance and sets the reference counter to 1. */
-int
-vlc_vaapi_SetInstance(VADisplay dpy)
-{
-    pthread_mutex_lock(&va_instance.lock);
-    if (va_instance.refcount != 0)
-    {
-        vaTerminate(dpy);
-        pthread_mutex_unlock(&va_instance.lock);
-        return VLC_EGENERIC;
-    }
-    va_instance.refcount = 1;
-    va_instance.dpy = dpy;
-    pthread_mutex_unlock(&va_instance.lock);
-    return VLC_SUCCESS;
-}
-
-/* Retrieve the VA instance and increases the reference counter by 1. */
-VADisplay
-vlc_vaapi_GetInstance(void)
-{
-    VADisplay dpy;
-    pthread_mutex_lock(&va_instance.lock);
-    if (!va_instance.dpy)
-        dpy = NULL;
-    else
-    {
-        dpy = va_instance.dpy;
-        ++va_instance.refcount;
-    }
-    pthread_mutex_unlock(&va_instance.lock);
-    return dpy;
-}
-
-/* Decreases the reference counter by 1 and frees the instance if that counter
-   reaches 0. */
-void
-vlc_vaapi_ReleaseInstance(VADisplay *dpy)
-{
-    assert(va_instance.dpy == dpy && va_instance.refcount > 0);
-    (void) dpy;
-
-    pthread_mutex_lock(&va_instance.lock);
-    if (--va_instance.refcount == 0)
-    {
-        vaTerminate(va_instance.dpy);
-        va_instance.dpy = NULL;
-    }
-    pthread_mutex_unlock(&va_instance.lock);
-}
-
-#pragma GCC visibility pop
diff --git a/modules/hw/vaapi/vlc_vaapi.c b/modules/hw/vaapi/vlc_vaapi.c
index 04514eb852..28f4e6a58f 100644
--- a/modules/hw/vaapi/vlc_vaapi.c
+++ b/modules/hw/vaapi/vlc_vaapi.c
@@ -39,6 +39,7 @@
 #include <vlc_atomic.h>
 #include <vlc_fourcc.h>
 #include <vlc_picture_pool.h>
+#include <vlc_instance_holder.h>
 
 /* This macro is designed to wrap any VA call, and in case of failure,
    display the VA error string then goto the 'error' label (which you must
@@ -422,6 +423,7 @@ struct picture_sys_t
 {
     struct pic_sys_vaapi_instance *instance;
     struct vaapi_pic_ctx ctx;
+    vlc_object_t* p_vlc_obj;
 };
 
 static void
@@ -434,7 +436,7 @@ pool_pic_destroy_cb(picture_t *pic)
     {
         vaDestroySurfaces(instance->dpy, instance->render_targets,
                           instance->num_render_targets);
-        vlc_vaapi_ReleaseInstance(instance->dpy);
+        vlc_instance_holder_release( p_sys->p_vlc_obj, "vaapi-instance" );
         free(instance);
     }
     free(pic->p_sys);
@@ -515,6 +517,7 @@ vlc_vaapi_PoolNew(vlc_object_t *o, VADisplay dpy, unsigned count,
             goto error_pic;
         }
         p_sys->instance = instance;
+        p_sys->p_vlc_obj = o->obj.libvlc;
         p_sys->ctx.s.destroy = pic_sys_ctx_destroy_cb;
         p_sys->ctx.s.copy = pic_ctx_copy_cb;
         p_sys->ctx.surface = instance->render_targets[i];
@@ -537,7 +540,8 @@ vlc_vaapi_PoolNew(vlc_object_t *o, VADisplay dpy, unsigned count,
         goto error_pic;
 
     atomic_store(&instance->refcount, count);
-    instance->dpy = vlc_vaapi_GetInstance(); /* Hold a reference on VADisplay */
+    /* Hold a reference on VADisplay */
+    instance->dpy = vlc_instance_holder_get( o, "vaapi-instance" );
     assert(instance->dpy == dpy);
 
     *render_targets = instance->render_targets;
diff --git a/modules/hw/vaapi/vlc_vaapi.h b/modules/hw/vaapi/vlc_vaapi.h
index 51dbc69a6c..e06bcfeca3 100644
--- a/modules/hw/vaapi/vlc_vaapi.h
+++ b/modules/hw/vaapi/vlc_vaapi.h
@@ -35,18 +35,12 @@
  * VA instance management *
  **************************/
 
-/* Allocates the VA instance and sets the reference counter to 1. */
-int
-vlc_vaapi_SetInstance(VADisplay dpy);
-
-/* Retrieve the VA instance and increases the reference counter by 1. */
-VADisplay
-vlc_vaapi_GetInstance(void);
-
-/* Decreases the reference counter by 1 and frees the instance if that counter
-   reaches 0. */
-void
-vlc_vaapi_ReleaseInstance(VADisplay *);
+static inline void
+vlc_vaapi_DestroyInstance( void* instance, void* opaque )
+{
+    VLC_UNUSED( opaque );
+    vaTerminate( (VADisplay)instance );
+}
 
 /*****************
  * VAAPI display *
diff --git a/modules/video_output/opengl/converter_vaapi.c b/modules/video_output/opengl/converter_vaapi.c
index 03987a8e34..658432e434 100644
--- a/modules/video_output/opengl/converter_vaapi.c
+++ b/modules/video_output/opengl/converter_vaapi.c
@@ -25,6 +25,7 @@
 #include "internal.h"
 #include "../../hw/vaapi/vlc_vaapi.h"
 #include <vlc_vout_window.h>
+#include <vlc_instance_holder.h>
 
 #include <assert.h>
 
@@ -252,7 +253,7 @@ tc_vaegl_release(const opengl_tex_converter_t *tc)
     if (priv->last.pic != NULL)
         vaegl_release_last_pic(tc, priv);
 
-    vlc_vaapi_ReleaseInstance(priv->vadpy);
+    vlc_instance_holder_release( VLC_OBJECT( tc->gl ), "vaapi-instance" );
 
 #ifdef HAVE_VA_X11
     if (priv->x11dpy != NULL)
@@ -296,12 +297,8 @@ tc_vaegl_init(opengl_tex_converter_t *tc, VADisplay *vadpy)
     if (vadpy == NULL)
         return VLC_EGENERIC;
 
-    int ret = VLC_ENOMEM;
-    struct priv *priv = tc->priv = calloc(1, sizeof(struct priv));
-    if (unlikely(tc->priv == NULL))
-        goto error;
+    struct priv *priv = tc->priv;
 
-    ret = VLC_EGENERIC;
     priv->vadpy = vadpy;
     priv->fourcc = 0;
 
@@ -330,30 +327,48 @@ tc_vaegl_init(opengl_tex_converter_t *tc, VADisplay *vadpy)
     if (tc_va_check_interop_blacklist(tc, priv->vadpy))
         goto error;
 
-    if (vlc_vaapi_SetInstance(priv->vadpy))
-    {
-        msg_Err(tc->gl, "VAAPI instance already in use");
-        vadpy = NULL;
-        goto error;
-    }
-
     tc->fshader = opengl_fragment_shader_init(tc, GL_TEXTURE_2D, VLC_CODEC_NV12,
                                               tc->fmt.space);
     if (tc->fshader == 0)
-    {
-        vlc_vaapi_ReleaseInstance(priv->vadpy);
-        vadpy = NULL;
         goto error;
-    }
     return VLC_SUCCESS;
 
 error:
     if (vadpy != NULL)
         vaTerminate(vadpy);
-    free(tc->priv);
-    return ret;
+    return VLC_EGENERIC;
+}
+
+
+static VADisplay CreateVADisplayInstance( VADisplay p_display, opengl_tex_converter_t* p_tc )
+{
+    if ( tc_vaegl_init( p_tc, p_display ) )
+    {
+        vaTerminate( p_display );
+        return NULL;
+    }
+    return p_display;
 }
 
+#ifdef HAVE_VA_X11
+static void* CreateVADisplayInstanceX11( void* p_opaque )
+{
+    opengl_tex_converter_t* p_tc = (opengl_tex_converter_t*)p_opaque;
+    struct priv* p_priv = p_tc->priv;
+    return CreateVADisplayInstance( vaGetDisplay( p_priv->x11dpy ), p_tc );
+}
+#endif
+
+#ifdef HAVE_VA_WL
+static void* CreateVADisplayInstanceWL( void* p_opaque )
+{
+    opengl_tex_converter_t* p_tc = (opengl_tex_converter_t*)p_opaque;
+    return CreateVADisplayInstance( vaGetDisplayWl( p_tc->gl->surface->display.wl ),
+                                    p_tc );
+}
+
+#endif
+
 int
 opengl_tex_converter_vaapi_init(opengl_tex_converter_t *tc)
 {
@@ -362,6 +377,9 @@ opengl_tex_converter_vaapi_init(opengl_tex_converter_t *tc)
      || tc->gl->egl.destroyImageKHR == NULL)
         return VLC_EGENERIC;
 
+    struct priv* p_priv = tc->priv = calloc(1, sizeof(struct priv));
+    if (unlikely(p_priv == NULL))
+        return VLC_ENOMEM;
     switch (tc->gl->surface->type)
     {
 #ifdef HAVE_VA_X11
@@ -369,27 +387,44 @@ opengl_tex_converter_vaapi_init(opengl_tex_converter_t *tc)
         {
             if (!vlc_xlib_init(VLC_OBJECT(tc->gl)))
                 return VLC_EGENERIC;
-            Display *x11dpy = XOpenDisplay(tc->gl->surface->display.x11);
-            if (x11dpy == NULL)
+            p_priv->x11dpy = XOpenDisplay(tc->gl->surface->display.x11);
+            if (p_priv->x11dpy == NULL)
+            {
+                free( p_priv );
                 return VLC_EGENERIC;
+            }
 
-            if (tc_vaegl_init(tc, vaGetDisplay(x11dpy)))
+            VADisplay disp = vlc_instance_holder_acquire(
+                        VLC_OBJECT( tc->gl ), "vaapi-instance",
+                        &CreateVADisplayInstanceX11, &vlc_vaapi_DestroyInstance,
+                        tc );
+            if (disp == NULL)
             {
-                XCloseDisplay(x11dpy);
+                XCloseDisplay(p_priv->x11dpy);
+                p_priv->x11dpy = NULL;
+                free( p_priv );
                 return VLC_EGENERIC;
             }
-            struct priv *priv = tc->priv;
-            priv->x11dpy = x11dpy;
             break;
         }
 #endif
 #ifdef HAVE_VA_WL
         case VOUT_WINDOW_TYPE_WAYLAND:
-            if (tc_vaegl_init(tc, vaGetDisplayWl(tc->gl->surface->display.wl)))
+        {
+            VADisplay disp = vlc_instance_holder_acquire(
+                    VLC_OBJECT( tc->gl ),"vaapi-instance",
+                    &CreateVADisplayInstanceWL, &vlc_vaapi_DestroyInstance,
+                    tc->gl->surface->display.wl);
+            if (disp == NULL)
+            {
+                free( p_priv );
                 return VLC_EGENERIC;
+            }
             break;
+        }
 #endif
         default:
+            free( p_priv );
             return VLC_EGENERIC;
     }
 
-- 
2.11.0



More information about the vlc-devel mailing list