[vlc-devel] [RFC PATCH 2/8] WIP: avcodec: va: force opaque direct rendering
Thomas Guillem
thomas at gllm.fr
Fri Feb 10 11:35:56 CET 2017
Removed a lot of code, I don't know if we should keep for software rendering.
---
modules/codec/avcodec/va.c | 2 +-
modules/codec/avcodec/vaapi.c | 280 ++++--------------------------------------
modules/codec/avcodec/video.c | 2 +-
3 files changed, 28 insertions(+), 256 deletions(-)
diff --git a/modules/codec/avcodec/va.c b/modules/codec/avcodec/va.c
index 091c35a381..3944dbeead 100644
--- a/modules/codec/avcodec/va.c
+++ b/modules/codec/avcodec/va.c
@@ -38,7 +38,7 @@ vlc_fourcc_t vlc_va_GetChroma(enum PixelFormat hwfmt, enum PixelFormat swfmt)
switch (hwfmt)
{
case AV_PIX_FMT_VAAPI_VLD:
- return VLC_CODEC_YV12;
+ return VLC_CODEC_VAAPI_OPAQUE;
case AV_PIX_FMT_DXVA2_VLD:
switch (swfmt)
diff --git a/modules/codec/avcodec/vaapi.c b/modules/codec/avcodec/vaapi.c
index 07daf0c9a2..20439cc939 100644
--- a/modules/codec/avcodec/vaapi.c
+++ b/modules/codec/avcodec/vaapi.c
@@ -49,6 +49,7 @@
#include "avcodec.h"
#include "va.h"
#include "../../video_chroma/copy.h"
+#include "../../hw/va/vlc_va.h"
#ifndef VA_SURFACE_ATTRIB_SETTABLE
#define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \
@@ -57,158 +58,40 @@
struct vlc_va_sys_t
{
-#ifdef VLC_VA_BACKEND_XLIB
- Display *p_display_x11;
-#endif
-#ifdef VLC_VA_BACKEND_DRM
- int drm_fd;
-#endif
struct vaapi_context hw_ctx;
/* */
- vlc_mutex_t lock;
- int width;
- int height;
VAImageFormat format;
-
- copy_cache_t image_cache;
-
- bool do_derive;
- uint8_t count;
- uint32_t available;
- VASurfaceID surfaces[32];
};
static int Extract( vlc_va_t *va, picture_t *p_picture, uint8_t *data )
{
- vlc_va_sys_t *sys = va->sys;
- VASurfaceID surface = (VASurfaceID)(uintptr_t)data;
- VAImage image;
- int ret = VLC_EGENERIC;
-
-#if VA_CHECK_VERSION(0,31,0)
- if (vaSyncSurface(sys->hw_ctx.display, surface))
-#else
- if (vaSyncSurface(sys->hw_ctx.display, sys->hw_ctx.context_id, surface))
-#endif
- return VLC_EGENERIC;
-
- if (!sys->do_derive || vaDeriveImage(sys->hw_ctx.display, surface, &image))
- { /* Fallback if image derivation is not supported */
- if (vaCreateImage(sys->hw_ctx.display, &sys->format, sys->width,
- sys->height, &image))
- return VLC_EGENERIC;
- if (vaGetImage(sys->hw_ctx.display, surface, 0, 0, sys->width,
- sys->height, image.image_id))
- goto error;
- }
-
- void *p_base;
- if (vaMapBuffer(sys->hw_ctx.display, image.buf, &p_base))
- goto error;
-
- const unsigned i_fourcc = sys->format.fourcc;
- if( i_fourcc == VA_FOURCC_YV12 ||
- i_fourcc == VA_FOURCC_IYUV )
- {
- bool b_swap_uv = i_fourcc == VA_FOURCC_IYUV;
- uint8_t *pp_plane[3];
- size_t pi_pitch[3];
-
- for( int i = 0; i < 3; i++ )
- {
- const int i_src_plane = (b_swap_uv && i != 0) ? (3 - i) : i;
- pp_plane[i] = (uint8_t*)p_base + image.offsets[i_src_plane];
- pi_pitch[i] = image.pitches[i_src_plane];
- }
- CopyFromYv12( p_picture, pp_plane, pi_pitch, sys->height, &sys->image_cache );
- }
- else
- {
- assert( i_fourcc == VA_FOURCC_NV12 );
- uint8_t *pp_plane[2];
- size_t pi_pitch[2];
-
- for( int i = 0; i < 2; i++ )
- {
- pp_plane[i] = (uint8_t*)p_base + image.offsets[i];
- pi_pitch[i] = image.pitches[i];
- }
- CopyFromNv12( p_picture, pp_plane, pi_pitch, sys->height, &sys->image_cache );
- }
-
- vaUnmapBuffer(sys->hw_ctx.display, image.buf);
- ret = VLC_SUCCESS;
-error:
- vaDestroyImage(sys->hw_ctx.display, image.image_id);
- return ret;
+ (void) va; (void) p_picture; (void) data;
+ return VLC_SUCCESS;
}
static int Get( vlc_va_t *va, picture_t *pic, uint8_t **data )
{
- vlc_va_sys_t *sys = va->sys;
- unsigned i = sys->count;
-
- vlc_mutex_lock( &sys->lock );
- if (sys->available)
- {
- i = ctz(sys->available);
- sys->available &= ~(1 << i);
- }
- vlc_mutex_unlock( &sys->lock );
-
- if( i >= sys->count )
- return VLC_ENOMEM;
-
- VASurfaceID *surface = &sys->surfaces[i];
-
- pic->context = surface;
- *data = (void *)(uintptr_t)*surface;
+ fprintf(stderr, "Get: %X\n", pic->p_sys->va_surface_id);
+ (void) va;
+ *data = (void *)(uintptr_t)pic->p_sys->va_surface_id;
return VLC_SUCCESS;
}
-static void Release( void *opaque, uint8_t *data )
-{
- (void) data;
- picture_t *pic = opaque;
- 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);
- sys->available |= 1 << i;
- vlc_mutex_unlock( &sys->lock );
-
- pic->context = NULL;
- picture_Release(pic);
-}
-
static void Delete( vlc_va_t *va, AVCodecContext *avctx )
{
vlc_va_sys_t *sys = va->sys;
(void) avctx;
- vlc_mutex_destroy(&sys->lock);
- CopyCleanCache(&sys->image_cache);
-
vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
- 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
- XCloseDisplay( sys->p_display_x11 );
-#endif
-#ifdef VLC_VA_BACKEND_DRM
- vlc_close( sys->drm_fd );
-#endif
- free( sys );
+ free(sys);
}
/** Finds a supported image chroma */
-static int FindFormat(vlc_va_sys_t *sys)
+static int FindFormat(vlc_va_sys_t *sys, VASurfaceID surface, int width,
+ int height)
{
int count = vaMaxNumImageFormats(sys->hw_ctx.display);
@@ -228,19 +111,13 @@ static int FindFormat(vlc_va_sys_t *sys)
{
unsigned fourcc = fmts[i].fourcc;
- if (fourcc != VA_FOURCC_YV12 && fourcc != VA_FOURCC_IYUV
- && fourcc != VA_FOURCC_NV12)
- continue;
-
VAImage image;
-
- if (vaCreateImage(sys->hw_ctx.display, &fmts[i], sys->width,
- sys->height, &image))
+ if (vaCreateImage(sys->hw_ctx.display, &fmts[i], width, height, &image))
continue;
/* Validate that vaGetImage works with this format */
- int val = vaGetImage(sys->hw_ctx.display, sys->surfaces[0], 0, 0,
- sys->width, sys->height, image.image_id);
+ int val = vaGetImage(sys->hw_ctx.display, surface, 0, 0,
+ width, height, image.image_id);
vaDestroyImage(sys->hw_ctx.display, image.image_id);
@@ -256,22 +133,9 @@ static int FindFormat(vlc_va_sys_t *sys)
free(fmts);
if (sys->format.fourcc == 0)
- return VLC_EGENERIC; /* None of the formats work */
-
- VAImage image;
-
- /* Use vaDerive() iif it supports the best selected format */
- sys->do_derive = false;
-
- if (vaDeriveImage(sys->hw_ctx.display, sys->surfaces[0],
- &image) == VA_STATUS_SUCCESS)
{
- if (image.format.fourcc == sys->format.fourcc)
- {
- sys->do_derive = true;
- sys->format = image.format;
- }
- vaDestroyImage(sys->hw_ctx.display, image.image_id);
+ fprintf(stderr, "no image");
+ return VLC_EGENERIC; /* None of the formats work */
}
return VLC_SUCCESS;
@@ -284,19 +148,10 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
return VLC_EGENERIC;
(void) fmt;
- (void) p_sys;
-#ifdef VLC_VA_BACKEND_XLIB
- if( !vlc_xlib_init( VLC_OBJECT(va) ) )
- {
- msg_Warn( va, "Ignoring VA-X11 API" );
- return VLC_EGENERIC;
- }
-#endif
VAProfile i_profile, *p_profiles_list;
bool b_supported_profile = false;
int i_profiles_nb = 0;
- unsigned count = 3;
/* */
switch( ctx->codec_id )
@@ -304,7 +159,6 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
i_profile = VAProfileMPEG2Main;
- count = 4;
break;
case AV_CODEC_ID_MPEG4:
i_profile = VAProfileMPEG4AdvancedSimple;
@@ -317,7 +171,6 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
break;
case AV_CODEC_ID_H264:
i_profile = VAProfileH264High;
- count = 18;
break;
case AV_CODEC_ID_HEVC:
if (ctx->profile == FF_PROFILE_HEVC_MAIN)
@@ -326,11 +179,9 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
i_profile = VAProfileHEVCMain10;
else
return VLC_EGENERIC;
- count = 18;
break;
case AV_CODEC_ID_VP8:
i_profile = VAProfileVP8Version0_3;
- count = 5;
break;
case AV_CODEC_ID_VP9:
if (ctx->profile == FF_PROFILE_VP9_0)
@@ -339,77 +190,26 @@ static int Create( vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
i_profile = VAProfileVP9Profile2;
else
return VLC_EGENERIC;
- count = 10;
break;
default:
return VLC_EGENERIC;
}
- count += ctx->thread_count;
-
- 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));
+ vlc_va_sys_t *sys = calloc(1, sizeof *sys);
/* */
sys->hw_ctx.display = NULL;
sys->hw_ctx.config_id = VA_INVALID_ID;
sys->hw_ctx.context_id = VA_INVALID_ID;
- sys->width = ctx->coded_width;
- sys->height = ctx->coded_height;
- sys->count = count;
- 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
- sys->p_display_x11 = XOpenDisplay(NULL);
- if( !sys->p_display_x11 )
- {
- msg_Err( va, "Could not connect to X server" );
- goto error;
- }
-
- sys->hw_ctx.display = vaGetDisplay(sys->p_display_x11);
-#endif
-#ifdef VLC_VA_BACKEND_DRM
- static const char const *drm_device_paths[] = {
- "/dev/dri/renderD128",
- "/dev/dri/card0"
- };
-
- for (int i = 0; ARRAY_SIZE(drm_device_paths); i++) {
- sys->drm_fd = vlc_open(drm_device_paths[i], O_RDWR);
- if (sys->drm_fd < 0)
- continue;
- sys->hw_ctx.display = vaGetDisplayDRM(sys->drm_fd);
- if (sys->hw_ctx.display)
- break;
+ sys->hw_ctx.display = p_sys->va_dpy;
- vlc_close(sys->drm_fd);
- sys->drm_fd = -1;
- }
-#endif
if (sys->hw_ctx.display == NULL)
{
msg_Err( va, "Could not get a VAAPI device" );
goto error;
}
- int major, minor;
- if (vaInitialize(sys->hw_ctx.display, &major, &minor))
- {
- msg_Err( va, "Failed to initialize the VAAPI device" );
- goto error;
- }
-
/* Check if the selected profile is supported */
i_profiles_nb = vaMaxNumProfiles(sys->hw_ctx.display);
p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) );
@@ -453,73 +253,45 @@ 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;
- }
-
/* Create a context */
if (vaCreateContext(sys->hw_ctx.display, sys->hw_ctx.config_id,
ctx->coded_width, ctx->coded_height, VA_PROGRESSIVE,
- sys->surfaces, sys->count, &sys->hw_ctx.context_id))
+ p_sys->render_targets, p_sys->num_render_targets,
+ &sys->hw_ctx.context_id))
{
sys->hw_ctx.context_id = VA_INVALID_ID;
- vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
+fprintf(stderr, "vaapi error: CONTEX KO\n");
goto error;
}
- if (FindFormat(sys))
+ if (FindFormat(sys, p_sys->va_surface_id, ctx->width, ctx->height))
goto error;
- if (unlikely(CopyInitCache(&sys->image_cache, ctx->coded_width)))
- goto error;
-
- vlc_mutex_init(&sys->lock);
-
- msg_Dbg(va, "using %s image format 0x%08x",
- sys->do_derive ? "derive" : "get", sys->format.fourcc);
+ msg_Err(va, "using get image format 0x%08x", sys->format.fourcc);
ctx->hwaccel_context = &sys->hw_ctx;
va->sys = sys;
va->description = vaQueryVendorString(sys->hw_ctx.display);
va->get = Get;
- va->release = Release;
+ va->release = NULL;
va->extract = Extract;
return VLC_SUCCESS;
error:
+fprintf(stderr, "vaapi error\n");
if (sys->hw_ctx.context_id != VA_INVALID_ID)
{
vaDestroyContext(sys->hw_ctx.display, sys->hw_ctx.context_id);
- vaDestroySurfaces(sys->hw_ctx.display, sys->surfaces, sys->count);
}
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
- if( sys->p_display_x11 != NULL )
- XCloseDisplay( sys->p_display_x11 );
-#endif
-#ifdef VLC_VA_BACKEND_DRM
- if( sys->drm_fd != -1 )
- vlc_close( sys->drm_fd );
-#endif
- free( sys );
+ free(sys);
return VLC_EGENERIC;
}
vlc_module_begin ()
-#if defined (VLC_VA_BACKEND_XLIB)
- set_description( N_("VA-API video decoder via X11") )
-#elif defined (VLC_VA_BACKEND_DRM)
- set_description( N_("VA-API video decoder via DRM") )
-#endif
- set_capability( "hw decoder", 0 )
+ set_description( N_("VA-API video decoder") )
+ set_capability( "hw decoder", 101 )
set_category( CAT_INPUT )
set_subcategory( SUBCAT_INPUT_VCODEC )
set_callbacks( Create, Delete )
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index a00e2b4634..b6cc3bc03b 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -1305,7 +1305,7 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
continue;
bool hwaccel = (dsc->flags & AV_PIX_FMT_FLAG_HWACCEL) != 0;
- msg_Dbg( p_dec, "available %sware decoder output format %d (%s)",
+ msg_Err( p_dec, "available %sware decoder output format %d (%s)",
hwaccel ? "hard" : "soft", pi_fmt[i], dsc->name );
if (hwaccel)
can_hwaccel = true;
--
2.11.0
More information about the vlc-devel
mailing list