wayland: port to 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 23 May 2012 10:07:14 +0000 (12:07 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 23 May 2012 10:09:39 +0000 (12:09 +0200)
ext/wayland/gstwaylandsink.c
ext/wayland/gstwaylandsink.h

index 2214409c47d0e9f346213576db1f082b047c5283..5847d74c31be6bb8fdbec5aafdf735fe1ebe254c 100644 (file)
@@ -3,7 +3,8 @@
  *
  * Copyright (C) 2011 Intel Corporation
  * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
- * 
+ * Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.com>
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
  * License as published by the Free Software Foundation; either
@@ -25,7 +26,7 @@
  *  The waylandsink is creating its own window and render the decoded video frames to that.
  *  Setup the Wayland environment as described in
  *  <ulink url="http://wayland.freedesktop.org/building.html">Wayland</ulink> home page.
- *  The current implementaion is based on weston compositor. 
+ *  The current implementaion is based on weston compositor.
  *
  * <refsect2>
  * <title>Example pipelines</title>
@@ -62,41 +63,67 @@ GST_DEBUG_CATEGORY (gstwayland_debug);
 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("video/x-raw-rgb, "
+    GST_STATIC_CAPS ("video/x-raw, "
+        "format = (string) BGRA, "
         "framerate = (fraction) [ 0, MAX ], "
-        "endianness = (int) 4321,"
-        "red_mask = (int) 65280, "
-        "green_mask = (int) 16711680, "
-        "blue_mask = (int) -16777216,"
         "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ] "));
 
-G_DEFINE_TYPE (GstWlBuffer, gst_wlbuffer, GST_TYPE_BUFFER);
-
 /*Fixme: Add more interfaces */
-GST_BOILERPLATE (GstWaylandSink, gst_wayland_sink, GstVideoSink,
-    GST_TYPE_VIDEO_SINK);
+#define gst_wayland_sink_parent_class parent_class
+G_DEFINE_TYPE (GstWaylandSink, gst_wayland_sink, GST_TYPE_VIDEO_SINK);
+
+/* wl metadata */
+GType
+gst_wl_meta_api_get_type (void)
+{
+  static volatile GType type;
+  static const gchar *tags[] =
+      { "memory", "size", "colorspace", "orientation", NULL };
+
+  if (g_once_init_enter (&type)) {
+    GType _type = gst_meta_api_type_register ("GstWlMetaAPI", tags);
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
 
-static void gst_wlbuffer_finalize (GstWlBuffer * wbuffer);
+static void
+gst_wl_meta_free (GstWlMeta * meta, GstBuffer * buffer)
+{
+  gst_object_unref (meta->sink);
+  munmap (meta->data, meta->size);
+  wl_buffer_destroy (meta->wbuffer);
+}
+
+const GstMetaInfo *
+gst_wl_meta_get_info (void)
+{
+  static const GstMetaInfo *wl_meta_info = NULL;
+
+  if (wl_meta_info == NULL) {
+    wl_meta_info =
+        gst_meta_register (GST_WL_META_API_TYPE, "GstWlMeta",
+        sizeof (GstWlMeta), (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) gst_wl_meta_free,
+        (GstMetaTransformFunction) NULL);
+  }
+  return wl_meta_info;
+}
 
 static void gst_wayland_sink_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 static void gst_wayland_sink_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
 static void gst_wayland_sink_finalize (GObject * object);
-static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink);
+static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink,
+    GstCaps * filter);
 static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
 static gboolean gst_wayland_sink_start (GstBaseSink * bsink);
 static gboolean gst_wayland_sink_stop (GstBaseSink * bsink);
-static GstFlowReturn
-gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
 static gboolean gst_wayland_sink_preroll (GstBaseSink * bsink,
     GstBuffer * buffer);
 static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
     GstBuffer * buffer);
-static void gst_wayland_bufferpool_clear (GstWaylandSink * sink);
-static void
-gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer);
 
 static int event_mask_update (uint32_t mask, void *data);
 static struct display *create_display (void);
@@ -106,80 +133,32 @@ static void redraw (void *data, struct wl_callback *callback, uint32_t time);
 static void create_window (GstWaylandSink * sink, struct display *display,
     int width, int height);
 
-static void
-gst_wlbuffer_init (GstWlBuffer * buffer)
-{
-  buffer->wbuffer = NULL;
-  buffer->wlsink = NULL;
-}
-
-static void
-gst_wlbuffer_class_init (GstWlBufferClass * klass)
-{
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (klass);
-
-  mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
-      gst_wlbuffer_finalize;
-}
-
-static void
-gst_wlbuffer_finalize (GstWlBuffer * wbuffer)
-{
-  GstWaylandSink *sink = NULL;
-
-  g_return_if_fail (wbuffer != NULL);
-
-  GST_DEBUG_OBJECT (sink, "Finalizing the WlBuffer");
-  sink = wbuffer->wlsink;
-  if (!sink) {
-    GST_WARNING_OBJECT (wbuffer, "No sink..");
-    goto beach;
-  }
-
-  GST_DEBUG_OBJECT (sink, "recycling buffer %p in pool", wbuffer);
-  /* need to increment the refcount again to recycle */
-  gst_buffer_ref (GST_BUFFER (wbuffer));
-  g_mutex_lock (sink->pool_lock);
-  sink->buffer_pool = g_slist_prepend (sink->buffer_pool, wbuffer);
-  g_mutex_unlock (sink->pool_lock);
-
-beach:
-  return;
-}
-
-static void
-gst_wayland_sink_base_init (gpointer gclass)
-{
-
-  GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sink_template));
-
-  gst_element_class_set_details_simple (element_class,
-      "wayland video sink", "Sink/Video",
-      "Output to wayland surface",
-      "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
-}
-
 static void
 gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSinkClass *gstbasesink_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
   gstbasesink_class = (GstBaseSinkClass *) klass;
 
   gobject_class->set_property = gst_wayland_sink_set_property;
   gobject_class->get_property = gst_wayland_sink_get_property;
   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_wayland_sink_finalize);
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sink_template));
+
+  gst_element_class_set_details_simple (gstelement_class,
+      "wayland video sink", "Sink/Video",
+      "Output to wayland surface",
+      "Sreerenj Balachandran <sreerenj.balachandran@intel.com>");
+
   gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_get_caps);
   gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_set_caps);
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_wayland_sink_start);
-  gstbasesink_class->buffer_alloc =
-      GST_DEBUG_FUNCPTR (gst_wayland_sink_buffer_alloc);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_wayland_sink_stop);
   gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_wayland_sink_preroll);
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_wayland_sink_render);
@@ -188,24 +167,16 @@ gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
       g_param_spec_pointer ("wayland-display", "Wayland Display",
           "Wayland  Display handle created by the application ",
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
-
-  parent_class = g_type_class_peek_parent (klass);
 }
 
 static void
-gst_wayland_sink_init (GstWaylandSink * sink,
-    GstWaylandSinkClass * wayland_sink_class)
+gst_wayland_sink_init (GstWaylandSink * sink)
 {
-
-  sink->caps = NULL;
-  sink->render_finish = TRUE;
+  sink->render_busy = FALSE;
   sink->display = NULL;
   sink->window = NULL;
 
-  sink->pool_lock = g_mutex_new ();
-  sink->buffer_pool = NULL;
-
-  sink->wayland_lock = g_mutex_new ();
+  g_mutex_init (&sink->wayland_lock);
 }
 
 static void
@@ -279,24 +250,15 @@ gst_wayland_sink_finalize (GObject * object)
   if (sink->display)
     destroy_display (sink->display);
 
-  if (sink->pool_lock) {
-    g_mutex_free (sink->pool_lock);
-    sink->pool_lock = NULL;
-  }
-
-  if (sink->buffer_pool) {
-    gst_wayland_bufferpool_clear (sink);
-  }
-
-  g_mutex_free (sink->wayland_lock);
+  g_mutex_clear (&sink->wayland_lock);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static GstCaps *
-gst_wayland_sink_get_caps (GstBaseSink * bsink)
+gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
 {
-  return gst_caps_copy (gst_static_pad_template_get_caps (&sink_template));
+  return gst_static_pad_template_get_caps (&sink_template);
 }
 
 static int
@@ -363,26 +325,24 @@ create_display (void)
   return display;
 }
 
-static GstWlBuffer *
+static GstBuffer *
 wayland_buffer_create (GstWaylandSink * sink)
 {
   char filename[1024];
   int fd, size, stride;
   static void *data;
   static int init = 0;
-  GstWlBuffer *wbuffer;
+  GstBuffer *buffer;
+  GstWlMeta *wmeta;
 
   GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers");
 
-  wbuffer = (GstWlBuffer *) gst_mini_object_new (GST_TYPE_WLBUFFER);
-  wbuffer->wlsink = gst_object_ref (sink);
-
   snprintf (filename, 256, "%s-%d-%s", "/tmp/wayland-shm", init++, "XXXXXX");
 
   fd = mkstemp (filename);
   if (fd < 0) {
     GST_ERROR_OBJECT (sink, "open %s failed:", filename);
-    exit (0);
+    return NULL;
   }
 
   stride = sink->video_width * 4;
@@ -391,7 +351,7 @@ wayland_buffer_create (GstWaylandSink * sink)
   if (ftruncate (fd, size) < 0) {
     GST_ERROR_OBJECT (sink, "ftruncate failed:");
     close (fd);
-    exit (0);
+    return NULL;
   }
 
   data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
@@ -400,92 +360,25 @@ wayland_buffer_create (GstWaylandSink * sink)
     GST_ELEMENT_ERROR (sink, LIBRARY, SHUTDOWN, (NULL),
         ("mmap() failed: %s", strerror (errno)));
     close (fd);
-    exit (0);
+    return NULL;
   }
 
-  wbuffer->wbuffer = wl_shm_create_buffer (sink->display->shm, fd,
+  buffer = gst_buffer_new ();
+
+  wmeta = (GstWlMeta *) gst_buffer_add_meta (buffer, GST_WL_META_INFO, NULL);
+  wmeta->sink = gst_object_ref (sink);
+  wmeta->wbuffer = wl_shm_create_buffer (sink->display->shm, fd,
       sink->video_width, sink->video_height, stride, WL_SHM_FORMAT_XRGB8888);
+  wmeta->data = data;
+  wmeta->size = size;
 
   close (fd);
 
-  GST_BUFFER_DATA (wbuffer) = data;
-  GST_BUFFER_SIZE (wbuffer) = size;
+  gst_buffer_append_memory (buffer,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_NO_SHARE, data,
+          size, 0, size, NULL, NULL));
 
-  return wbuffer;
-}
-
-static void
-gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer)
-{
-  if (buffer->wlsink) {
-    buffer->wlsink = NULL;
-    gst_object_unref (sink);
-  }
-
-  GST_MINI_OBJECT_CLASS (gst_wlbuffer_parent_class)->finalize (GST_MINI_OBJECT
-      (buffer));
-}
-
-static void
-gst_wayland_bufferpool_clear (GstWaylandSink * sink)
-{
-  g_mutex_lock (sink->pool_lock);
-  while (sink->buffer_pool) {
-    GstWlBuffer *buffer = sink->buffer_pool->data;
-
-    sink->buffer_pool = g_slist_delete_link (sink->buffer_pool,
-        sink->buffer_pool);
-    gst_wayland_buffer_destroy (sink, buffer);
-  }
-  g_mutex_unlock (sink->pool_lock);
-}
-
-static GstFlowReturn
-gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
-  GstWlBuffer *buffer = NULL;
-  GstFlowReturn ret = GST_FLOW_OK;
-  GstStructure *structure = NULL;
-  GstCaps *desired_caps = NULL;
-
-  GST_LOG_OBJECT (sink, "a buffer of %u bytes was requested with caps "
-      "%" GST_PTR_FORMAT " and offset %" G_GUINT64_FORMAT, size, caps, offset);
-
-  desired_caps = gst_caps_copy (caps);
-  structure = gst_caps_get_structure (desired_caps, 0);
-
-  if (gst_structure_get_int (structure, "width", &sink->video_width) &&
-      gst_structure_get_int (structure, "height", &sink->video_height)) {
-    sink->bpp = size / sink->video_width / sink->video_height;
-  }
-
-  g_mutex_lock (sink->pool_lock);
-  while (sink->buffer_pool) {
-    buffer = (GstWlBuffer *) sink->buffer_pool->data;
-
-    if (buffer) {
-      sink->buffer_pool =
-          g_slist_delete_link (sink->buffer_pool, sink->buffer_pool);
-    } else {
-      break;
-    }
-  }
-
-  g_mutex_unlock (sink->pool_lock);
-
-  if (!buffer)
-    buffer = wayland_buffer_create (sink);
-
-  if (buffer)
-    gst_buffer_set_caps (GST_BUFFER (buffer), caps);
-
-  *buf = GST_BUFFER (buffer);
-
-  gst_caps_unref (desired_caps);
-
-  return ret;
+  return buffer;
 }
 
 static gboolean
@@ -493,16 +386,10 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
 {
   GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
   const GstStructure *structure;
-  GstCaps *allowed_caps;
   gboolean ret = TRUE;
 
   GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
 
-  allowed_caps = gst_pad_get_caps (GST_BASE_SINK_PAD (bsink));
-
-  if (!gst_caps_can_intersect (allowed_caps, caps))
-    return FALSE;
-
   structure = gst_caps_get_structure (caps, 0);
 
   ret &= gst_structure_get_int (structure, "width", &sink->video_width);
@@ -511,8 +398,6 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
   if (!ret)
     return FALSE;
 
-  gst_caps_replace (&sink->caps, caps);
-
   return TRUE;
 }
 
@@ -524,7 +409,7 @@ redraw (void *data, struct wl_callback *callback, uint32_t time)
 
   GstWaylandSink *sink = (GstWaylandSink *) data;
 
-  sink->render_finish = TRUE;
+  sink->render_busy = FALSE;
 }
 
 static void
@@ -536,7 +421,7 @@ create_window (GstWaylandSink * sink, struct display *display, int width,
   if (sink->window)
     return;
 
-  g_mutex_lock (sink->wayland_lock);
+  g_mutex_lock (&sink->wayland_lock);
 
   window = malloc (sizeof *window);
   window->display = display;
@@ -547,12 +432,14 @@ create_window (GstWaylandSink * sink, struct display *display, int width,
   window->shell_surface = wl_shell_get_shell_surface (display->shell,
       window->surface);
   /* wl_shell_surface_set_toplevel (window->shell_surface); */
+#ifdef WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT
   wl_shell_surface_set_fullscreen (window->shell_surface,
       WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
+#endif
 
   sink->window = window;
 
-  g_mutex_unlock (sink->wayland_lock);
+  g_mutex_unlock (&sink->wayland_lock);
 }
 
 static gboolean
@@ -582,8 +469,7 @@ gst_wayland_sink_stop (GstBaseSink * bsink)
 static GstFlowReturn
 gst_wayland_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
 {
-  GST_DEBUG_OBJECT (bsink, "preroll buffer %p, data = %p", buffer,
-      GST_BUFFER_DATA (buffer));
+  GST_DEBUG_OBJECT (bsink, "preroll buffer %p", buffer);
   return gst_wayland_sink_render (bsink, buffer);
 }
 
@@ -591,73 +477,68 @@ static GstFlowReturn
 gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 {
   GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
-  gboolean mem_cpy = TRUE;
   GstVideoRectangle src, dst, res;
+  GstBuffer *to_render;
+  GstWlMeta *meta;
 
-  GST_LOG_OBJECT (sink,
-      "render buffer %p, data = %p, timestamp = %" GST_TIME_FORMAT, buffer,
-      GST_BUFFER_DATA (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
+  GST_LOG_OBJECT (sink, "render buffer %p" GST_TIME_FORMAT, buffer);
 
   if (!sink->window)
     create_window (sink, sink->display, sink->video_width, sink->video_height);
 
-  if (sink->render_finish) {
-    if (GST_IS_WLBUFFER (buffer)) {
-      GstWlBuffer *tmp_buffer = (GstWlBuffer *) buffer;
+  if (sink->render_busy)
+    goto was_busy;
 
-      /* Does it have a waylandbuffer ? */
-      if (tmp_buffer->wbuffer) {
-        mem_cpy = FALSE;
-        GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
-            "ourselves and it has a wayland buffer, no memcpy then", buffer);
-        sink->window->buffer = tmp_buffer->wbuffer;
-      } else {
-        /* No wayland buffer, that's a malloc */
-        GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
-            "ourselves but it does not hold a wayland buffer", buffer);
-      }
-    } else {
-      /* Not our baby! */
-      GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we did not allocate",
-          buffer);
-    }
+  meta = gst_buffer_get_wl_meta (buffer);
 
-    if (mem_cpy) {
+  if (meta && meta->sink == sink) {
+    GST_LOG_OBJECT (sink, "buffer %p from our pool, writing directly", buffer);
+    to_render = buffer;
+  } else {
+    GstMapInfo src;
 
-      GstWlBuffer *wlbuf = wayland_buffer_create (sink);
+    GST_LOG_OBJECT (sink, "buffer %p not from our pool, copying", buffer);
 
-      memcpy (GST_BUFFER_DATA (wlbuf), GST_BUFFER_DATA (buffer),
-          GST_BUFFER_SIZE (buffer));
-      sink->window->buffer = wlbuf->wbuffer;
-    }
+    to_render = wayland_buffer_create (sink);
 
-    src.w = sink->video_width;
-    src.h = sink->video_height;
-    dst.w = sink->window->width;
-    dst.h = sink->window->height;
+    gst_buffer_map (buffer, &src, GST_MAP_READ);
+    gst_buffer_fill (to_render, 0, src.data, src.size);
+    gst_buffer_unmap (buffer, &src);
 
-    gst_video_sink_center_rect (src, dst, &res, FALSE);
+    meta = gst_buffer_get_wl_meta (to_render);
+  }
 
-    sink->render_finish = FALSE;
+  src.w = sink->video_width;
+  src.h = sink->video_height;
+  dst.w = sink->window->width;
+  dst.h = sink->window->height;
 
-    wl_buffer_damage (sink->window->buffer, 0, 0, res.w, res.h);
+  gst_video_sink_center_rect (src, dst, &res, FALSE);
 
-    wl_surface_attach (sink->window->surface, sink->window->buffer, 0, 0);
+  sink->render_busy = TRUE;
 
-    wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
+  wl_buffer_damage (meta->wbuffer, 0, 0, res.w, res.h);
+  wl_surface_attach (sink->window->surface, meta->wbuffer, 0, 0);
+  wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
 
-    if (sink->callback)
-      wl_callback_destroy (sink->callback);
+  if (sink->callback)
+    wl_callback_destroy (sink->callback);
 
-    sink->callback = wl_surface_frame (sink->window->surface);
-    wl_callback_add_listener (sink->callback, &frame_listener, sink);
-    wl_display_iterate (sink->display->display, sink->display->mask);
+  sink->callback = wl_surface_frame (sink->window->surface);
+  wl_callback_add_listener (sink->callback, &frame_listener, sink);
+  wl_display_iterate (sink->display->display, sink->display->mask);
 
-  } else
-    GST_LOG_OBJECT (sink,
-        "Waiting to get the signal from compositor to render the next frame..");
+  if (buffer != to_render)
+    gst_buffer_unref (to_render);
 
   return GST_FLOW_OK;
+
+was_busy:
+  {
+    GST_LOG_OBJECT (sink,
+        "Waiting to get the signal from compositor to render the next frame..");
+    return GST_FLOW_OK;
+  }
 }
 
 static const struct wl_callback_listener frame_listener = {
index f9c1ca87cbc4e1e3f0336be566970099e9949f7f..22a4ede6171e44ef1e471d6c01e4d0782308ef37 100644 (file)
@@ -69,63 +69,54 @@ struct window
   int width, height;
   struct wl_surface *surface;
   struct wl_shell_surface *shell_surface;
-  struct wl_buffer *buffer;
 };
 
 typedef struct _GstWaylandSink GstWaylandSink;
 typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
 
-#define GST_TYPE_WLBUFFER (gst_wlbuffer_get_type())
-#define GST_IS_WLBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WLBUFFER))
-#define GST_WLBUFFER (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WLBUFFER, GstWlBuffer))
+typedef struct _GstWlMeta GstWlMeta;
 
-typedef struct _GstWlBuffer GstWlBuffer;
-typedef struct _GstWlBufferClass GstWlBufferClass;
+GType gst_wl_meta_api_get_type (void);
+#define GST_WL_META_API_TYPE  (gst_wl_meta_api_get_type())
+const GstMetaInfo * gst_wl_meta_get_info (void);
+#define GST_WL_META_INFO  (gst_wl_meta_get_info())
 
-struct _GstWlBuffer {
-  GstBuffer buffer; /* Extending GstBuffer */
-  
-  struct wl_buffer *wbuffer;
-  
-  GstWaylandSink *wlsink;
-};
+#define gst_buffer_get_wl_meta(b) ((GstWlMeta*)gst_buffer_get_meta((b),GST_WL_META_API_TYPE))
 
-struct _GstWlBufferClass
-{
-  GstBufferClass parent_class;
+struct _GstWlMeta {
+  GstMeta meta;
+
+  GstWaylandSink *sink;
+
+  struct wl_buffer *wbuffer;
+  void *data;
+  size_t size;
 };
 
 struct _GstWaylandSink
 {
-
   GstVideoSink parent;
 
-  GstCaps *caps;
-  
   struct display *display;
   struct window *window;
   struct wl_callback *callback;
 
-  GMutex *pool_lock;
-  GSList *buffer_pool;
-
-  GMutex *wayland_lock;
+  GMutex wayland_lock;
 
   gint video_width;
   gint video_height;
   guint bpp;
 
-  gboolean render_finish;
-
+  gboolean render_busy;
 };
 
 struct _GstWaylandSinkClass
 {
-  GstVideoSinkClass parent; 
+  GstVideoSinkClass parent;
 };
 
 GType gst_wayland_sink_get_type (void) G_GNUC_CONST;
-GType gst_wlbuffer_get_type (void);
 
 G_END_DECLS
+
 #endif /* __GST_WAYLAND_VIDEO_SINK_H__ */