diff options
author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2013-04-15 13:48:43 +0200 |
---|---|---|
committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2013-04-15 13:48:43 +0200 |
commit | 132d78ad3e56e5c6d5ab5992b364c572f60da6bc (patch) | |
tree | 7b012d3790b219326eb2e19b7cb5c514198b5f55 /gst/vaapi/gstvaapivideobuffer.c | |
parent | ad56d80c9e6b2944de1a29c193296dd949cfbaeb (diff) |
plugins: implement GstSurfaceMeta API.
Implement GstSurfaceMeta API for GStreamer 1.0.x. Even though this is
an unstable/deprecated API, this makes it possible to support Clutter
sink with minimal changes. Tested against clutter-gst 1.9.92.
Diffstat (limited to 'gst/vaapi/gstvaapivideobuffer.c')
-rw-r--r-- | gst/vaapi/gstvaapivideobuffer.c | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/gst/vaapi/gstvaapivideobuffer.c b/gst/vaapi/gstvaapivideobuffer.c index 1ae3f794..1d4ec805 100644 --- a/gst/vaapi/gstvaapivideobuffer.c +++ b/gst/vaapi/gstvaapivideobuffer.c @@ -32,10 +32,116 @@ #endif #if GST_CHECK_VERSION(1,0,0) -static inline GstBuffer * +#include <gst/video/gstsurfacemeta.h> + +#define GST_VAAPI_SURFACE_META_CAST(obj) \ + ((GstVaapiSurfaceMeta *)(obj)) + +typedef struct _GstVaapiSurfaceMeta GstVaapiSurfaceMeta; +struct _GstVaapiSurfaceMeta { + GstSurfaceMeta base; + GstBuffer *buffer; +}; + +#define GST_VAAPI_SURFACE_META_INFO gst_vaapi_surface_meta_get_info() +static const GstMetaInfo * +gst_vaapi_surface_meta_get_info(void); + +typedef GstSurfaceConverter *(*GstSurfaceConverterCreateFunc)( + GstSurfaceMeta *meta, const gchar *type, GValue *dest); + +#if USE_GLX +static GstSurfaceConverter * +gst_vaapi_surface_create_converter_glx(GstSurfaceMeta *base_meta, + const gchar *type, GValue *dest) +{ + GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + + return gst_vaapi_video_converter_glx_new(meta->buffer, type, dest); +} + +#undef gst_vaapi_video_converter_glx_new +#define gst_vaapi_video_converter_glx_new \ + gst_vaapi_surface_create_converter_glx +#endif + +static GstSurfaceConverter * +gst_vaapi_surface_create_converter(GstSurfaceMeta *base_meta, + const gchar *type, GValue *dest) +{ + GstVaapiSurfaceMeta * const meta = GST_VAAPI_SURFACE_META_CAST(base_meta); + GstVaapiVideoMeta * const vmeta = + gst_buffer_get_vaapi_video_meta(meta->buffer); + GstSurfaceConverterCreateFunc func; + + if (G_UNLIKELY(!vmeta)) + return NULL; + + func = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter(vmeta); + + return func ? func(base_meta, type, dest) : NULL; +} + +static gboolean +gst_vaapi_surface_meta_init(GstVaapiSurfaceMeta *meta, gpointer params, + GstBuffer *buffer) +{ + meta->base.create_converter = gst_vaapi_surface_create_converter; + meta->buffer = buffer; + return TRUE; +} + +static void +gst_vaapi_surface_meta_free(GstVaapiSurfaceMeta *meta, GstBuffer *buffer) +{ +} + +static gboolean +gst_vaapi_surface_meta_transform(GstBuffer *dst_buffer, GstMeta *meta, + GstBuffer *src_buffer, GQuark type, gpointer data) +{ + GstVaapiVideoMeta * const src_vmeta = + gst_buffer_get_vaapi_video_meta(src_buffer); + + if (GST_META_TRANSFORM_IS_COPY(type)) { + GstVaapiSurfaceMeta * const dst_smeta = GST_VAAPI_SURFACE_META_CAST( + gst_buffer_add_meta(dst_buffer, GST_VAAPI_SURFACE_META_INFO, NULL)); + + /* Note: avoid meta lookups in gst_vaapi_surface_create_converter() + by directly calling the GstVaapiVideoMeta::surface_converter hook */ + dst_smeta->base.create_converter = (GstSurfaceConverterCreateFunc) + gst_vaapi_video_meta_get_surface_converter(src_vmeta); + return TRUE; + } + return FALSE; +} + +const GstMetaInfo * +gst_vaapi_surface_meta_get_info(void) +{ + static gsize g_meta_info; + + if (g_once_init_enter(&g_meta_info)) { + gsize meta_info = GPOINTER_TO_SIZE(gst_meta_register( + GST_SURFACE_META_API_TYPE, + "GstVaapiSurfaceMeta", sizeof(GstVaapiSurfaceMeta), + (GstMetaInitFunction)gst_vaapi_surface_meta_init, + (GstMetaFreeFunction)gst_vaapi_surface_meta_free, + (GstMetaTransformFunction)gst_vaapi_surface_meta_transform)); + g_once_init_leave(&g_meta_info, meta_info); + } + return GSIZE_TO_POINTER(g_meta_info); +} + +static GstBuffer * gst_surface_buffer_new(void) { - return gst_buffer_new(); + GstBuffer * const buffer = gst_buffer_new(); + + if (buffer) + gst_buffer_add_meta(buffer, GST_VAAPI_SURFACE_META_INFO, NULL); + return buffer; } #else #include <gst/video/gstsurfacebuffer.h> |