From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Robert Mader <robert.mader@collabora.com>
Date: Sun, 25 Feb 2024 17:36:08 +0100
Subject: [PATCH] gst: Sanitize caps before translating
DMABuf caps without concrete formats and modifiers don't map well to the
Pipewire negotiation process.
Introduce a new gst_caps_sanitize() helper function, where such cases
can be handled.
---
src/gst/gstpipewireformat.c | 40 +++++++++++++++++++++++++++++++++++++
src/gst/gstpipewireformat.h | 2 ++
src/gst/gstpipewiresrc.c | 6 +++++-
3 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c
index ff1752a06565..6830de234a8d 100644
--- a/src/gst/gstpipewireformat.c
+++ b/src/gst/gstpipewireformat.c
@@ -1176,3 +1176,43 @@ gst_caps_from_format (const struct spa_pod *format)
}
return res;
}
+
+static gboolean
+filter_dmabuf_caps (GstCapsFeatures *features,
+ GstStructure *structure,
+ gpointer user_data)
+{
+ const GValue *value;
+ const char *v;
+
+ if (!gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF))
+ return TRUE;
+
+ if (!(value = gst_structure_get_value (structure, "format")) ||
+ !(v = get_nth_string (value, 0)))
+ return FALSE;
+
+#ifdef HAVE_GSTREAMER_DMA_DRM
+ {
+ int idx;
+
+ idx = gst_video_format_from_string (v);
+ if (idx == GST_VIDEO_FORMAT_UNKNOWN)
+ return FALSE;
+
+ if (idx == GST_VIDEO_FORMAT_DMA_DRM &&
+ !gst_structure_get_value (structure, "drm-format"))
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+GstCaps *
+gst_caps_sanitize (GstCaps *caps)
+{
+ caps = gst_caps_make_writable (caps);
+ gst_caps_filter_and_map_in_place (caps, filter_dmabuf_caps, NULL);
+ return caps;
+}
diff --git a/src/gst/gstpipewireformat.h b/src/gst/gstpipewireformat.h
index abd45c4e9bbb..ca76b70c2f06 100644
--- a/src/gst/gstpipewireformat.h
+++ b/src/gst/gstpipewireformat.h
@@ -15,6 +15,8 @@ GPtrArray * gst_caps_to_format_all (GstCaps *caps);
GstCaps * gst_caps_from_format (const struct spa_pod *format);
+GstCaps * gst_caps_sanitize (GstCaps *caps);
+
G_END_DECLS
#endif
diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c
index f96da74ba3d0..a9ef7d1b2430 100644
--- a/src/gst/gstpipewiresrc.c
+++ b/src/gst/gstpipewiresrc.c
@@ -847,10 +847,14 @@ gst_pipewire_src_negotiate (GstBaseSrc * basesrc)
/* no peer, work with our own caps then */
possible_caps = g_steal_pointer (&thiscaps);
}
+
+ GST_DEBUG_OBJECT (basesrc, "have common caps: %" GST_PTR_FORMAT, possible_caps);
+ gst_caps_sanitize (possible_caps);
+
if (gst_caps_is_empty (possible_caps))
goto no_common_caps;
- GST_DEBUG_OBJECT (basesrc, "have common caps: %" GST_PTR_FORMAT, possible_caps);
+ GST_DEBUG_OBJECT (basesrc, "have common caps (sanitized): %" GST_PTR_FORMAT, possible_caps);
if (pw_stream_get_state(pwsrc->stream, NULL) == PW_STREAM_STATE_STREAMING) {
g_autoptr (GstCaps) current_caps = NULL;