summaryrefslogtreecommitdiff
path: root/ext/wayland
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2013-06-18 13:47:54 +0200
committerSebastian Dröge <slomo@circular-chaos.org>2013-06-18 14:03:13 +0200
commit3fc6f1d9b7110baa3c9e85a9037b3ff4dbdfd330 (patch)
tree9d43fe714c5ddca56433ce1f7681fe1c98830547 /ext/wayland
parent67e71d7931b3573663ff31ae0e4ffff225f2b163 (diff)
downloadgstreamer-plugins-bad-3fc6f1d9b7110baa3c9e85a9037b3ff4dbdfd330.tar.gz
wayland: Add support for RGBx and RGBA formats
Wayland interface could offer two buffers pixels formats: WL_SHM_FORMAT_XRGB8888 and WL_SHM_FORMAT_ARGB8888. Update waylandsink to support them and check if the format is really available. https://bugzilla.gnome.org/show_bug.cgi?id=702112
Diffstat (limited to 'ext/wayland')
-rw-r--r--ext/wayland/gstwaylandsink.c84
-rw-r--r--ext/wayland/gstwaylandsink.h1
-rw-r--r--ext/wayland/waylandpool.c2
3 files changed, 77 insertions, 10 deletions
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index c04a108f9..bf2c3eb4c 100644
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -59,13 +59,17 @@ enum
GST_DEBUG_CATEGORY (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define CAPS "{xRGB, ARGB}"
+#else
+#define CAPS "{BGRx, BGRA}"
+#endif
+
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
- GST_STATIC_CAPS ("video/x-raw, "
- "format = (string) BGRA, "
- "framerate = (fraction) [ 0, MAX ], "
- "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ] "));
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (CAPS))
+ );
/*Fixme: Add more interfaces */
#define gst_wayland_sink_parent_class parent_class
@@ -97,6 +101,48 @@ static void create_window (GstWaylandSink * sink, struct display *display,
int width, int height);
static void shm_pool_destroy (struct shm_pool *pool);
+typedef struct
+{
+ uint32_t wl_format;
+ GstVideoFormat gst_format;
+} wl_VideoFormat;
+
+static const wl_VideoFormat formats[] = {
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+ {WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
+ {WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
+#else
+ {WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
+ {WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
+#endif
+};
+
+static uint32_t
+gst_wayland_format_to_wl_format (GstVideoFormat format)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (formats); i++)
+ if (formats[i].gst_format == format)
+ return formats[i].wl_format;
+
+ GST_WARNING ("wayland video format not found");
+ return -1;
+}
+
+static const gchar *
+gst_wayland_format_to_string (uint32_t wl_format)
+{
+ guint i;
+ GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
+
+ for (i = 0; i < G_N_ELEMENTS (formats); i++)
+ if (formats[i].wl_format == wl_format)
+ format = formats[i].gst_format;
+
+ return gst_video_format_to_string (format);
+}
+
static void
gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
{
@@ -317,17 +363,28 @@ create_display (void)
wl_display_roundtrip (display->display);
- if (!(display->formats & (1 << WL_SHM_FORMAT_XRGB8888))) {
- GST_ERROR ("WL_SHM_FORMAT_XRGB32 not available");
- return NULL;
- }
-
wl_display_get_fd (display->display);
return display;
}
static gboolean
+gst_wayland_sink_format_from_caps (uint32_t * wl_format, GstCaps * caps)
+{
+ GstStructure *structure;
+ const gchar *format;
+ GstVideoFormat fmt;
+
+ structure = gst_caps_get_structure (caps, 0);
+ format = gst_structure_get_string (structure, "format");
+ fmt = gst_video_format_from_string (format);
+
+ *wl_format = gst_wayland_format_to_wl_format (fmt);
+
+ return (*wl_format != -1);
+}
+
+static gboolean
gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
@@ -344,6 +401,15 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
if (!gst_video_info_from_caps (&info, caps))
goto invalid_format;
+ if (!gst_wayland_sink_format_from_caps (&sink->format, caps))
+ goto invalid_format;
+
+ if (!(sink->display->formats & (1 << sink->format))) {
+ GST_DEBUG_OBJECT (sink, "%s not available",
+ gst_wayland_format_to_string (sink->format));
+ return FALSE;
+ }
+
sink->video_width = info.width;
sink->video_height = info.height;
size = info.size;
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index 6607bd18c..cb3383ed2 100644
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -103,6 +103,7 @@ struct _GstWaylandSink
gint video_width;
gint video_height;
+ uint32_t format;
};
struct _GstWaylandSinkClass
diff --git a/ext/wayland/waylandpool.c b/ext/wayland/waylandpool.c
index cab305f33..9eb028aff 100644
--- a/ext/wayland/waylandpool.c
+++ b/ext/wayland/waylandpool.c
@@ -233,7 +233,7 @@ gst_buffer_add_wayland_meta (GstBuffer * buffer, GstWaylandBufferPool * wpool)
return NULL;
wmeta->wbuffer = wl_shm_pool_create_buffer (sink->shm_pool->pool, offset,
- sink->video_width, sink->video_height, stride, WL_SHM_FORMAT_XRGB8888);
+ sink->video_width, sink->video_height, stride, sink->format);
wmeta->data = data;
wmeta->size = size;