@@ -302,13 +302,47 @@ gst_libcamera_stream_configuration_to_caps(const StreamConfiguration &stream_cfg
return caps;
}
+static void
+configure_colorspace_from_caps(StreamConfiguration &stream_cfg,
+ GstStructure *s)
+{
+ if (gst_structure_has_field(s, "colorimetry")) {
+ const gchar *colorimetry_str = gst_structure_get_string(s, "colorimetry");
+ GstVideoColorimetry colorimetry;
+
+ if (!gst_video_colorimetry_from_string(&colorimetry, colorimetry_str))
+ g_critical("Invalid colorimetry %s", colorimetry_str);
+
+ stream_cfg.colorSpace = colorspace_from_colorimetry(colorimetry);
+ /* Check if colorimetry had any identifiers which did not map */
+ if (colorimetry.primaries != GST_VIDEO_COLOR_PRIMARIES_UNKNOWN &&
+ stream_cfg.colorSpace == ColorSpace::Raw) {
+ GST_ERROR("One or more identifiers could not be mapped for %s colorimetry",
+ colorimetry_str);
+ stream_cfg.colorSpace = std::nullopt;
+ }
+ }
+}
+
+static gboolean
+check_colorspace(const ColorSpace colorSpace, const gchar *colorimetry_old)
+{
+ GstVideoColorimetry colorimetry = colorimetry_from_colorspace(colorSpace);
+ g_autofree gchar *colorimetry_new = gst_video_colorimetry_to_string(&colorimetry);
+ if (!g_strcmp0(colorimetry_old, colorimetry_new)) {
+ return true;
+ }
+ return false;
+}
+
void
-gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
+gst_libcamera_configure_stream_from_caps(CameraConfiguration &cam_cfg,
+ StreamConfiguration &stream_cfg,
GstCaps *caps)
{
GstVideoFormat gst_format = pixel_format_to_gst_format(stream_cfg.pixelFormat);
guint i;
- gint best_fixed = -1, best_in_range = -1;
+ gint best_fixed = -1, best_in_range = -1, colorimetry_index = -1;
GstStructure *s;
/*
@@ -354,10 +388,13 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
}
/* Prefer reliable fixed value over ranges */
- if (best_fixed >= 0)
+ if (best_fixed >= 0) {
s = gst_caps_get_structure(caps, best_fixed);
- else
+ colorimetry_index = best_fixed;
+ } else {
s = gst_caps_get_structure(caps, best_in_range);
+ colorimetry_index = best_in_range;
+ }
if (gst_structure_has_name(s, "video/x-raw")) {
const gchar *format = gst_video_format_to_string(gst_format);
@@ -380,6 +417,26 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
gst_structure_get_int(s, "height", &height);
stream_cfg.size.width = width;
stream_cfg.size.height = height;
+
+ /* Create new caps, copy the structure with best resolutions
+ * and normalize the caps.
+ */
+ GstCaps *ncaps = gst_caps_copy_nth(caps, colorimetry_index);
+ ncaps = gst_caps_normalize(ncaps);
+
+ /* Configure Colorimetry */
+ StreamConfiguration dup_stream_cfg = stream_cfg;
+ for (i = 0; i < gst_caps_get_size(ncaps); i++) {
+ GstStructure *ns = gst_caps_get_structure(ncaps, i);
+ configure_colorspace_from_caps(stream_cfg, ns);
+ g_autofree const gchar *colorimetry_old = gst_structure_get_string(ns, "colorimetry");
+ if (cam_cfg.validate() != CameraConfiguration::Invalid) {
+ if (check_colorspace(stream_cfg.colorSpace.value(), colorimetry_old))
+ break;
+ else
+ stream_cfg = dup_stream_cfg;
+ }
+ }
}
#if !GST_CHECK_VERSION(1, 17, 1)
@@ -8,6 +8,7 @@
#pragma once
+#include <libcamera/camera.h>
#include <libcamera/camera_manager.h>
#include <libcamera/stream.h>
@@ -16,7 +17,8 @@
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,
+void gst_libcamera_configure_stream_from_caps(libcamera::CameraConfiguration &cam_cfg,
+ libcamera::StreamConfiguration &stream_cfg,
GstCaps *caps);
#if !GST_CHECK_VERSION(1, 17, 1)
gboolean gst_task_resume(GstTask *task);
@@ -492,6 +492,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
for (gsize i = 0; i < state->srcpads_.size(); i++) {
GstPad *srcpad = state->srcpads_[i];
StreamConfiguration &stream_cfg = state->config_->at(i);
+ CameraConfiguration &cam_cfg = *(state->config_);
/* Retrieve the supported caps. */
g_autoptr(GstCaps) filter = gst_libcamera_stream_formats_to_caps(stream_cfg.formats());
@@ -503,7 +504,7 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,
/* Fixate caps and configure the stream. */
caps = gst_caps_make_writable(caps);
- gst_libcamera_configure_stream_from_caps(stream_cfg, caps);
+ gst_libcamera_configure_stream_from_caps(cam_cfg, stream_cfg, caps);
}
if (flow_ret != GST_FLOW_OK)