@@ -1245,9 +1245,13 @@ AG_GST_CHECK_FEATURE(DIRECTFB, [directfb],
dfbvideosink , [
dnl **** Wayland ****
translit(dnm, m, l) AM_CONDITIONAL(USE_WAYLAND, true)
AG_GST_CHECK_FEATURE(WAYLAND, [wayland sink], wayland , [
- PKG_CHECK_MODULES(WAYLAND, wayland-client >= 1.0.0, [
- HAVE_WAYLAND="yes" ], [ HAVE_WAYLAND="no"
- ])
+ PKG_CHECK_MODULES(WAYLAND, wayland-client >= 1.0.0,
+ [HAVE_WAYLAND="yes" ], [ HAVE_WAYLAND="no"])
+ PKG_CHECK_MODULES(WAYLAND_DRM, egl >= 9.2.2,
+ [HAVE_WAYLAND_DRM="yes"
+ AC_DEFINE(HAVE_WAYLAND_DRM, 1, [Define if wayland DRM protocol is
available])],
+ [ HAVE_WAYLAND_DRM="no"])
+ AM_CONDITIONAL(USE_WAYLAND_DRM, test "x$HAVE_WAYLAND_DRM" = "xyes")
])
dnl *** DTS ***
@@ -1,12 +1,21 @@
plugin_LTLIBRARIES = libgstwaylandsink.la
-libgstwaylandsink_la_SOURCES = gstwaylandsink.c waylandpool.c
+if USE_WAYLAND_DRM
+wayland_drm_src = waylanddrmpool.c
+wayland_drm_lib = -lgstallocators-$(GST_API_VERSION)
+else
+wayland_drm_src =
+wayland_drm_lib =
+endif
+
+libgstwaylandsink_la_SOURCES = gstwaylandsink.c waylandpool.c
$(wayland_drm_src)
libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
- $(WAYLAND_CFLAGS)
+ $(WAYLAND_CFLAGS) $(WAYLAND_DRM_CFLAGS)
libgstwaylandsink_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
-lgstvideo-$(GST_API_VERSION) \
- $(WAYLAND_LIBS)
+ $(WAYLAND_LIBS) $(WAYLAND_DRM_LIBS) \
+ $(wayland_drm_lib)
libgstwaylandsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstwaylandsink_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
-noinst_HEADERS = gstwaylandsink.h waylandpool.h
+noinst_HEADERS = gstwaylandsink.h waylandpool.h waylanddrmpool.h
@@ -53,10 +53,12 @@ enum
enum
{
PROP_0,
- PROP_WAYLAND_DISPLAY
+ PROP_WAYLAND_DISPLAY,
+ PROP_MODE
};
GST_DEBUG_CATEGORY (gstwayland_debug);
+GST_DEBUG_CATEGORY (gstwayland_debug_pool);
#define GST_CAT_DEFAULT gstwayland_debug
#if G_BYTE_ORDER == G_BIG_ENDIAN
@@ -65,6 +67,27 @@ GST_DEBUG_CATEGORY (gstwayland_debug);
#define CAPS "{BGRx, BGRA}"
#endif
+#define DEFAULT_MODE GST_WAYLAND_POOL_AUTO
+
+#define GST_TYPE_WAYLAND_POOL_MODE (gst_wayland_pool_mode_get_type ())
+static GType
+gst_wayland_pool_mode_get_type (void)
+{
+ static GType wayland_pool_mode_type = 0;
+ static const GEnumValue pool_modes[] = {
+ {GST_WAYLAND_POOL_DRM, "use DRM to allocated pool buffers", "DRM"},
+ {GST_WAYLAND_POOL_SHM, "use shared memory to allocated pool
buffers", "SHM"},
+ {GST_WAYLAND_POOL_AUTO, "use DRM or share memory", "AUTO"},
+ {0, NULL, NULL}
+ };
+
+ if (!wayland_pool_mode_type) {
+ wayland_pool_mode_type =
+ g_enum_register_static ("GstWaylandPoolMode", pool_modes);
+ }
+ return wayland_pool_mode_type;
+}
+
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
@@ -92,7 +115,7 @@ gst_wayland_sink_propose_allocation (GstBaseSink *
bsink, GstQuery * query);
static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
GstBuffer * buffer);
-static struct display *create_display (void);
+static struct display *create_display (GstWaylandSink * wsink);
static void registry_handle_global (void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version);
static void frame_redraw_callback (void *data,
@@ -115,8 +138,29 @@ static const wl_VideoFormat formats[] = {
{WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
{WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
#endif
+#ifdef HAVE_WAYLAND_DRM
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ {WL_DRM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
+ {WL_DRM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
+#else
+ {WL_DRM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
+ {WL_DRM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
+#endif
+#endif
};
+static int
+gst_wayland_wl_format_to_index (uint32_t wl_format)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (formats); i++)
+ if (formats[i].wl_format == wl_format)
+ return i;
+
+ return -1;
+}
+
static uint32_t
gst_wayland_format_to_wl_format (GstVideoFormat format)
{
@@ -179,6 +223,11 @@ 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));
+
+ g_object_class_install_property (gobject_class, PROP_MODE,
+ g_param_spec_enum ("mode", "Mode",
+ "buffer allocation method", GST_TYPE_WAYLAND_POOL_MODE,
+ DEFAULT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}
static void
@@ -188,7 +237,7 @@ gst_wayland_sink_init (GstWaylandSink * sink)
sink->window = NULL;
sink->shm_pool = NULL;
sink->pool = NULL;
-
+ sink->pool_mode = DEFAULT_MODE;
g_mutex_init (&sink->wayland_lock);
}
@@ -202,6 +251,9 @@ gst_wayland_sink_get_property (GObject * object,
case PROP_WAYLAND_DISPLAY:
g_value_set_pointer (value, sink->display);
break;
+ case PROP_MODE:
+ g_value_set_enum (value, sink->pool_mode);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -218,6 +270,9 @@ gst_wayland_sink_set_property (GObject * object,
case PROP_WAYLAND_DISPLAY:
sink->display = g_value_get_pointer (value);
break;
+ case PROP_MODE:
+ sink->pool_mode = g_value_get_enum (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -310,14 +365,61 @@ static void
shm_format (void *data, struct wl_shm *wl_shm, uint32_t format)
{
struct display *d = data;
-
- d->formats |= (1 << format);
+ int index = gst_wayland_wl_format_to_index (format);
+ if (index != -1)
+ d->formats |= (1 << index);
}
struct wl_shm_listener shm_listenter = {
shm_format
};
+#ifdef HAVE_WAYLAND_DRM
+
+static void
+drm_handle_device (void *data, struct wl_drm *wl_drm, const char *name)
+{
+ struct display *d = data;
+ GstWaylandSink *sink = d->sink;
+
+ sink->device_name = strdup (name);
+ if (!sink->device_name) {
+ GST_WARNING_OBJECT (sink, "no device name");
+ return;
+ }
+ GST_DEBUG_OBJECT (sink, "drm device name %s", sink->device_name);
+ sink->authenticated = FALSE;
+
+ return;
+}
+
+static void
+drm_handle_format (void *data, struct wl_drm *wl_drm, uint32_t format)
+{
+ struct display *d = data;
+ GstWaylandSink *sink = d->sink;
+ int index = gst_wayland_wl_format_to_index (format);
+ GST_DEBUG_OBJECT (sink, "server supported format %.4s", (char *) &format);
+ if (index != -1)
+ d->formats |= (1 << index);
+}
+
+static void
+drm_handle_authenticated (void *data, struct wl_drm *wl_drm)
+{
+ struct display *d = data;
+ GstWaylandSink *sink = d->sink;
+ sink->authenticated = TRUE;
+ GST_DEBUG_OBJECT (sink, "authenticated");
+}
+
+struct wl_drm_listener drm_listenter = {
+ drm_handle_device,
+ drm_handle_format,
+ drm_handle_authenticated
+};
+#endif
+
static void
registry_handle_global (void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
@@ -333,6 +435,12 @@ registry_handle_global (void *data, struct
wl_registry *registry,
d->shm = wl_registry_bind (registry, id, &wl_shm_interface, 1);
wl_shm_add_listener (d->shm, &shm_listenter, d);
}
+#ifdef HAVE_WAYLAND_DRM
+ else if (strcmp (interface, "wl_drm") == 0) {
+ d->drm = wl_registry_bind (registry, id, &wl_drm_interface, 1);
+ wl_drm_add_listener (d->drm, &drm_listenter, d);
+ }
+#endif
}
static const struct wl_registry_listener registry_listener = {
@@ -340,7 +448,7 @@ static const struct wl_registry_listener
registry_listener = {
};
static struct display *
-create_display (void)
+create_display (GstWaylandSink * wsink)
{
struct display *display;
@@ -351,6 +459,7 @@ create_display (void)
free (display);
return NULL;
}
+ display->sink = wsink;
display->registry = wl_display_get_registry (display->display);
wl_registry_add_listener (display->registry, ®istry_listener, display);
@@ -388,11 +497,12 @@ static gboolean
gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
- GstBufferPool *newpool, *oldpool;
+ GstBufferPool *newpool = NULL, *oldpool = NULL;
GstVideoInfo info;
GstStructure *structure;
static GstAllocationParams params = { 0, 0, 0, 15, };
guint size;
+ int index;
sink = GST_WAYLAND_SINK (bsink);
@@ -404,7 +514,11 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink,
GstCaps * caps)
if (!gst_wayland_sink_format_from_caps (&sink->format, caps))
goto invalid_format;
- if (!(sink->display->formats & (1 << sink->format))) {
+ index = gst_wayland_wl_format_to_index (sink->format);
+ if (index == -1)
+ goto invalid_format;
+
+ if (!(sink->display->formats & (1 << index))) {
GST_DEBUG_OBJECT (sink, "%s not available",
gst_wayland_format_to_string (sink->format));
return FALSE;
@@ -415,7 +529,17 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink,
GstCaps * caps)
size = info.size;
/* create a new pool for the new configuration */
- newpool = gst_wayland_buffer_pool_new (sink);
+#ifdef HAVE_WAYLAND_DRM
+ if (sink->pool_mode == GST_WAYLAND_POOL_AUTO
+ || sink->pool_mode == GST_WAYLAND_POOL_DRM)
+ newpool = gst_wayland_drm_buffer_pool_new (sink);
+ if (!newpool )
+#endif
+ {
+ if (sink->pool_mode == GST_WAYLAND_POOL_AUTO
+ || sink->pool_mode == GST_WAYLAND_POOL_SHM)
+ newpool = gst_wayland_buffer_pool_new (sink);
+ }
if (!newpool) {
GST_DEBUG_OBJECT (sink, "Failed to create new pool");
@@ -515,7 +639,7 @@ gst_wayland_sink_start (GstBaseSink * bsink)
GST_DEBUG_OBJECT (sink, "start");
if (!sink->display)
- sink->display = create_display ();
+ sink->display = create_display (sink);
if (sink->display == NULL) {
GST_ELEMENT_ERROR (bsink, RESOURCE, OPEN_READ_WRITE,
@@ -579,8 +703,13 @@ gst_wayland_sink_propose_allocation (GstBaseSink
* bsink, GstQuery * query)
goto invalid_caps;
GST_DEBUG_OBJECT (sink, "create new pool");
- pool = gst_wayland_buffer_pool_new (sink);
-
+#ifdef HAVE_WAYLAND_DRM
+ pool = gst_wayland_drm_buffer_pool_new (sink);
+ if (!pool)
+#endif
+ {
+ pool = gst_wayland_buffer_pool_new (sink);
+ }
/* the normal size of a frame */
size = info.size;
@@ -725,7 +854,10 @@ static gboolean
plugin_init (GstPlugin * plugin)
{
GST_DEBUG_CATEGORY_INIT (gstwayland_debug, "waylandsink", 0,
- " wayland video sink");
+ "wayland video sink");
+
+ GST_DEBUG_CATEGORY_INIT (gstwayland_debug_pool, "waylandpool", 0,
+ "wayland pool");
return gst_element_register (plugin, "waylandsink", GST_RANK_MARGINAL,
GST_TYPE_WAYLAND_SINK);
@@ -41,6 +41,10 @@
#include <gst/video/gstvideometa.h>
#include <wayland-client.h>
+#ifdef HAVE_WAYLAND_DRM
+#include <wayland-drm-client-protocol.h>
+#include <xf86drm.h>
+#endif
#define GST_TYPE_WAYLAND_SINK \
(gst_wayland_sink_get_type())
@@ -55,6 +59,9 @@
#define GST_WAYLAND_SINK_GET_CLASS(inst) \
(G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK,
GstWaylandSinkClass))
+typedef struct _GstWaylandSink GstWaylandSink;
+typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
+
struct display
{
struct wl_display *display;
@@ -62,7 +69,11 @@ struct display
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
+#ifdef HAVE_WAYLAND_DRM
+ struct wl_drm *drm;
+#endif
uint32_t formats;
+ GstWaylandSink *sink;
};
struct window
@@ -84,10 +95,21 @@ struct shm_pool {
void *data;
};
-typedef struct _GstWaylandSink GstWaylandSink;
-typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
-
#include "waylandpool.h"
+#ifdef HAVE_WAYLAND_DRM
+#include "waylanddrmpool.h"
+#endif
+
+/**
+ * GST_WAYLAND_POOL_DRM: use DRM to allocated pool buffers
+ * GST_WAYLAND_POOL_SHM: use shared memory to allocated pool buffers
+ * GST_WAYLAND_POOL_AUTO: use DRM or share memory
+ */
+typedef enum {
+ GST_WAYLAND_POOL_DRM,
+ GST_WAYLAND_POOL_SHM,
+ GST_WAYLAND_POOL_AUTO
+} GstWaylandPoolMode;
struct _GstWaylandSink
{
@@ -104,6 +126,11 @@ struct _GstWaylandSink
gint video_width;
gint video_height;
uint32_t format;
+#ifdef HAVE_WAYLAND_DRM
+ gboolean authenticated;
+ char *device_name;
+#endif
+ GstWaylandPoolMode pool_mode;
};
struct _GstWaylandSinkClass
new file mode 100644
@@ -0,0 +1,270 @@
+/* GStreamer
+ * Copyright (C) 2013 Linaro
+ *
+ * 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 St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* Debugging category */
+#include <gst/gstinfo.h>
+
+/* Helper functions */
+#include <gst/video/video.h>
+#include <gst/video/gstvideometa.h>
+#include <gst/video/gstvideopool.h>
+
+#include "gst/allocators/gstdmabuf.h"
+#include "waylanddrmpool.h"
+#include <libkms/libkms.h>
+
+GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug_pool);
+#define GST_CAT_DEFAULT gstwayland_debug_pool
+
+/* bufferpool */
+static void gst_wayland_drm_buffer_pool_finalize (GObject * object);
+
+#define gst_wayland_drm_buffer_pool_parent_class parent_class
+G_DEFINE_TYPE (GstWaylandDRMBufferPool, gst_wayland_drm_buffer_pool,
+ GST_TYPE_BUFFER_POOL);
+
+static void
+wayland_drm_pool_mem_unmap (GstMemory * gmem)
+{
+ /* do nothing, except avoid doing munmap */
+}
+
+static gboolean
+wayland_drm_buffer_pool_set_config (GstBufferPool * pool,
GstStructure * config)
+{
+ GstWaylandDRMBufferPool *wpool = GST_WAYLAND_DRM_BUFFER_POOL_CAST (pool);
+ GstVideoInfo info;
+ GstCaps *caps;
+ GstAllocator *allocator;
+
+ if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL))
+ goto wrong_config;
+
+ if (caps == NULL)
+ goto no_caps;
+
+ /* now parse the caps from the config */
+ if (!gst_video_info_from_caps (&info, caps))
+ goto wrong_caps;
+
+ GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width,
info.height,
+ caps);
+
+ allocator = gst_dmabuf_allocator_obtain ();
+ /* hook to avoid unmap issue on drm buffer */
+ allocator->mem_unmap = wayland_drm_pool_mem_unmap;
+
+ if (wpool->allocator)
+ gst_object_unref (wpool->allocator);
+ if ((wpool->allocator = allocator))
+ gst_object_ref (allocator);
+
+ wpool->caps = gst_caps_ref (caps);
+ wpool->info = info;
+ wpool->width = info.width;
+ wpool->height = info.height;
+
+ return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config);
+ /* ERRORS */
+wrong_config:
+ {
+ GST_WARNING_OBJECT (pool, "invalid config");
+ return FALSE;
+ }
+no_caps:
+ {
+ GST_WARNING_OBJECT (pool, "no caps in config");
+ return FALSE;
+ }
+wrong_caps:
+ {
+ GST_WARNING_OBJECT (pool,
+ "failed getting geometry from caps %" GST_PTR_FORMAT, caps);
+ return FALSE;
+ }
+}
+
+static int
+create_dumb (int drm_fd, uint32_t width, uint32_t height, int
*prime_fd, int *stride)
+{
+ struct drm_mode_create_dumb create_arg;
+ gint ret;
+
+ *prime_fd = -1;
+ *stride = 0;
+
+ memset (&create_arg, 0, sizeof (create_arg));
+ create_arg.bpp = 32;
+ create_arg.width = width;
+ create_arg.height = height;
+
+ GST_WARNING ("Create DUMB buffer %dx%d", width, height);
+ ret = drmIoctl (drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
+ if (ret) {
+ GST_ERROR ("DRM_IOCTL_MODE_CREATE_DUMB failed %s (0x%x) on fd %d",
+ strerror (errno), errno, drm_fd);
+ return ret;
+ }
+
+ *stride = create_arg.pitch;
+
+ ret = drmPrimeHandleToFD (drm_fd, create_arg.handle, DRM_CLOEXEC, prime_fd);
+ if (ret) {
+ struct drm_mode_destroy_dumb destroy_arg;
+
+ GST_WARNING ("Can't get fd from handle");
+
+ memset (&destroy_arg, 0, sizeof destroy_arg);
+ destroy_arg.handle = create_arg.handle;
+ drmIoctl (drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
+ }
+
+ return ret;
+}
+
+static GstWlMeta *
+gst_buffer_add_wayland_meta (GstBuffer * buffer,
+ GstWaylandDRMBufferPool * wpool)
+{
+ GstWlMeta *wmeta;
+ GstWaylandSink *sink;
+ int prime_fd, stride, ret;
+
+ sink = wpool->sink;
+
+ if (!sink->display->drm) {
+ GST_ERROR_OBJECT (wpool, "no drm access");
+ return NULL;
+ }
+
+ ret = create_dumb (wpool->fd, wpool->width, wpool->height,
&prime_fd, &stride);
+ if (ret || prime_fd == -1)
+ return NULL;
+
+ GST_DEBUG_OBJECT (wpool, "drm buffer prime fd %d", prime_fd);
+ wmeta = (GstWlMeta *) gst_buffer_add_meta (buffer, GST_WL_META_INFO, NULL);
+ wmeta->sink = gst_object_ref (sink);
+ wmeta->size = wpool->width * wpool->height * 4;
+ wmeta->wbuffer =
+ wl_drm_create_prime_buffer (sink->display->drm, prime_fd, wpool->width,
+ wpool->height, WL_DRM_FORMAT_XRGB8888, 0, stride, 0, 0, 0, 0);
+
+ GST_DEBUG_OBJECT (wpool, "Add drm buffer to pool");
+
+ gst_buffer_append_memory (buffer,
+ gst_dmabuf_allocator_alloc (wpool->allocator, prime_fd, wmeta->size));
+
+ return wmeta;
+}
+
+static GstFlowReturn
+wayland_drm_buffer_pool_alloc (GstBufferPool * pool, GstBuffer ** buffer,
+ GstBufferPoolAcquireParams * params)
+{
+ GstWaylandDRMBufferPool *wpool = GST_WAYLAND_DRM_BUFFER_POOL_CAST (pool);
+ GstBuffer *w_buffer;
+ GstWlMeta *meta;
+
+ if (wpool->fd == -1 && wpool->device_name) {
+ wpool->fd = open (wpool->device_name, O_RDWR, 0);
+ }
+
+ if (wpool->fd == -1) {
+ GST_ERROR_OBJECT (wpool, "%s not open", wpool->device_name);
+ return GST_FLOW_ERROR;
+ }
+
+ if (!wpool->sink->authenticated) {
+ drm_magic_t magic;
+ drmGetMagic (wpool->fd, &magic);
+ wl_drm_authenticate (wpool->sink->display->drm, magic);
+ wl_display_roundtrip (wpool->sink->display->display);
+ }
+
+ if (!wpool->sink->authenticated) {
+ GST_ERROR_OBJECT (wpool, "client not authenficated !");
+ return GST_FLOW_ERROR;
+ }
+
+ w_buffer = gst_buffer_new ();
+ meta = gst_buffer_add_wayland_meta (w_buffer, wpool);
+ if (meta == NULL) {
+ gst_buffer_unref (w_buffer);
+ goto no_buffer;
+ }
+ *buffer = w_buffer;
+
+ return GST_FLOW_OK;
+
+ /* ERROR */
+no_buffer:
+ {
+ GST_WARNING_OBJECT (wpool, "can't create buffer");
+ return GST_FLOW_ERROR;
+ }
+}
+
+GstBufferPool *
+gst_wayland_drm_buffer_pool_new (GstWaylandSink * sink)
+{
+ GstWaylandDRMBufferPool *wpool;
+
+ g_return_val_if_fail (GST_IS_WAYLAND_SINK (sink), NULL);
+ wpool = g_object_new (GST_TYPE_WAYLAND_DRM_BUFFER_POOL, NULL);
+ wpool->sink = gst_object_ref (sink);
+ wpool->fd = -1;
+ wpool->device_name = strdup (sink->device_name);
+
+ return GST_BUFFER_POOL_CAST (wpool);
+}
+
+static void
+gst_wayland_drm_buffer_pool_class_init (GstWaylandDRMBufferPoolClass * klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstBufferPoolClass *gstbufferpool_class = (GstBufferPoolClass *) klass;
+
+ gobject_class->finalize = gst_wayland_drm_buffer_pool_finalize;
+
+ gstbufferpool_class->set_config = wayland_drm_buffer_pool_set_config;
+ gstbufferpool_class->alloc_buffer = wayland_drm_buffer_pool_alloc;
+}
+
+static void
+gst_wayland_drm_buffer_pool_init (GstWaylandDRMBufferPool * pool)
+{
+
+}
+
+static void
+gst_wayland_drm_buffer_pool_finalize (GObject * object)
+{
+ GstWaylandDRMBufferPool *pool = GST_WAYLAND_DRM_BUFFER_POOL_CAST (object);
+
+ if (pool->allocator)
+ gst_object_unref (pool->allocator);
+
+ gst_object_unref (pool->sink);
+
+ G_OBJECT_CLASS (gst_wayland_drm_buffer_pool_parent_class)->finalize (object);
+}
new file mode 100644
@@ -0,0 +1,63 @@
+/* GStreamer Wayland DRM buffer pool
+ * Copyright (C) 2013 Linaro
+ *
+ * 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 St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_WAYLAND_DRM_BUFFER_POOL_H__
+#define __GST_WAYLAND_DRM_BUFFER_POOL_H__
+
+G_BEGIN_DECLS
+
+#include "gstwaylandsink.h"
+#include "waylandpool.h"
+
+typedef struct _GstWaylandDRMBufferPool GstWaylandDRMBufferPool;
+typedef struct _GstWaylandDRMBufferPoolClass GstWaylandDRMBufferPoolClass;
+
+/* buffer pool functions */
+#define GST_TYPE_WAYLAND_DRM_BUFFER_POOL
(gst_wayland_drm_buffer_pool_get_type())
+#define GST_IS_WAYLAND_DRM_BUFFER_POOL(obj)
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WAYLAND_DRM_BUFFER_POOL))
+#define GST_WAYLAND_DRM_BUFFER_POOL(obj)
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WAYLAND_DRM_BUFFER_POOL,
GstWaylandDRMBufferPool))
+#define GST_WAYLAND_DRM_BUFFER_POOL_CAST(obj) ((GstWaylandDRMBufferPool*)(obj))
+
+struct _GstWaylandDRMBufferPool
+{
+ GstBufferPool bufferpool;
+
+ GstWaylandSink *sink;
+ GstAllocator *allocator;
+ gint fd;
+ gchar *device_name;
+
+ GstCaps *caps;
+ GstVideoInfo info;
+ guint width;
+ guint height;
+};
+
+struct _GstWaylandDRMBufferPoolClass
+{
+ GstBufferPoolClass parent_class;
+};
+
+GType gst_wayland_drm_buffer_pool_get_type (void);
+
+GstBufferPool *gst_wayland_drm_buffer_pool_new (GstWaylandSink * waylandsink);
Use wayland_drm protocol to create a pool of buffer. The benefit is to be able to use dmabuf and so allow zero copy between hardware accelerated elements. Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> --- configure.ac | 10 +- ext/wayland/Makefile.am | 17 ++- ext/wayland/gstwaylandsink.c | 158 ++++++++++++++++++++++-- ext/wayland/gstwaylandsink.h | 33 +++++- ext/wayland/waylanddrmpool.c | 270 ++++++++++++++++++++++++++++++++++++++++++ ext/wayland/waylanddrmpool.h | 63 ++++++++++ 6 files changed, 528 insertions(+), 23 deletions(-) create mode 100644 ext/wayland/waylanddrmpool.c create mode 100644 ext/wayland/waylanddrmpool.h + +G_END_DECLS + +#endif /*__GST_WAYLAND_DRM_BUFFER_POOL_H__*/