vlc | branch: master | Rémi Denis-Courmont <r...@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 _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits