[libcamera-devel] [PATCH v2 14/27] gst: utils: Add StreamConfiguration helpers

Nicolas Dufresne nicolas.dufresne at collabora.com
Thu Feb 27 21:03:54 CET 2020


This add helpers to deal with the conversion from StreamConfiguration
to caps and vis-versa. This is needed to implement caps negotiation.

Signed-off-by: Nicolas Dufresne <nicolas.dufresne at collabora.com>
---
 src/gstreamer/gstlibcamera-utils.cpp | 64 ++++++++++++++++++++++++++++
 src/gstreamer/gstlibcamera-utils.h   |  3 ++
 2 files changed, 67 insertions(+)

diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
index dc129c3..231f3c5 100644
--- a/src/gstreamer/gstlibcamera-utils.cpp
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -40,6 +40,18 @@ drm_to_gst_format(guint drm_fourcc)
 	return GST_VIDEO_FORMAT_UNKNOWN;
 }
 
+static inline guint
+gst_format_to_drm(GstVideoFormat gst_format)
+{
+	if (gst_format == GST_VIDEO_FORMAT_ENCODED)
+		return DRM_FORMAT_INVALID;
+
+	for (const auto &item : format_map)
+		if (item.gst_format == gst_format)
+			return item.drm_fourcc;
+	return DRM_FORMAT_INVALID;
+}
+
 static GstStructure *
 bare_structure_from_fourcc(guint fourcc)
 {
@@ -96,3 +108,55 @@ gst_libcamera_stream_formats_to_caps(const StreamFormats &formats)
 
 	return caps;
 }
+
+GstCaps *
+gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg)
+{
+	GstCaps *caps = gst_caps_new_empty();
+	GstStructure *s = bare_structure_from_fourcc(stream_cfg.pixelFormat);
+
+	gst_structure_set(s,
+			  "width", G_TYPE_INT, stream_cfg.size.width,
+			  "height", G_TYPE_INT, stream_cfg.size.height,
+			  nullptr);
+	gst_caps_append_structure(caps, s);
+
+	return caps;
+}
+
+void
+gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
+					 GstCaps *caps)
+{
+	GstVideoFormat gst_format = drm_to_gst_format(stream_cfg.pixelFormat);
+
+	/* First fixate the caps using default configuration value */
+	g_assert(gst_caps_is_writable(caps));
+	caps = gst_caps_truncate(caps);
+	GstStructure *s = gst_caps_get_structure(caps, 0);
+
+	gst_structure_fixate_field_nearest_int(s, "width", stream_cfg.size.width);
+	gst_structure_fixate_field_nearest_int(s, "height", stream_cfg.size.height);
+
+	if (gst_structure_has_name(s, "video/x-raw")) {
+		const gchar *format = gst_video_format_to_string(gst_format);
+		gst_structure_fixate_field_string(s, "format", format);
+	}
+
+	/* Then configure the stream with the result. */
+	if (gst_structure_has_name(s, "video/x-raw")) {
+		const gchar *format = gst_structure_get_string(s, "format");
+		gst_format = gst_video_format_from_string(format);
+		stream_cfg.pixelFormat = gst_format_to_drm(gst_format);
+	} else if (gst_structure_has_name(s, "image/jpeg")) {
+		stream_cfg.pixelFormat = DRM_FORMAT_MJPEG;
+	} else {
+		g_critical("Unsupported media type: %s", gst_structure_get_name(s));
+	}
+
+	gint width, height;
+	gst_structure_get_int(s, "width", &width);
+	gst_structure_get_int(s, "height", &height);
+	stream_cfg.size.width = width;
+	stream_cfg.size.height = height;
+}
diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h
index 737ca63..51898a0 100644
--- a/src/gstreamer/gstlibcamera-utils.h
+++ b/src/gstreamer/gstlibcamera-utils.h
@@ -14,6 +14,9 @@
 #include <libcamera/stream.h>
 
 GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats);
+GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg);
+void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg,
+					      GstCaps *caps);
 
 /**
  * \class GLibLocker
-- 
2.24.1



More information about the libcamera-devel mailing list