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.
This commit is contained in:
Gwenole Beauchesne 2013-04-15 13:48:43 +02:00
parent ad56d80c9e
commit 132d78ad3e

View file

@ -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>