gstreamer: Honor downstream format preferences in caps negotiation
diff mbox series

Message ID 20260721104411.2393571-1-elliot.chen@oss.nxp.com
State New
Headers show
Series
  • gstreamer: Honor downstream format preferences in caps negotiation
Related show

Commit Message

elliot.chen@oss.nxp.com July 21, 2026, 10:44 a.m. UTC
From: Elliot Chen <elliot.chen@nxp.com>

When negotiating caps in gst_libcamera_src_negotiate(), the previous
approach passed the libcamera stream format filter directly to
gst_pad_peer_query_caps(), which caused the negotiated format to be
selected based on the source format order rather than the preference
from downstream element.

Split the caps query into two steps: first query the full set of caps
supported by the downstream peer, then intersect with the libcamera
stream formats using GST_CAPS_INTERSECT_FIRST. This mode preserves the
order of the first operand (caps from downstream), so the preferred
format from downstream element is selected during fixation.

Signed-off-by: Elliot Chen <elliot.chen@nxp.com>
---
 src/gstreamer/gstlibcamerasrc.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Patch
diff mbox series

diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp
index 9061f9163..ba4c2d81d 100644
--- a/src/gstreamer/gstlibcamerasrc.cpp
+++ b/src/gstreamer/gstlibcamerasrc.cpp
@@ -598,8 +598,13 @@  gst_libcamera_src_negotiate(GstLibcameraSrc *self)
 		StreamConfiguration &stream_cfg = state->config_->at(i);
 
 		/* Retrieve the supported caps. */
+		g_autoptr(GstCaps) peer_caps = gst_pad_peer_query_caps(srcpad, NULL);
+		if (!peer_caps || gst_caps_is_empty(peer_caps))
+			return false;
+
 		g_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());
-		g_autoptr(GstCaps) caps = gst_pad_peer_query_caps(srcpad, filter);
+		/* Intersect with downstream's preferred format order first */
+		g_autoptr(GstCaps) caps = gst_caps_intersect_full(peer_caps, filter, GST_CAPS_INTERSECT_FIRST);
 		if (gst_caps_is_empty(caps))
 			return false;