[vlc-commits] vaapi: advance and simplify surface allocation

Rémi Denis-Courmont git at videolan.org
Fri Apr 24 22:47:04 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Apr 24 23:17:26 2015 +0300| [4b01d3ccadedd611f1ee966d4f34d9dfde772187] | committer: Rémi Denis-Courmont

vaapi: advance and simplify surface allocation

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4b01d3ccadedd611f1ee966d4f34d9dfde772187
---

 modules/codec/avcodec/vaapi.c |   88 ++++++++++++++++-------------------------
 1 file changed, 33 insertions(+), 55 deletions(-)

diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 79d7bbf..24a38d1 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -55,12 +55,6 @@
     vaCreateSurfaces(d, w, h, f, ns, s)
 #endif
 
-typedef struct
-{
-    VASurfaceID  i_id;
-    vlc_va_sys_t *sys;
-} vlc_va_surface_t;
-
 struct vlc_va_sys_t
 {
 #ifdef VLC_VA_BACKEND_XLIB
@@ -77,8 +71,6 @@ struct vlc_va_sys_t
     int          i_surface_height;
     vlc_fourcc_t i_surface_chroma;
 
-    vlc_va_surface_t *p_surface;
-
     VAImage      image;
     copy_cache_t image_cache;
 
@@ -86,6 +78,7 @@ struct vlc_va_sys_t
 
     uint8_t      count;
     uint32_t     available;
+    VASurfaceID  surfaces[32];
 };
 
 static void DestroySurfaces( vlc_va_sys_t *sys )
@@ -103,19 +96,9 @@ static void DestroySurfaces( vlc_va_sys_t *sys )
     if (sys->hw_ctx.context_id != VA_INVALID_ID)
         vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
 
-    for( unsigned i = 0; i < sys->count && sys->p_surface; i++ )
-    {
-        vlc_va_surface_t *p_surface = &sys->p_surface[i];
-
-        if( p_surface->i_id != VA_INVALID_SURFACE )
-            vaDestroySurfaces(sys->hw_ctx.display, &p_surface->i_id, 1);
-    }
-    free( sys->p_surface );
-
     /* */
     sys->image.image_id = VA_INVALID_ID;
     sys->hw_ctx.context_id = VA_INVALID_ID;
-    sys->p_surface = NULL;
     sys->i_surface_width = 0;
     sys->i_surface_height = 0;
     vlc_mutex_destroy(&sys->lock);
@@ -127,36 +110,13 @@ static int CreateSurfaces( vlc_va_sys_t *sys, void **pp_hw_ctx, vlc_fourcc_t *pi
     assert( i_width > 0 && i_height > 0 );
 
     /* */
-    sys->p_surface = calloc( sys->count, sizeof(*sys->p_surface) );
-    if( !sys->p_surface )
-        return VLC_EGENERIC;
     sys->image.image_id = VA_INVALID_ID;
     sys->hw_ctx.context_id   = VA_INVALID_ID;
 
-    /* Create surfaces */
-    VASurfaceID pi_surface_id[sys->count];
-    if (vaCreateSurfaces(sys->hw_ctx.display, VA_RT_FORMAT_YUV420, i_width,
-                         i_height, pi_surface_id, sys->count, NULL, 0 ) )
-    {
-        for( unsigned i = 0; i < sys->count; i++ )
-            sys->p_surface[i].i_id = VA_INVALID_SURFACE;
-        goto error;
-    }
-
-    sys->available = (1 << sys->count) - 1;
-
-    for( unsigned i = 0; i < sys->count; i++ )
-    {
-        vlc_va_surface_t *p_surface = &sys->p_surface[i];
-
-        p_surface->i_id = pi_surface_id[i];
-        p_surface->sys = sys;
-    }
-
     /* Create a context */
     if (vaCreateContext(sys->hw_ctx.display, sys->hw_ctx.config_id,
                         i_width, i_height, VA_PROGRESSIVE,
-                        pi_surface_id, sys->count, &sys->hw_ctx.context_id))
+                        sys->surfaces, sys->count, &sys->hw_ctx.context_id))
     {
         sys->hw_ctx.context_id = VA_INVALID_ID;
         goto error;
@@ -176,7 +136,7 @@ static int CreateSurfaces( vlc_va_sys_t *sys, void **pp_hw_ctx, vlc_fourcc_t *pi
 
     VAImage test_image;
     vlc_fourcc_t  deriveImageFormat = 0;
-    if (vaDeriveImage(sys->hw_ctx.display, pi_surface_id[0], &test_image) == VA_STATUS_SUCCESS)
+    if (vaDeriveImage(sys->hw_ctx.display, sys->surfaces[0], &test_image) == VA_STATUS_SUCCESS)
     {
         sys->b_supports_derive = true;
         deriveImageFormat = test_image.format.fourcc;
@@ -197,7 +157,7 @@ static int CreateSurfaces( vlc_va_sys_t *sys, void **pp_hw_ctx, vlc_fourcc_t *pi
                 continue;
             }
             /* Validate that vaGetImage works with this format */
-            if (vaGetImage(sys->hw_ctx.display, pi_surface_id[0],
+            if (vaGetImage(sys->hw_ctx.display, sys->surfaces[0],
                            0, 0, i_width, i_height, sys->image.image_id))
             {
                 vaDestroyImage(sys->hw_ctx.display, sys->image.image_id);
@@ -354,19 +314,20 @@ static int Get( vlc_va_t *va, picture_t *pic, uint8_t **data )
     if( i >= sys->count )
         return VLC_ENOMEM;
 
-    vlc_va_surface_t *p_surface = &sys->p_surface[i];
+    VASurfaceID *surface = &sys->surfaces[i];
 
-    pic->context = p_surface;
-    *data = (void *)(uintptr_t)p_surface->i_id;
+    pic->context = surface;
+    *data = (void *)(uintptr_t)*surface;
     return VLC_SUCCESS;
 }
 
 static void Release( void *opaque, uint8_t *data )
 {
     picture_t *pic = opaque;
-    vlc_va_surface_t *p_surface = pic->context;
-    vlc_va_sys_t *sys = p_surface->sys;
-    unsigned i = p_surface - sys->p_surface;
+    VASurfaceID *surface = pic->context;
+    vlc_va_sys_t *sys = (void *)((((uintptr_t)surface)
+        - offsetof(vlc_va_sys_t, surfaces)) & ~(sizeof (sys->surfaces) - 1));
+    unsigned i = surface - sys->surfaces;
 
     vlc_mutex_lock( &sys->lock );
     assert(((sys->available >> i) & 1) == 0);
@@ -407,9 +368,8 @@ static void Delete( vlc_va_t *va, AVCodecContext *avctx )
     vlc_va_sys_t *sys = va->sys;
 
     (void) avctx;
-    if( sys->i_surface_width || sys->i_surface_height )
-        DestroySurfaces( sys );
 
+    vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
     vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id);
     vaTerminate(sys->hw_ctx.display);
 #ifdef VLC_VA_BACKEND_XLIB
@@ -467,10 +427,16 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     }
     count += ctx->thread_count;
 
-    vlc_va_sys_t *sys = calloc( 1, sizeof(*sys) );
-    if ( unlikely(sys == NULL) )
+    vlc_va_sys_t *sys;
+    void *mem;
+
+    assert(popcount(sizeof (sys->surfaces)) == 1);
+    if (unlikely(posix_memalign(&mem, sizeof (sys->surfaces), sizeof (*sys))))
        return VLC_ENOMEM;
 
+    sys = mem;
+    memset(sys, 0, sizeof (*sys));
+
     /* */
     sys->hw_ctx.display = NULL;
     sys->hw_ctx.config_id = VA_INVALID_ID;
@@ -478,8 +444,9 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     sys->image.image_id = VA_INVALID_ID;
     sys->b_supports_derive = false;
     sys->count = count;
-    sys->available = 0;
+    sys->available = (1 << sys->count) - 1;
     assert(count < sizeof (sys->available) * CHAR_BIT);
+    assert(count * sizeof (sys->surfaces[0]) <= sizeof (sys->surfaces));
 
     /* Create a VA display */
 #ifdef VLC_VA_BACKEND_XLIB
@@ -558,6 +525,15 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
         goto error;
     }
 
+    /* Create surfaces */
+    assert(ctx->coded_width > 0 && ctx->coded_height > 0);
+    if (vaCreateSurfaces(sys->hw_ctx.display, VA_RT_FORMAT_YUV420,
+                         ctx->coded_width, ctx->coded_height,
+                         sys->surfaces, sys->count, NULL, 0))
+    {
+        goto error;
+    }
+
     vlc_mutex_init(&sys->lock);
 
     va->sys = sys;
@@ -569,6 +545,8 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
     return VLC_SUCCESS;
 
 error:
+    if (sys->hw_ctx.config_id != VA_INVALID_ID)
+        vaDestroyConfig(sys->hw_ctx.display, sys->hw_ctx.config_id);
     if (sys->hw_ctx.display != NULL)
         vaTerminate(sys->hw_ctx.display);
 #ifdef VLC_VA_BACKEND_XLIB



More information about the vlc-commits mailing list