waylandsink: support linux dmabuf protocol

Support the wayland zwp_linux_dmabuf_unstable_v1 protocol.
SHM formats and DMABuf formats are exposed differently in caps: the
DMABuf formats are flagged with GST_CAPS_FEATURE_MEMORY_DMABUF.
No buffer pool is proposed for DMABuf buffers, it is the upstream
element responsibility to provide with such buffers.

https://bugzilla.gnome.org/show_bug.cgi?id=711155
This commit is contained in:
Fabien Dessenne 2016-09-22 11:10:47 +02:00 committed by Nicolas Dufresne
parent 3272f2002f
commit 2ad337e440
10 changed files with 430 additions and 56 deletions

View file

@ -1,6 +1,10 @@
plugin_LTLIBRARIES = libgstwaylandsink.la
BUILT_SOURCES = viewporter-protocol.c viewporter-client-protocol.h
BUILT_SOURCES = \
viewporter-protocol.c \
viewporter-client-protocol.h \
linux-dmabuf-unstable-v1-protocol.c \
linux-dmabuf-unstable-v1-client-protocol.h
libgstwaylandsink_la_SOURCES = \
gstwaylandsink.c \
@ -8,9 +12,12 @@ libgstwaylandsink_la_SOURCES = \
wlbuffer.c \
wldisplay.c \
wlwindow.c \
wlvideoformat.c
wlvideoformat.c \
wllinuxdmabuf.c
nodist_libgstwaylandsink_la_SOURCES = viewporter-protocol.c
nodist_libgstwaylandsink_la_SOURCES = \
viewporter-protocol.c \
linux-dmabuf-unstable-v1-protocol.c
libgstwaylandsink_la_CFLAGS = $(GST_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
$(WAYLAND_CFLAGS) $(GST_PLUGINS_BAD_CFLAGS)
@ -29,7 +36,8 @@ noinst_HEADERS = \
wlbuffer.h \
wldisplay.h \
wlwindow.h \
wlvideoformat.h
wlvideoformat.h \
wllinuxdmabuf.h
CLEANFILES = $(BUILT_SOURCES)

View file

@ -45,6 +45,7 @@
#include "wlvideoformat.h"
#include "wlbuffer.h"
#include "wlshmallocator.h"
#include "wllinuxdmabuf.h"
#include <gst/wayland/wayland.h>
#include <gst/video/videooverlay.h>
@ -66,13 +67,17 @@ enum
GST_DEBUG_CATEGORY (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
#define WL_VIDEO_FORMATS \
"{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, " \
"RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, " \
"YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }"
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE
("{ BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, "
"RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, "
"YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }"))
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (WL_VIDEO_FORMATS) ";"
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF,
WL_VIDEO_FORMATS))
);
static void gst_wayland_sink_get_property (GObject * object,
@ -386,29 +391,43 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
sink = GST_WAYLAND_SINK (bsink);
caps = gst_pad_get_pad_template_caps (GST_VIDEO_SINK_PAD (sink));
caps = gst_caps_make_writable (caps);
g_mutex_lock (&sink->display_lock);
if (sink->display) {
GValue list = G_VALUE_INIT;
GValue shm_list = G_VALUE_INIT, dmabuf_list = G_VALUE_INIT;
GValue value = G_VALUE_INIT;
GArray *formats;
gint i;
enum wl_shm_format fmt;
guint fmt;
g_value_init (&list, GST_TYPE_LIST);
g_value_init (&shm_list, GST_TYPE_LIST);
g_value_init (&dmabuf_list, GST_TYPE_LIST);
/* Add corresponding shm formats */
formats = sink->display->shm_formats;
for (i = 0; i < formats->len; i++) {
g_value_init (&value, G_TYPE_STRING);
fmt = g_array_index (formats, uint32_t, i);
g_value_set_static_string (&value, gst_wl_shm_format_to_string (fmt));
gst_value_list_append_and_take_value (&list, &value);
gst_value_list_append_and_take_value (&shm_list, &value);
}
caps = gst_caps_make_writable (caps);
gst_structure_take_value (gst_caps_get_structure (caps, 0), "format",
&list);
&shm_list);
/* Add corresponding dmabuf formats */
formats = sink->display->dmabuf_formats;
for (i = 0; i < formats->len; i++) {
g_value_init (&value, G_TYPE_STRING);
fmt = g_array_index (formats, uint32_t, i);
g_value_set_static_string (&value, gst_wl_dmabuf_format_to_string (fmt));
gst_value_list_append_and_take_value (&dmabuf_list, &value);
}
gst_structure_take_value (gst_caps_get_structure (caps, 1), "format",
&dmabuf_list);
GST_DEBUG_OBJECT (sink, "display caps: %" GST_PTR_FORMAT, caps);
}
@ -454,45 +473,52 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
{
GstWaylandSink *sink;
GstBufferPool *newpool;
GstVideoInfo info;
enum wl_shm_format format;
GArray *formats;
gint i;
gboolean use_dmabuf;
GstVideoFormat format;
sink = GST_WAYLAND_SINK (bsink);
GST_DEBUG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
/* extract info from caps */
if (!gst_video_info_from_caps (&info, caps))
if (!gst_video_info_from_caps (&sink->video_info, caps))
goto invalid_format;
format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (&info));
if ((gint) format == -1)
goto invalid_format;
/* verify we support the requested format */
formats = sink->display->shm_formats;
for (i = 0; i < formats->len; i++) {
if (g_array_index (formats, uint32_t, i) == format)
break;
}
if (i >= formats->len)
goto unsupported_format;
/* store the video info */
sink->video_info = info;
format = GST_VIDEO_INFO_FORMAT (&sink->video_info);
sink->video_info_changed = TRUE;
/* create a new pool for the new configuration */
newpool = gst_wayland_create_pool (sink, caps);
if (!newpool)
goto pool_failed;
use_dmabuf = gst_caps_features_contains (gst_caps_get_features (caps, 0),
GST_CAPS_FEATURE_MEMORY_DMABUF);
if (!use_dmabuf) {
/* shm - verify format support */
enum wl_shm_format format_shm = gst_video_format_to_wl_shm_format (format);
if ((gint) format_shm == -1)
goto invalid_format;
gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
gst_object_unref (newpool);
if (!is_shm_format_supported (format_shm, sink->display))
goto unsupported_format;
/* create a new pool for the new configuration */
newpool = gst_wayland_create_pool (sink, caps);
if (!newpool)
goto pool_failed;
gst_object_replace ((GstObject **) & sink->pool, (GstObject *) newpool);
gst_object_unref (newpool);
} else {
/* dmabuf - verify format support */
gint format_dmabuf = gst_video_format_to_wl_dmabuf_format (format);
if (format_dmabuf == -1)
goto invalid_format;
if (!is_dmabuf_format_supported (format_dmabuf, sink->display))
goto unsupported_format;
/* No pool for dmabuf, this is under upstream element responsability */
}
sink->use_dmabuf = use_dmabuf;
return TRUE;
@ -505,7 +531,7 @@ invalid_format:
unsupported_format:
{
GST_ERROR_OBJECT (sink, "Format %s is not available on the display",
gst_wl_shm_format_to_string (format));
gst_video_format_to_string (format));
return FALSE;
}
pool_failed:
@ -639,12 +665,21 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
GST_LOG_OBJECT (sink, "buffer %p does not have a wl_buffer from our "
"display, creating it", buffer);
/* FIXME check all memory when introducing DMA-Buf */
mem = gst_buffer_peek_memory (buffer, 0);
if (gst_is_fd_memory (mem)) {
wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
&sink->video_info);
} else if (sink->display->dmabuf) {
guint i, nb_dmabuf = 0;
for (i = 0; i < gst_buffer_n_memory (buffer); i++)
if (gst_is_dmabuf_memory (gst_buffer_peek_memory (buffer, i)))
nb_dmabuf++;
if (nb_dmabuf && (nb_dmabuf == gst_buffer_n_memory (buffer)))
wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (buffer, sink->display,
&sink->video_info);
}
if (wbuf) {
@ -655,7 +690,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
GstVideoInfo src_info = sink->video_info;
/* we don't know how to create a wl_buffer directly from the provided
* memory, so we have to copy the data to a memory that we know how
* memory, so we have to copy the data to shm memory that we know how
* to handle... */
GST_LOG_OBJECT (sink, "buffer %p cannot have a wl_buffer, "
@ -690,9 +725,13 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, sink->display,
&sink->video_info);
if (G_UNLIKELY (!wbuf))
goto no_wl_buffer;
goto no_wl_buffer_shm;
gst_buffer_add_wl_buffer (to_render, wbuf, sink->display);
} else {
/* we cannot get a wl_buffer and if we do not have any pool to create
* one by ourself */
goto no_wl_buffer;
}
if (!gst_video_frame_map (&dst, &sink->video_info, to_render,
@ -737,12 +776,18 @@ no_buffer:
GST_WARNING_OBJECT (sink, "could not create buffer");
goto done;
}
no_wl_buffer:
no_wl_buffer_shm:
{
GST_ERROR_OBJECT (sink, "could not create wl_buffer out of wl_shm memory");
ret = GST_FLOW_ERROR;
goto done;
}
no_wl_buffer:
{
GST_ERROR_OBJECT (sink, "buffer %p cannot have a wl_buffer", buffer);
ret = GST_FLOW_ERROR;
goto done;
}
activate_failed:
{
GST_ERROR_OBJECT (sink, "failed to activate bufferpool.");

View file

@ -56,6 +56,7 @@ struct _GstWaylandSink
GstWlDisplay *display;
GstWlWindow *window;
GstBufferPool *pool;
gboolean use_dmabuf;
gboolean video_info_changed;
GstVideoInfo video_info;

View file

@ -24,6 +24,7 @@
#include "wldisplay.h"
#include "wlbuffer.h"
#include "wlvideoformat.h"
#include <errno.h>
@ -45,6 +46,7 @@ static void
gst_wl_display_init (GstWlDisplay * self)
{
self->shm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
self->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
self->wl_fd_poll = gst_poll_new (TRUE);
self->buffers = g_hash_table_new (g_direct_hash, g_direct_equal);
g_mutex_init (&self->buffers_mutex);
@ -71,6 +73,7 @@ gst_wl_display_finalize (GObject * gobject)
g_hash_table_remove_all (self->buffers);
g_array_unref (self->shm_formats);
g_array_unref (self->dmabuf_formats);
gst_poll_free (self->wl_fd_poll);
g_hash_table_unref (self->buffers);
g_mutex_clear (&self->buffers_mutex);
@ -81,6 +84,9 @@ gst_wl_display_finalize (GObject * gobject)
if (self->shm)
wl_shm_destroy (self->shm);
if (self->dmabuf)
zwp_linux_dmabuf_v1_destroy (self->dmabuf);
if (self->shell)
wl_shell_destroy (self->shell);
@ -147,6 +153,50 @@ static const struct wl_shm_listener shm_listener = {
shm_format
};
static void
dmabuf_format (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
uint32_t format)
{
GstWlDisplay *self = data;
if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN)
g_array_append_val (self->dmabuf_formats, format);
}
static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
dmabuf_format,
};
gboolean
is_shm_format_supported (enum wl_shm_format format_shm, GstWlDisplay * display)
{
GArray *formats;
guint i;
formats = display->shm_formats;
for (i = 0; i < formats->len; i++) {
if (g_array_index (formats, uint32_t, i) == format_shm)
return TRUE;
}
return FALSE;
}
gboolean
is_dmabuf_format_supported (guint format_dmabuf, GstWlDisplay * display)
{
GArray *formats;
guint i;
formats = display->dmabuf_formats;
for (i = 0; i < formats->len; i++) {
if (g_array_index (formats, uint32_t, i) == format_dmabuf)
return TRUE;
}
return FALSE;
}
static void
registry_handle_global (void *data, struct wl_registry *registry,
uint32_t id, const char *interface, uint32_t version)
@ -167,6 +217,10 @@ registry_handle_global (void *data, struct wl_registry *registry,
} else if (g_strcmp0 (interface, "wp_viewporter") == 0) {
self->viewporter =
wl_registry_bind (registry, id, &wp_viewporter_interface, 1);
} else if (g_strcmp0 (interface, "zwp_linux_dmabuf_v1") == 0) {
self->dmabuf =
wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 1);
zwp_linux_dmabuf_v1_add_listener (self->dmabuf, &dmabuf_listener, self);
}
}
@ -281,6 +335,10 @@ gst_wl_display_new_existing (struct wl_display * display,
"display may not work properly.");
}
if (!self->dmabuf) {
g_warning ("Could not bind to zwp_linux_dmabuf_v1");
}
self->thread = g_thread_try_new ("GstWlDisplay", gst_wl_display_thread_run,
self, &err);
if (err) {

View file

@ -24,6 +24,7 @@
#include <gst/gst.h>
#include <wayland-client.h>
#include "viewporter-client-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"
G_BEGIN_DECLS
@ -52,7 +53,9 @@ struct _GstWlDisplay
struct wl_shell *shell;
struct wl_shm *shm;
struct wp_viewporter *viewporter;
struct zwp_linux_dmabuf_v1 *dmabuf;
GArray *shm_formats;
GArray *dmabuf_formats;
/* private */
gboolean own_display;
@ -79,6 +82,11 @@ GstWlDisplay *gst_wl_display_new_existing (struct wl_display * display,
void gst_wl_display_register_buffer (GstWlDisplay * self, gpointer buf);
void gst_wl_display_unregister_buffer (GstWlDisplay * self, gpointer buf);
gboolean is_shm_format_supported (enum wl_shm_format format_shm,
GstWlDisplay * display);
gboolean is_dmabuf_format_supported (guint format_dmabuf,
GstWlDisplay * display);
G_END_DECLS
#endif /* __GST_WL_DISPLAY_H__ */

146
ext/wayland/wllinuxdmabuf.c Normal file
View file

@ -0,0 +1,146 @@
/* GStreamer Wayland video sink
*
* Copyright (C) 2016 STMicroelectronics SA
* Copyright (C) 2016 Fabien Dessenne <fabien.dessenne@st.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
* 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gst/allocators/gstdmabuf.h>
#include "wllinuxdmabuf.h"
#include "wlvideoformat.h"
GST_DEBUG_CATEGORY_EXTERN (gstwayland_debug);
#define GST_CAT_DEFAULT gstwayland_debug
typedef struct
{
GMutex lock;
GCond cond;
struct wl_buffer *wbuf;
} ConstructBufferData;
static void
create_succeeded (void *data, struct zwp_linux_buffer_params_v1 *params,
struct wl_buffer *new_buffer)
{
ConstructBufferData *d = data;
g_mutex_lock (&d->lock);
d->wbuf = new_buffer;
zwp_linux_buffer_params_v1_destroy (params);
g_cond_signal (&d->cond);
g_mutex_unlock (&d->lock);
}
static void
create_failed (void *data, struct zwp_linux_buffer_params_v1 *params)
{
ConstructBufferData *d = data;
g_mutex_lock (&d->lock);
d->wbuf = NULL;
zwp_linux_buffer_params_v1_destroy (params);
g_cond_signal (&d->cond);
g_mutex_unlock (&d->lock);
}
static const struct zwp_linux_buffer_params_v1_listener params_listener = {
create_succeeded,
create_failed
};
struct wl_buffer *
gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
GstWlDisplay * display, const GstVideoInfo * info)
{
GstMemory *mem;
int fd, format;
guint i, width, height, offset, stride;
guint nmem, nplanes, mem_idx, flags = 0;
struct zwp_linux_buffer_params_v1 *params;
gint64 timeout;
ConstructBufferData data;
mem = gst_buffer_peek_memory (buf, 0);
format = gst_video_format_to_wl_dmabuf_format (GST_VIDEO_INFO_FORMAT (info));
g_return_val_if_fail (is_dmabuf_format_supported (format, display), NULL);
g_cond_init (&data.cond);
g_mutex_init (&data.lock);
g_mutex_lock (&data.lock);
width = GST_VIDEO_INFO_WIDTH (info);
height = GST_VIDEO_INFO_HEIGHT (info);
nplanes = GST_VIDEO_INFO_N_PLANES (info);
nmem = gst_buffer_n_memory (buf);
/* Creation and configuration of planes */
params = zwp_linux_dmabuf_v1_create_params (display->dmabuf);
for (i = 0; i < nplanes; i++) {
mem_idx = (nmem == nplanes) ? i : 0;
fd = gst_dmabuf_memory_get_fd (gst_buffer_peek_memory (buf, mem_idx));
offset = GST_VIDEO_INFO_PLANE_OFFSET (info, i);
stride = GST_VIDEO_INFO_PLANE_STRIDE (info, i);
zwp_linux_buffer_params_v1_add (params, fd, i, offset, stride, 0, 0);
}
if (GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_INTERLACED)) {
GST_DEBUG_OBJECT (mem->allocator, "interlaced buffer");
flags = ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_INTERLACED;
if (!GST_BUFFER_FLAG_IS_SET (buf, GST_VIDEO_BUFFER_FLAG_TFF)) {
GST_DEBUG_OBJECT (mem->allocator, "with bottom field first");
flags |= ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_BOTTOM_FIRST;
}
}
/* Request buffer creation */
zwp_linux_buffer_params_v1_add_listener (params, &params_listener, &data);
zwp_linux_buffer_params_v1_create (params, width, height, format, flags);
/* Wait for the request answer */
wl_display_flush (display->display);
data.wbuf = (gpointer) 0x1;
timeout = g_get_monotonic_time () + G_TIME_SPAN_SECOND;
while (data.wbuf == (gpointer) 0x1) {
if (!g_cond_wait_until (&data.cond, &data.lock, timeout)) {
GST_ERROR_OBJECT (mem->allocator, "zwp_linux_buffer_params_v1 time out");
zwp_linux_buffer_params_v1_destroy (params);
data.wbuf = NULL;
}
}
if (!data.wbuf) {
GST_ERROR_OBJECT (mem->allocator, "can't create linux-dmabuf buffer");
} else {
GST_DEBUG_OBJECT (mem->allocator, "created linux_dmabuf wl_buffer (%p):"
"%dx%d, fmt=%.4s, %d planes",
data.wbuf, width, height, (char *) &format, nplanes);
}
g_mutex_unlock (&data.lock);
g_mutex_clear (&data.lock);
g_cond_clear (&data.cond);
return data.wbuf;
}

View file

@ -0,0 +1,38 @@
/* GStreamer Wayland video sink
*
* Copyright (C) 2016 STMicroelectronics SA
* Copyright (C) 2016 Fabien Dessenne <fabien.dessenne@st.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
* 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_LINUX_DMABUF_H__
#define __GST_WL_LINUX_DMABUF_H__
#include "gstwaylandsink.h"
G_BEGIN_DECLS
#ifndef GST_CAPS_FEATURE_MEMORY_DMABUF
#define GST_CAPS_FEATURE_MEMORY_DMABUF "memory:DMABuf"
#endif
struct wl_buffer * gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
GstWlDisplay * display, const GstVideoInfo * info);
G_END_DECLS
#endif /* __GST_WL_LINUX_DMABUF_H__ */

View file

@ -146,6 +146,7 @@ gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display,
g_return_val_if_fail (gst_is_fd_memory (mem), NULL);
g_return_val_if_fail (size <= memsize, NULL);
g_return_val_if_fail (is_shm_format_supported (format, display), NULL);
GST_DEBUG_OBJECT (mem->allocator, "Creating wl_buffer of size %"
G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height,

View file

@ -34,9 +34,15 @@ typedef struct
{
enum wl_shm_format wl_format;
GstVideoFormat gst_format;
} wl_VideoFormat;
} wl_ShmVideoFormat;
static const wl_VideoFormat formats[] = {
typedef struct
{
guint wl_format;
GstVideoFormat gst_format;
} wl_DmabufVideoFormat;
static const wl_ShmVideoFormat shm_formats[] = {
#if G_BYTE_ORDER == G_BIG_ENDIAN
{WL_SHM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
{WL_SHM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
@ -77,29 +83,82 @@ static const wl_VideoFormat formats[] = {
{WL_SHM_FORMAT_YUV444, GST_VIDEO_FORMAT_v308},
};
static const wl_DmabufVideoFormat dmabuf_formats[] = {
#if G_BYTE_ORDER == G_BIG_ENDIAN
{DRM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_xRGB},
{DRM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_ARGB},
{DRM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_xBGR},
{DRM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_RGBx},
{DRM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_BGRx},
{DRM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_ABGR},
{DRM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_RGBA},
{DRM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_BGRA},
{DRM_FORMAT_RGB888, GST_VIDEO_FORMAT_RGB},
{DRM_FORMAT_BGR888, GST_VIDEO_FORMAT_BGR},
#else
{DRM_FORMAT_XRGB8888, GST_VIDEO_FORMAT_BGRx},
{DRM_FORMAT_ARGB8888, GST_VIDEO_FORMAT_BGRA},
{DRM_FORMAT_XBGR8888, GST_VIDEO_FORMAT_RGBx},
{DRM_FORMAT_RGBX8888, GST_VIDEO_FORMAT_xBGR},
{DRM_FORMAT_BGRX8888, GST_VIDEO_FORMAT_xRGB},
{DRM_FORMAT_ABGR8888, GST_VIDEO_FORMAT_RGBA},
{DRM_FORMAT_RGBA8888, GST_VIDEO_FORMAT_ABGR},
{DRM_FORMAT_BGRA8888, GST_VIDEO_FORMAT_ARGB},
{DRM_FORMAT_RGB888, GST_VIDEO_FORMAT_BGR},
{DRM_FORMAT_BGR888, GST_VIDEO_FORMAT_RGB},
#endif
{DRM_FORMAT_RGB565, GST_VIDEO_FORMAT_RGB16},
{DRM_FORMAT_YUYV, GST_VIDEO_FORMAT_YUY2},
{DRM_FORMAT_NV12, GST_VIDEO_FORMAT_NV12},
};
enum wl_shm_format
gst_video_format_to_wl_shm_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;
for (i = 0; i < G_N_ELEMENTS (shm_formats); i++)
if (shm_formats[i].gst_format == format)
return shm_formats[i].wl_format;
GST_WARNING ("wayland shm video format not found");
return -1;
}
gint
gst_video_format_to_wl_dmabuf_format (GstVideoFormat format)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (dmabuf_formats); i++)
if (dmabuf_formats[i].gst_format == format)
return dmabuf_formats[i].wl_format;
GST_WARNING ("wayland dmabuf video format not found");
return -1;
}
GstVideoFormat
gst_wl_shm_format_to_video_format (enum wl_shm_format wl_format)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (formats); i++)
if (formats[i].wl_format == wl_format)
return formats[i].gst_format;
for (i = 0; i < G_N_ELEMENTS (shm_formats); i++)
if (shm_formats[i].wl_format == wl_format)
return shm_formats[i].gst_format;
return GST_VIDEO_FORMAT_UNKNOWN;
}
GstVideoFormat
gst_wl_dmabuf_format_to_video_format (guint wl_format)
{
guint i;
for (i = 0; i < G_N_ELEMENTS (dmabuf_formats); i++)
if (dmabuf_formats[i].wl_format == wl_format)
return dmabuf_formats[i].gst_format;
GST_WARNING ("gst video format not found");
return GST_VIDEO_FORMAT_UNKNOWN;
}
@ -109,3 +168,10 @@ gst_wl_shm_format_to_string (enum wl_shm_format wl_format)
return gst_video_format_to_string
(gst_wl_shm_format_to_video_format (wl_format));
}
const gchar *
gst_wl_dmabuf_format_to_string (guint wl_format)
{
return gst_video_format_to_string
(gst_wl_dmabuf_format_to_video_format (wl_format));
}

View file

@ -26,13 +26,16 @@
#include <wayland-client-protocol.h>
#include <gst/video/video.h>
#include <drm/drm_fourcc.h>
G_BEGIN_DECLS
enum wl_shm_format gst_video_format_to_wl_shm_format (GstVideoFormat format);
gint gst_video_format_to_wl_dmabuf_format (GstVideoFormat format);
GstVideoFormat gst_wl_shm_format_to_video_format (enum wl_shm_format wl_format);
GstVideoFormat gst_wl_dmabuf_format_to_video_format (guint wl_format);
const gchar *gst_wl_shm_format_to_string (enum wl_shm_format wl_format);
const gchar *gst_wl_dmabuf_format_to_string (guint wl_format);
G_END_DECLS