mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
waylandsink: Add DRM modifiers support
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5103>
This commit is contained in:
parent
ebea1219a9
commit
6e22846301
11 changed files with 163 additions and 53 deletions
|
@ -29641,7 +29641,7 @@
|
|||
"long-name": "Gtk Wayland Video Sink",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "video/x-raw:\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw:\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
}
|
||||
|
@ -237564,7 +237564,7 @@
|
|||
"long-name": "wayland video sink",
|
||||
"pad-templates": {
|
||||
"sink": {
|
||||
"caps": "video/x-raw:\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"caps": "video/x-raw:\n format: { BGRx, BGRA, RGBx, xBGR, xRGB, RGBA, ABGR, ARGB, RGB, BGR, RGB16, BGR16, YUY2, YVYU, UYVY, AYUV, NV12, NV21, NV16, NV61, YUV9, YVU9, Y41B, I420, YV12, Y42B, v308 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n\nvideo/x-raw(memory:DMABuf):\n format: DMA_DRM\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
|
||||
"direction": "sink",
|
||||
"presence": "always"
|
||||
}
|
||||
|
|
|
@ -50,8 +50,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (WL_VIDEO_FORMATS) ";"
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF,
|
||||
WL_VIDEO_FORMATS))
|
||||
GST_VIDEO_DMA_DRM_CAPS_MAKE)
|
||||
);
|
||||
|
||||
static void gst_gtk_wayland_sink_get_property (GObject * object,
|
||||
|
@ -109,6 +108,7 @@ typedef struct _GstGtkWaylandSinkPrivate
|
|||
|
||||
gboolean video_info_changed;
|
||||
GstVideoInfo video_info;
|
||||
guint64 modifier;
|
||||
GstCaps *caps;
|
||||
|
||||
gboolean redraw_pending;
|
||||
|
@ -797,10 +797,11 @@ gst_gtk_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
if (priv->display) {
|
||||
GValue shm_list = G_VALUE_INIT, dmabuf_list = G_VALUE_INIT;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GArray *formats;
|
||||
GArray *formats, *modifiers;
|
||||
gint i;
|
||||
guint fmt;
|
||||
GstVideoFormat gfmt;
|
||||
guint64 mod;
|
||||
|
||||
g_value_init (&shm_list, GST_TYPE_LIST);
|
||||
g_value_init (&dmabuf_list, GST_TYPE_LIST);
|
||||
|
@ -822,17 +823,19 @@ gst_gtk_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
|
||||
/* Add corresponding dmabuf formats */
|
||||
formats = gst_wl_display_get_dmabuf_formats (priv->display);
|
||||
modifiers = gst_wl_display_get_dmabuf_modifiers (priv->display);
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
fmt = g_array_index (formats, uint32_t, i);
|
||||
gfmt = gst_wl_dmabuf_format_to_video_format (fmt);
|
||||
mod = g_array_index (modifiers, guint64, i);
|
||||
if (gfmt != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_static_string (&value, gst_video_format_to_string (gfmt));
|
||||
g_value_take_string (&value, gst_wl_dmabuf_format_to_string (fmt, mod));
|
||||
gst_value_list_append_and_take_value (&dmabuf_list, &value);
|
||||
}
|
||||
}
|
||||
|
||||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "format",
|
||||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "drm-format",
|
||||
&dmabuf_list);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "display caps: %" GST_PTR_FORMAT, caps);
|
||||
|
@ -948,14 +951,26 @@ gst_gtk_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
gst_gtk_wayland_sink_get_instance_private (self);
|
||||
gboolean use_dmabuf;
|
||||
GstVideoFormat format;
|
||||
GstVideoInfoDmaDrm drm_info;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "set caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
/* extract info from caps */
|
||||
if (!gst_video_info_from_caps (&priv->video_info, caps))
|
||||
goto invalid_format;
|
||||
gst_video_info_dma_drm_init (&drm_info);
|
||||
|
||||
if (gst_video_is_dma_drm_caps (caps)) {
|
||||
if (!gst_video_info_dma_drm_from_caps (&drm_info, caps))
|
||||
goto invalid_format;
|
||||
|
||||
if (!gst_video_info_dma_drm_to_video_info (&drm_info, &priv->video_info))
|
||||
goto invalid_format;
|
||||
} else {
|
||||
/* extract info from caps */
|
||||
if (!gst_video_info_from_caps (&priv->video_info, caps))
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
format = GST_VIDEO_INFO_FORMAT (&priv->video_info);
|
||||
priv->modifier = drm_info.drm_modifier;
|
||||
priv->video_info_changed = TRUE;
|
||||
priv->skip_dumb_buffer_copy = FALSE;
|
||||
|
||||
|
@ -970,9 +985,11 @@ gst_gtk_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
|
||||
/* validate the format base on the memory type. */
|
||||
if (use_dmabuf) {
|
||||
if (!gst_wl_display_check_format_for_dmabuf (priv->display, format))
|
||||
if (!gst_wl_display_check_format_for_dmabuf (priv->display, format,
|
||||
drm_info.drm_modifier))
|
||||
goto unsupported_format;
|
||||
} else if (!gst_wl_display_check_format_for_shm (priv->display, format)) {
|
||||
} else if (!gst_wl_display_check_format_for_shm (priv->display, format,
|
||||
drm_info.drm_modifier)) {
|
||||
/* Note: we still support dmabuf in this case, but formats must also be
|
||||
* supported on SHM interface to ensure a fallback is possible as we are
|
||||
* not guarantied we'll get dmabuf in the buffers. */
|
||||
|
@ -1037,6 +1054,8 @@ gst_gtk_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
|
|||
GstStructure *config;
|
||||
pool = gst_wl_video_buffer_pool_new ();
|
||||
config = gst_buffer_pool_get_config (pool);
|
||||
gst_buffer_pool_config_set_params (config,
|
||||
caps, priv->video_info.size, 2, 0);
|
||||
gst_buffer_pool_config_set_allocator (config,
|
||||
gst_wl_shm_allocator_get (), NULL);
|
||||
gst_buffer_pool_set_config (pool, config);
|
||||
|
@ -1117,6 +1136,7 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
GstVideoFormat format;
|
||||
GstMemory *mem;
|
||||
struct wl_buffer *wbuf = NULL;
|
||||
guint64 modifier;
|
||||
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
|
@ -1162,7 +1182,8 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
"display, creating it", buffer);
|
||||
|
||||
format = GST_VIDEO_INFO_FORMAT (&priv->video_info);
|
||||
if (gst_wl_display_check_format_for_dmabuf (priv->display, format)) {
|
||||
modifier = priv->modifier;
|
||||
if (gst_wl_display_check_format_for_dmabuf (priv->display, format, modifier)) {
|
||||
guint i, nb_dmabuf = 0;
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++)
|
||||
|
@ -1171,7 +1192,7 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
|
||||
if (nb_dmabuf && (nb_dmabuf == gst_buffer_n_memory (buffer)))
|
||||
wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (buffer, priv->display,
|
||||
&priv->video_info);
|
||||
&priv->video_info, modifier);
|
||||
|
||||
/* DMABuf did not work, let try and make this a dmabuf, it does not matter
|
||||
* if it was a SHM since the compositor needs to copy that anyway, and
|
||||
|
@ -1195,7 +1216,7 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
/* attach a wl_buffer if there isn't one yet */
|
||||
if (G_UNLIKELY (!wlbuffer)) {
|
||||
wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (to_render,
|
||||
priv->display, &priv->video_info);
|
||||
priv->display, &priv->video_info, modifier);
|
||||
|
||||
if (G_UNLIKELY (!wbuf)) {
|
||||
GST_WARNING_OBJECT (self, "failed to import DRM Dumb dmabuf");
|
||||
|
@ -1226,7 +1247,9 @@ gst_gtk_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
handle_shm:
|
||||
if (!wbuf && gst_wl_display_check_format_for_shm (priv->display, format)) {
|
||||
if (!wbuf
|
||||
&& gst_wl_display_check_format_for_shm (priv->display, format,
|
||||
modifier)) {
|
||||
if (gst_buffer_n_memory (buffer) == 1 && gst_is_fd_memory (mem))
|
||||
wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, priv->display,
|
||||
&priv->video_info);
|
||||
|
|
|
@ -77,8 +77,7 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
GST_PAD_SINK,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (WL_VIDEO_FORMATS) ";"
|
||||
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_DMABUF,
|
||||
WL_VIDEO_FORMATS))
|
||||
GST_VIDEO_DMA_DRM_CAPS_MAKE)
|
||||
);
|
||||
|
||||
static void gst_wayland_sink_get_property (GObject * object,
|
||||
|
@ -549,10 +548,11 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
if (self->display) {
|
||||
GValue shm_list = G_VALUE_INIT, dmabuf_list = G_VALUE_INIT;
|
||||
GValue value = G_VALUE_INIT;
|
||||
GArray *formats;
|
||||
GArray *formats, *modifiers;
|
||||
gint i;
|
||||
guint fmt;
|
||||
GstVideoFormat gfmt;
|
||||
guint64 mod;
|
||||
|
||||
g_value_init (&shm_list, GST_TYPE_LIST);
|
||||
g_value_init (&dmabuf_list, GST_TYPE_LIST);
|
||||
|
@ -574,17 +574,19 @@ gst_wayland_sink_get_caps (GstBaseSink * bsink, GstCaps * filter)
|
|||
|
||||
/* Add corresponding dmabuf formats */
|
||||
formats = gst_wl_display_get_dmabuf_formats (self->display);
|
||||
modifiers = gst_wl_display_get_dmabuf_modifiers (self->display);
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
fmt = g_array_index (formats, uint32_t, i);
|
||||
gfmt = gst_wl_dmabuf_format_to_video_format (fmt);
|
||||
mod = g_array_index (modifiers, guint64, i);
|
||||
if (gfmt != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
g_value_init (&value, G_TYPE_STRING);
|
||||
g_value_set_static_string (&value, gst_video_format_to_string (gfmt));
|
||||
g_value_take_string (&value, gst_wl_dmabuf_format_to_string (fmt, mod));
|
||||
gst_value_list_append_and_take_value (&dmabuf_list, &value);
|
||||
}
|
||||
}
|
||||
|
||||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "format",
|
||||
gst_structure_take_value (gst_caps_get_structure (caps, 1), "drm-format",
|
||||
&dmabuf_list);
|
||||
|
||||
GST_DEBUG_OBJECT (self, "display caps: %" GST_PTR_FORMAT, caps);
|
||||
|
@ -692,14 +694,26 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
GstWaylandSink *self = GST_WAYLAND_SINK (bsink);;
|
||||
gboolean use_dmabuf;
|
||||
GstVideoFormat format;
|
||||
GstVideoInfoDmaDrm drm_info;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "set caps %" GST_PTR_FORMAT, caps);
|
||||
|
||||
/* extract info from caps */
|
||||
if (!gst_video_info_from_caps (&self->video_info, caps))
|
||||
goto invalid_format;
|
||||
gst_video_info_dma_drm_init (&drm_info);
|
||||
|
||||
if (gst_video_is_dma_drm_caps (caps)) {
|
||||
if (!gst_video_info_dma_drm_from_caps (&drm_info, caps))
|
||||
goto invalid_format;
|
||||
|
||||
if (!gst_video_info_dma_drm_to_video_info (&drm_info, &self->video_info))
|
||||
goto invalid_format;
|
||||
} else {
|
||||
/* extract info from caps */
|
||||
if (!gst_video_info_from_caps (&self->video_info, caps))
|
||||
goto invalid_format;
|
||||
}
|
||||
|
||||
format = GST_VIDEO_INFO_FORMAT (&self->video_info);
|
||||
self->modifier = drm_info.drm_modifier;
|
||||
self->video_info_changed = TRUE;
|
||||
self->skip_dumb_buffer_copy = FALSE;
|
||||
|
||||
|
@ -714,9 +728,11 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
|
|||
|
||||
/* validate the format base on the memory type. */
|
||||
if (use_dmabuf) {
|
||||
if (!gst_wl_display_check_format_for_dmabuf (self->display, format))
|
||||
if (!gst_wl_display_check_format_for_dmabuf (self->display, format,
|
||||
drm_info.drm_modifier))
|
||||
goto unsupported_format;
|
||||
} else if (!gst_wl_display_check_format_for_shm (self->display, format)) {
|
||||
} else if (!gst_wl_display_check_format_for_shm (self->display, format,
|
||||
drm_info.drm_modifier)) {
|
||||
/* Note: we still support dmabuf in this case, but formats must also be
|
||||
* supported on SHM interface to ensure a fallback is possible as we are
|
||||
* not guarantied we'll get dmabuf in the buffers. */
|
||||
|
@ -838,6 +854,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
GstVideoFormat format;
|
||||
GstMemory *mem;
|
||||
struct wl_buffer *wbuf = NULL;
|
||||
guint64 modifier;
|
||||
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
|
@ -894,7 +911,8 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
"display, creating it", buffer);
|
||||
|
||||
format = GST_VIDEO_INFO_FORMAT (&self->video_info);
|
||||
if (gst_wl_display_check_format_for_dmabuf (self->display, format)) {
|
||||
modifier = self->modifier;
|
||||
if (gst_wl_display_check_format_for_dmabuf (self->display, format, modifier)) {
|
||||
guint i, nb_dmabuf = 0;
|
||||
|
||||
for (i = 0; i < gst_buffer_n_memory (buffer); i++)
|
||||
|
@ -903,7 +921,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
|
||||
if (nb_dmabuf && (nb_dmabuf == gst_buffer_n_memory (buffer)))
|
||||
wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (buffer, self->display,
|
||||
&self->video_info);
|
||||
&self->video_info, modifier);
|
||||
|
||||
/* DMABuf did not work, let try and make this a dmabuf, it does not matter
|
||||
* if it was a SHM since the compositor needs to copy that anyway, and
|
||||
|
@ -927,7 +945,7 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
/* attach a wl_buffer if there isn't one yet */
|
||||
if (G_UNLIKELY (!wlbuffer)) {
|
||||
wbuf = gst_wl_linux_dmabuf_construct_wl_buffer (to_render,
|
||||
self->display, &self->video_info);
|
||||
self->display, &self->video_info, modifier);
|
||||
|
||||
if (G_UNLIKELY (!wbuf)) {
|
||||
GST_WARNING_OBJECT (self, "failed to import DRM Dumb dmabuf");
|
||||
|
@ -958,7 +976,9 @@ gst_wayland_sink_show_frame (GstVideoSink * vsink, GstBuffer * buffer)
|
|||
}
|
||||
|
||||
handle_shm:
|
||||
if (!wbuf && gst_wl_display_check_format_for_shm (self->display, format)) {
|
||||
if (!wbuf
|
||||
&& gst_wl_display_check_format_for_shm (self->display, format,
|
||||
modifier)) {
|
||||
if (gst_buffer_n_memory (buffer) == 1 && gst_is_fd_memory (mem))
|
||||
wbuf = gst_wl_shm_memory_construct_wl_buffer (mem, self->display,
|
||||
&self->video_info);
|
||||
|
|
|
@ -54,6 +54,7 @@ struct _GstWaylandSink
|
|||
|
||||
gboolean video_info_changed;
|
||||
GstVideoInfo video_info;
|
||||
guint64 modifier;
|
||||
gboolean fullscreen;
|
||||
GstCaps *caps;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "xdg-shell-client-protocol.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#define GST_CAT_DEFAULT gst_wl_display_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
@ -52,6 +53,7 @@ typedef struct _GstWlDisplayPrivate
|
|||
struct zwp_linux_dmabuf_v1 *dmabuf;
|
||||
GArray *shm_formats;
|
||||
GArray *dmabuf_formats;
|
||||
GArray *dmabuf_modifiers;
|
||||
|
||||
/* private */
|
||||
gboolean own_display;
|
||||
|
@ -85,6 +87,7 @@ gst_wl_display_init (GstWlDisplay * self)
|
|||
|
||||
priv->shm_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->dmabuf_formats = g_array_new (FALSE, FALSE, sizeof (uint32_t));
|
||||
priv->dmabuf_modifiers = g_array_new (FALSE, FALSE, sizeof (guint64));
|
||||
priv->wl_fd_poll = gst_poll_new (TRUE);
|
||||
priv->buffers = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
g_mutex_init (&priv->buffers_mutex);
|
||||
|
@ -123,6 +126,7 @@ gst_wl_display_finalize (GObject * gobject)
|
|||
|
||||
g_array_unref (priv->shm_formats);
|
||||
g_array_unref (priv->dmabuf_formats);
|
||||
g_array_unref (priv->dmabuf_modifiers);
|
||||
gst_poll_free (priv->wl_fd_poll);
|
||||
g_hash_table_unref (priv->buffers);
|
||||
g_mutex_clear (&priv->buffers_mutex);
|
||||
|
@ -181,26 +185,68 @@ static const struct wl_shm_listener shm_listener = {
|
|||
static void
|
||||
dmabuf_format (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
|
||||
uint32_t format)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
dmabuf_modifier (void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
|
||||
uint32_t format, uint32_t modifier_hi, uint32_t modifier_lo)
|
||||
{
|
||||
GstWlDisplay *self = data;
|
||||
guint64 modifier = (guint64) modifier_hi << 32 | modifier_lo;
|
||||
static gboolean table_header = TRUE;
|
||||
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN)
|
||||
if (gst_wl_dmabuf_format_to_video_format (format) != GST_VIDEO_FORMAT_UNKNOWN) {
|
||||
GstVideoFormat gst_format = gst_wl_dmabuf_format_to_video_format (format);
|
||||
const guint32 fourcc = gst_video_dma_drm_fourcc_from_format (gst_format);
|
||||
|
||||
/*
|
||||
* Ignore unsupported formats along with implicit modifiers. Implicit
|
||||
* modifiers have been source of garbled output for many many years and it
|
||||
* was decided that we prefer disabling zero-copy over risking a bad output.
|
||||
*/
|
||||
if (fourcc == DRM_FORMAT_INVALID || modifier == DRM_FORMAT_MOD_INVALID)
|
||||
return;
|
||||
|
||||
if (table_header == TRUE) {
|
||||
GST_INFO ("===== All DMA Formats With Modifiers =====");
|
||||
GST_INFO ("| Gst Format | DRM Format |");
|
||||
table_header = FALSE;
|
||||
}
|
||||
|
||||
if (modifier == 0)
|
||||
GST_INFO ("|-----------------------------------------");
|
||||
|
||||
GST_INFO ("| %-12s | %-23s |",
|
||||
(modifier == 0) ? gst_video_format_to_string (gst_format) : "",
|
||||
gst_video_dma_drm_fourcc_to_string (fourcc, modifier));
|
||||
|
||||
g_array_append_val (priv->dmabuf_formats, format);
|
||||
g_array_append_val (priv->dmabuf_modifiers, modifier);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
|
||||
dmabuf_format,
|
||||
dmabuf_modifier,
|
||||
};
|
||||
|
||||
gboolean
|
||||
gst_wl_display_check_format_for_shm (GstWlDisplay * self, GstVideoFormat format)
|
||||
gst_wl_display_check_format_for_shm (GstWlDisplay * self,
|
||||
GstVideoFormat format, guint64 modifier)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
enum wl_shm_format shm_fmt;
|
||||
GArray *formats;
|
||||
guint i;
|
||||
|
||||
if (modifier != DRM_FORMAT_MOD_INVALID && modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||
GST_ERROR ("SHM interface does not support modifiers");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
shm_fmt = gst_video_format_to_wl_shm_format (format);
|
||||
if (shm_fmt == (enum wl_shm_format) -1)
|
||||
return FALSE;
|
||||
|
@ -216,10 +262,10 @@ gst_wl_display_check_format_for_shm (GstWlDisplay * self, GstVideoFormat format)
|
|||
|
||||
gboolean
|
||||
gst_wl_display_check_format_for_dmabuf (GstWlDisplay * self,
|
||||
GstVideoFormat format)
|
||||
GstVideoFormat format, guint64 modifier)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
GArray *formats;
|
||||
GArray *formats, *modifiers;
|
||||
guint i, dmabuf_fmt;
|
||||
|
||||
if (!priv->dmabuf)
|
||||
|
@ -230,9 +276,13 @@ gst_wl_display_check_format_for_dmabuf (GstWlDisplay * self,
|
|||
return FALSE;
|
||||
|
||||
formats = priv->dmabuf_formats;
|
||||
modifiers = priv->dmabuf_modifiers;
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
if (g_array_index (formats, uint32_t, i) == dmabuf_fmt)
|
||||
return TRUE;
|
||||
if (g_array_index (formats, uint32_t, i) == dmabuf_fmt) {
|
||||
if (g_array_index (modifiers, guint64, i) == modifier) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -277,7 +327,7 @@ registry_handle_global (void *data, struct wl_registry *registry,
|
|||
wl_registry_bind (registry, id, &wp_viewporter_interface, 1);
|
||||
} else if (g_strcmp0 (interface, "zwp_linux_dmabuf_v1") == 0) {
|
||||
priv->dmabuf =
|
||||
wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 1);
|
||||
wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 3);
|
||||
zwp_linux_dmabuf_v1_add_listener (priv->dmabuf, &dmabuf_listener, self);
|
||||
}
|
||||
}
|
||||
|
@ -550,6 +600,14 @@ gst_wl_display_get_dmabuf_v1 (GstWlDisplay * self)
|
|||
return priv->dmabuf;
|
||||
}
|
||||
|
||||
GArray *
|
||||
gst_wl_display_get_dmabuf_modifiers (GstWlDisplay * self)
|
||||
{
|
||||
GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self);
|
||||
|
||||
return priv->dmabuf_modifiers;
|
||||
}
|
||||
|
||||
GArray *
|
||||
gst_wl_display_get_dmabuf_formats (GstWlDisplay * self)
|
||||
{
|
||||
|
|
|
@ -57,11 +57,11 @@ gpointer gst_wl_display_lookup_buffer (GstWlDisplay * self, gpointer gstmem);
|
|||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_check_format_for_shm (GstWlDisplay * self,
|
||||
GstVideoFormat format);
|
||||
GstVideoFormat format, guint64 modifier);
|
||||
|
||||
GST_WL_API
|
||||
gboolean gst_wl_display_check_format_for_dmabuf (GstWlDisplay * self,
|
||||
GstVideoFormat format);
|
||||
GstVideoFormat format, guint64 modifier);
|
||||
|
||||
GST_WL_API
|
||||
struct wl_display *gst_wl_display_get_display (GstWlDisplay * self);
|
||||
|
@ -93,6 +93,9 @@ GArray *gst_wl_display_get_shm_formats (GstWlDisplay * self);
|
|||
GST_WL_API
|
||||
GArray *gst_wl_display_get_dmabuf_formats (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
GArray *gst_wl_display_get_dmabuf_modifiers (GstWlDisplay * self);
|
||||
|
||||
GST_WL_API
|
||||
struct zwp_linux_dmabuf_v1 *gst_wl_display_get_dmabuf_v1 (GstWlDisplay * self);
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ static const struct zwp_linux_buffer_params_v1_listener params_listener = {
|
|||
|
||||
struct wl_buffer *
|
||||
gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
||||
GstWlDisplay * display, const GstVideoInfo * info)
|
||||
GstWlDisplay * display, const GstVideoInfo * info, guint64 modifier)
|
||||
{
|
||||
GstMemory *mem;
|
||||
int format;
|
||||
|
@ -97,7 +97,7 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
|||
ConstructBufferData data;
|
||||
|
||||
g_return_val_if_fail (gst_wl_display_check_format_for_dmabuf (display,
|
||||
GST_VIDEO_INFO_FORMAT (info)), NULL);
|
||||
GST_VIDEO_INFO_FORMAT (info), modifier), NULL);
|
||||
|
||||
mem = gst_buffer_peek_memory (buf, 0);
|
||||
format = gst_video_format_to_wl_dmabuf_format (GST_VIDEO_INFO_FORMAT (info));
|
||||
|
@ -116,9 +116,11 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
|||
strides = vmeta->stride;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (display, "Creating wl_buffer from DMABuf of size %"
|
||||
G_GSSIZE_FORMAT " (%d x %d), format %s", info->size, width, height,
|
||||
gst_wl_dmabuf_format_to_string (format));
|
||||
const gchar *format_string =
|
||||
gst_wl_dmabuf_format_to_string (format, modifier);
|
||||
GST_DEBUG_OBJECT (display,
|
||||
"Creating wl_buffer from DMABuf of size %" G_GSSIZE_FORMAT
|
||||
" (%d x %d), format %s", info->size, width, height, format_string);
|
||||
|
||||
/* Creation and configuration of planes */
|
||||
params = zwp_linux_dmabuf_v1_create_params (gst_wl_display_get_dmabuf_v1
|
||||
|
@ -134,7 +136,7 @@ gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
|||
GstMemory *m = gst_buffer_peek_memory (buf, mem_idx);
|
||||
gint fd = gst_dmabuf_memory_get_fd (m);
|
||||
zwp_linux_buffer_params_v1_add (params, fd, i, m->offset + skip,
|
||||
stride, 0, 0);
|
||||
stride, modifier >> 32, modifier & G_GUINT64_CONSTANT (0x0ffffffff));
|
||||
} else {
|
||||
GST_ERROR_OBJECT (mem->allocator, "memory does not seem to contain "
|
||||
"enough data for the specified format");
|
||||
|
|
|
@ -36,7 +36,7 @@ GST_WL_API
|
|||
void gst_wl_linux_dmabuf_init_once (void);
|
||||
|
||||
GST_WL_API
|
||||
struct wl_buffer * gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
||||
GstWlDisplay * display, const GstVideoInfo * info);
|
||||
struct wl_buffer *gst_wl_linux_dmabuf_construct_wl_buffer (GstBuffer * buf,
|
||||
GstWlDisplay * display, const GstVideoInfo * info, guint64 modifier);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#define GST_CAT_DEFAULT gst_wl_shm_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
@ -219,7 +220,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 (gst_wl_display_check_format_for_shm (display,
|
||||
GST_VIDEO_INFO_FORMAT (info)), NULL);
|
||||
GST_VIDEO_INFO_FORMAT (info), DRM_FORMAT_MOD_INVALID), NULL);
|
||||
|
||||
GST_DEBUG_OBJECT (display, "Creating wl_buffer from SHM of size %"
|
||||
G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height,
|
||||
|
|
|
@ -140,9 +140,11 @@ gst_wl_shm_format_to_string (enum wl_shm_format wl_format)
|
|||
(gst_wl_shm_format_to_video_format (wl_format));
|
||||
}
|
||||
|
||||
const gchar *
|
||||
gst_wl_dmabuf_format_to_string (guint wl_format)
|
||||
gchar *
|
||||
gst_wl_dmabuf_format_to_string (guint wl_format, guint64 modifier)
|
||||
{
|
||||
return gst_video_format_to_string
|
||||
(gst_wl_dmabuf_format_to_video_format (wl_format));
|
||||
GstVideoFormat gst_format = gst_wl_dmabuf_format_to_video_format (wl_format);
|
||||
const guint32 fourcc = gst_video_dma_drm_fourcc_from_format (gst_format);
|
||||
|
||||
return gst_video_dma_drm_fourcc_to_string (fourcc, modifier);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,6 @@ GST_WL_API
|
|||
const gchar *gst_wl_shm_format_to_string (enum wl_shm_format wl_format);
|
||||
|
||||
GST_WL_API
|
||||
const gchar *gst_wl_dmabuf_format_to_string (guint wl_format);
|
||||
gchar * gst_wl_dmabuf_format_to_string (guint wl_format, guint64 modifier);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
Loading…
Reference in a new issue