summaryrefslogtreecommitdiff
path: root/gst/vaapi/gstvaapivideobuffer.c
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-04-15 13:48:43 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2013-04-15 13:48:43 +0200
commit132d78ad3e56e5c6d5ab5992b364c572f60da6bc (patch)
tree7b012d3790b219326eb2e19b7cb5c514198b5f55 /gst/vaapi/gstvaapivideobuffer.c
parentad56d80c9e6b2944de1a29c193296dd949cfbaeb (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.c110
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>