waylandsink: split window-related code out to a new GstWlWindow class
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Thu, 13 Feb 2014 10:59:45 +0000 (11:59 +0100)
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>
Tue, 17 Jun 2014 11:51:22 +0000 (13:51 +0200)
GstWlWindow also has API ready to support subsurfaces.

ext/wayland/Makefile.am
ext/wayland/gstwaylandsink.c
ext/wayland/gstwaylandsink.h
ext/wayland/wlwindow.c [new file with mode: 0644]
ext/wayland/wlwindow.h [new file with mode: 0644]

index 60cbf7e..ffc13ef 100644 (file)
@@ -1,7 +1,7 @@
 plugin_LTLIBRARIES = libgstwaylandsink.la
 
-libgstwaylandsink_la_SOURCES =  gstwaylandsink.c waylandpool.c wldisplay.c \
-                                wlvideoformat.c
+libgstwaylandsink_la_SOURCES =  gstwaylandsink.c waylandpool.c \
+                                wldisplay.c wlwindow.c wlvideoformat.c
 libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
                                $(WAYLAND_CFLAGS)
 libgstwaylandsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
@@ -10,4 +10,5 @@ libgstwaylandsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
 libgstwaylandsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstwaylandsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
-noinst_HEADERS = gstwaylandsink.h waylandpool.h wldisplay.h wlvideoformat.h
+noinst_HEADERS = gstwaylandsink.h waylandpool.h \
+                 wldisplay.h wlwindow.h wlvideoformat.h
index 0767a0e..6c12c35 100644 (file)
@@ -94,8 +94,6 @@ static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
 
 static void frame_redraw_callback (void *data,
     struct wl_callback *callback, uint32_t time);
-static void create_window (GstWaylandSink * sink, GstWlDisplay * display,
-    int width, int height);
 
 static void
 gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
@@ -177,18 +175,6 @@ gst_wayland_sink_set_property (GObject * object,
 }
 
 static void
-destroy_window (struct window *window)
-{
-  if (window->shell_surface)
-    wl_shell_surface_destroy (window->shell_surface);
-
-  if (window->surface)
-    wl_surface_destroy (window->surface);
-
-  free (window);
-}
-
-static void
 gst_wayland_sink_finalize (GObject * object)
 {
   GstWaylandSink *sink = GST_WAYLAND_SINK (object);
@@ -196,7 +182,7 @@ gst_wayland_sink_finalize (GObject * object)
   GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
 
   if (sink->window)
-    destroy_window (sink->window);
+    g_object_unref (sink->window);
   if (sink->display)
     g_object_unref (sink->display);
 
@@ -289,62 +275,6 @@ config_failed:
   }
 }
 
-static void
-handle_ping (void *data, struct wl_shell_surface *shell_surface,
-    uint32_t serial)
-{
-  wl_shell_surface_pong (shell_surface, serial);
-}
-
-static void
-handle_configure (void *data, struct wl_shell_surface *shell_surface,
-    uint32_t edges, int32_t width, int32_t height)
-{
-}
-
-static void
-handle_popup_done (void *data, struct wl_shell_surface *shell_surface)
-{
-}
-
-static const struct wl_shell_surface_listener shell_surface_listener = {
-  handle_ping,
-  handle_configure,
-  handle_popup_done
-};
-
-static void
-create_window (GstWaylandSink * sink, GstWlDisplay * display, int width,
-    int height)
-{
-  struct window *window;
-
-  if (sink->window)
-    return;
-
-  g_mutex_lock (&sink->wayland_lock);
-
-  window = malloc (sizeof *window);
-  window->width = width;
-  window->height = height;
-
-  window->surface = wl_compositor_create_surface (display->compositor);
-
-  window->shell_surface = wl_shell_get_shell_surface (display->shell,
-      window->surface);
-
-  g_return_if_fail (window->shell_surface);
-
-  wl_shell_surface_add_listener (window->shell_surface,
-      &shell_surface_listener, window);
-
-  wl_shell_surface_set_toplevel (window->shell_surface);
-
-  sink->window = window;
-
-  g_mutex_unlock (&sink->wayland_lock);
-}
-
 static gboolean
 gst_wayland_sink_start (GstBaseSink * bsink)
 {
@@ -471,14 +401,13 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
   GstBuffer *to_render;
   GstWlMeta *meta;
   GstFlowReturn ret;
-  struct window *window;
+  struct wl_surface *surface;
   struct wl_callback *callback;
 
   GST_LOG_OBJECT (sink, "render buffer %p", buffer);
   if (!sink->window)
-    create_window (sink, sink->display, sink->video_width, sink->video_height);
-
-  window = sink->window;
+    sink->window = gst_wl_window_new_toplevel (sink->display, sink->video_width,
+        sink->video_height);
 
   meta = gst_buffer_get_wl_meta (buffer);
 
@@ -513,11 +442,13 @@ gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
 
   gst_video_sink_center_rect (src, dst, &res, FALSE);
 
-  wl_surface_attach (sink->window->surface, meta->wbuffer, 0, 0);
-  wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
-  callback = wl_surface_frame (window->surface);
-  wl_callback_add_listener (callback, &frame_callback_listener, window);
-  wl_surface_commit (window->surface);
+  surface = gst_wl_window_get_wl_surface (sink->window);
+
+  wl_surface_attach (surface, meta->wbuffer, 0, 0);
+  wl_surface_damage (surface, 0, 0, res.w, res.h);
+  callback = wl_surface_frame (surface);
+  wl_callback_add_listener (callback, &frame_callback_listener, NULL);
+  wl_surface_commit (surface);
   wl_display_flush (sink->display->display);
 
   if (buffer != to_render)
index 9dfddbd..c72b54c 100644 (file)
@@ -43,6 +43,7 @@
 #include <wayland-client.h>
 
 #include "wldisplay.h"
+#include "wlwindow.h"
 
 G_BEGIN_DECLS
 
@@ -59,13 +60,6 @@ G_BEGIN_DECLS
 #define GST_WAYLAND_SINK_GET_CLASS(inst) \
         (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstWaylandSinkClass))
 
-struct window
-{
-  int width, height;
-  struct wl_surface *surface;
-  struct wl_shell_surface *shell_surface;
-};
-
 typedef struct _GstWaylandSink GstWaylandSink;
 typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
 
@@ -78,8 +72,7 @@ struct _GstWaylandSink
   GstVideoSink parent;
 
   GstWlDisplay *display;
-  struct window *window;
-
+  GstWlWindow *window;
   GstBufferPool *pool;
 
   GMutex wayland_lock;
diff --git a/ext/wayland/wlwindow.c b/ext/wayland/wlwindow.c
new file mode 100644 (file)
index 0000000..97107ef
--- /dev/null
@@ -0,0 +1,167 @@
+/* GStreamer Wayland video sink
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Sreerenj Balachandran <sreerenj.balachandran@intel.com>
+ * Copyright (C) 2014 Collabora Ltd.
+ *
+ * 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
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#include "wlwindow.h"
+
+G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT);
+
+static void gst_wl_window_finalize (GObject * gobject);
+
+static void
+handle_ping (void *data, struct wl_shell_surface *shell_surface,
+    uint32_t serial)
+{
+  wl_shell_surface_pong (shell_surface, serial);
+}
+
+static void
+handle_configure (void *data, struct wl_shell_surface *shell_surface,
+    uint32_t edges, int32_t width, int32_t height)
+{
+}
+
+static void
+handle_popup_done (void *data, struct wl_shell_surface *shell_surface)
+{
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+  handle_ping,
+  handle_configure,
+  handle_popup_done
+};
+
+static void
+gst_wl_window_class_init (GstWlWindowClass * klass)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = gst_wl_window_finalize;
+}
+
+static void
+gst_wl_window_init (GstWlWindow * self)
+{
+}
+
+static void
+gst_wl_window_finalize (GObject * gobject)
+{
+  GstWlWindow *self = GST_WL_WINDOW (gobject);
+
+  if (self->shell_surface) {
+    wl_shell_surface_destroy (self->shell_surface);
+  }
+
+  if (self->own_surface) {
+    wl_surface_destroy (self->surface);
+  }
+
+  g_clear_object (&self->display);
+
+  G_OBJECT_CLASS (gst_wl_window_parent_class)->finalize (gobject);
+}
+
+GstWlWindow *
+gst_wl_window_new_toplevel (GstWlDisplay * display, gint width, gint height)
+{
+  GstWlWindow *window;
+
+  window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
+  window->display = g_object_ref (display);
+  window->width = width;
+  window->height = height;
+
+  window->surface = wl_compositor_create_surface (display->compositor);
+  window->own_surface = TRUE;
+
+  window->shell_surface = wl_shell_get_shell_surface (display->shell,
+      window->surface);
+
+  if (window->shell_surface) {
+    wl_shell_surface_add_listener (window->shell_surface,
+        &shell_surface_listener, window);
+    wl_shell_surface_set_toplevel (window->shell_surface);
+  } else {
+    GST_ERROR ("Unable to get wl_shell_surface");
+
+    g_object_unref (window);
+    return NULL;
+  }
+
+  return window;
+}
+
+GstWlWindow *
+gst_wl_window_new_from_surface (GstWlDisplay * display,
+    struct wl_surface * surface, gint width, gint height)
+{
+  GstWlWindow *window;
+
+  g_return_val_if_fail (surface != NULL, NULL);
+
+  window = g_object_new (GST_TYPE_WL_WINDOW, NULL);
+  window->display = g_object_ref (display);
+  window->width = width;
+  window->height = height;
+
+  window->surface = surface;
+  window->own_surface = FALSE;
+
+  return window;
+}
+
+GstWlDisplay *
+gst_wl_window_get_display (GstWlWindow * window)
+{
+  g_return_val_if_fail (window != NULL, NULL);
+
+  return g_object_ref (window->display);
+}
+
+struct wl_surface *
+gst_wl_window_get_wl_surface (GstWlWindow * window)
+{
+  g_return_val_if_fail (window != NULL, NULL);
+
+  return window->surface;
+}
+
+void
+gst_wl_window_get_size (GstWlWindow * window, gint * w, gint * h)
+{
+  g_return_if_fail (window != NULL);
+
+  if (w)
+    *w = window->width;
+
+  if (h)
+    *h = window->height;
+}
+
+void
+gst_wl_window_set_size (GstWlWindow * window, gint w, gint h)
+{
+  g_return_if_fail (window != NULL);
+
+  window->width = w;
+  window->height = h;
+}
diff --git a/ext/wayland/wlwindow.h b/ext/wayland/wlwindow.h
new file mode 100644 (file)
index 0000000..8ba6a91
--- /dev/null
@@ -0,0 +1,65 @@
+/* GStreamer Wayland video sink
+ *
+ * Copyright (C) 2014 Collabora Ltd.
+ *
+ * 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
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __GST_WL_WINDOW_H__
+#define __GST_WL_WINDOW_H__
+
+#include "wldisplay.h"
+
+#define GST_TYPE_WL_WINDOW                  (gst_wl_window_get_type ())
+#define GST_WL_WINDOW(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WL_WINDOW, GstWlWindow))
+#define GST_IS_WL_WINDOW(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WL_WINDOW))
+#define GST_WL_WINDOW_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_WL_WINDOW, GstWlWindowClass))
+#define GST_IS_WL_WINDOW_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_WL_WINDOW))
+#define GST_WL_WINDOW_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_WL_WINDOW, GstWlWindowClass))
+
+typedef struct _GstWlWindow GstWlWindow;
+typedef struct _GstWlWindowClass GstWlWindowClass;
+
+struct _GstWlWindow
+{
+  GObject parent_instance;
+
+  GstWlDisplay *display;
+  struct wl_surface *surface;
+  struct wl_shell_surface *shell_surface;
+  gint width, height;
+  gboolean own_surface;
+};
+
+struct _GstWlWindowClass
+{
+  GObjectClass parent_class;
+};
+
+GType gst_wl_window_get_type (void);
+
+GstWlWindow *gst_wl_window_new_toplevel (GstWlDisplay * display,
+        gint width, gint height);
+GstWlWindow *gst_wl_window_new_from_surface (GstWlDisplay * display,
+        struct wl_surface * surface, gint width, gint height);
+
+GstWlDisplay *gst_wl_window_get_display (GstWlWindow * window);
+struct wl_surface *gst_wl_window_get_wl_surface (GstWlWindow * window);
+
+void gst_wl_window_get_size (GstWlWindow * window, gint * w, gint * h);
+void gst_wl_window_set_size (GstWlWindow * window, gint w, gint h);
+
+#endif /* __GST_WL_WINDOW_H__ */