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
This commit is contained in:
Benjamin Gaignard 2013-06-18 13:47:54 +02:00 committed by Sebastian Dröge
parent 67e71d7931
commit 3fc6f1d9b7
3 changed files with 77 additions and 10 deletions

View file

@ -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,16 +363,27 @@ 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)
{
@ -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;

View file

@ -103,6 +103,7 @@ struct _GstWaylandSink
gint video_width;
gint video_height;
uint32_t format;
};
struct _GstWaylandSinkClass

View file

@ -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;