From patchwork Mon Mar 23 09:02:05 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 26312 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 99221C32DE for ; Mon, 23 Mar 2026 09:22:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id EBC9862743; Mon, 23 Mar 2026 10:22:44 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="chrt7WLi"; dkim-atps=neutral Received: from mail-wm1-x334.google.com (mail-wm1-x334.google.com [IPv6:2a00:1450:4864:20::334]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D43162737 for ; Mon, 23 Mar 2026 10:22:42 +0100 (CET) Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-48558d6ef83so24267635e9.3 for ; Mon, 23 Mar 2026 02:22:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; t=1774257762; x=1774862562; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TEj1zmU+YqKtZdBJqgTz/7IaGGOHqNsvZLmX/9GK6A4=; b=chrt7WLiMZjSWMbkMykMal4Oyezd9TgfsutPIVlGhaty1RzWvhXHybvKuikD9wfx1v jEV8j6xZEpspJC/yjD07pekhQtfyeWhRhGfPCO3Zr2f0JInBeweelTE2gXbabF8fEETl GHz66ctb7dVRVmKRl7s9/YeGwKQu4FQ9u6MbhnIPBcKTprSMZphqyfkTXCflZJQoQ6R2 MHHVlVETw6YHVvIc4AuZgu5bhD0EOy0o0iEem0IX+OF9aac5Ula7C4dTGY/DFaEe8vwA d5R26w+RON5/TS770+8HSNUg85z6OxT1f4bpFCKh/xvH2i4158EMmeD/2QUB0EeO3nUk gs3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774257762; x=1774862562; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=TEj1zmU+YqKtZdBJqgTz/7IaGGOHqNsvZLmX/9GK6A4=; b=AZmnZjqaeeCKGBAsD8qP41L5IghvPGHyS6oHp5SIe9dt4z800M0zzCOTxFvUo44fdA Bl3wz9UvH7/QlvzUOMqxPFKgRFZwCUkI6YVzcfNvBzqVzW1mfBmvgJYYRs2uigZdF6VK KEZTJkjv7F3YC/9Sj2lP1dPbMmpeEm6NHX8AeWjKdyEttsqemlwepD/ZNwWjE1wsSGLS LPa2YudiqCeUAsdckX6Wc2mYhQjEpN4jeb24YiP6wyQuFLy4qH4Y8bHmOWFOhaOJ8CTL AGIhs5Pf1w+viTvAvyALUaYy1PZAg4V41gp+48W2Kvo3GFM25OYOLnkRc3mIJYXlVnVi ykZg== X-Gm-Message-State: AOJu0YwnHO4rD+J/K+IF1VzHAw49L6QnHnYXMmuKQfGu3vWSbpB9odnu kOIYgQKN1BURLZInmyDAONj6Qk0eKSZRTRMmNsOwgdEk7XlaVgfHK1eiLwiFGQLTrvA4aGSSK1v TgrJJ X-Gm-Gg: ATEYQzxHHREr5QWtd9DZko0uOx+xt1VAVSPFS9rloKFJ/rOQynC8fd3DJMOAdCsYBi8 vPayQ/yvJ7f+htenY5qAp7MielvOqYQf4pTnek+zSNyb0GAptavCES0iURNVFz+b1/TrlG8+DP6 hEut4XD69ni1CIysOJWREs1MyEWFXYGDIqRpLi0m5Xo9k/LD3OwR8lXCLPRREIyXbImIqOSt2iT nLR3vfN5MPE/eLskyPoLdoCp+wiEkZNnIoDhNEv7WD00lIV2WSe8TyNyGLB8bMb+/PQlPkdLGxL GL30iDeRclmVKMk5Gn4Bmyz5gY4906N0I5tHYfVe0wewBZXHripPaw+zuDO60ZnL4Y9lLPloFQe PusoeaNoQV42ZZmI5iXQeWpWNN6k+aJP74QYMDiZCbDtiIwjZcuxQ5m0M7cSkneGUKQB3nOnoFZ MMLRBKWTmj0rTgy9JpqS/lph3qkUd0stivOPEooS5esv48o4iZRmORUtxi3Vh3ht25poSBfCuK5 FySKkpN+q7asOtOfuxQehskxaN98wvmGF3KPyQEaCnUAcUXo704 X-Received: by 2002:a05:600c:8b83:b0:486:fa9c:185 with SMTP id 5b1f17b1804b1-486fee2ffd5mr148455995e9.31.1774257761549; Mon, 23 Mar 2026 02:22:41 -0700 (PDT) Received: from davidp-pi5.pitowers.org ([2a00:1098:3142:1f:88ea:c658:5b20:5e46]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48703e26408sm278310335e9.11.2026.03.23.02.22.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Mar 2026 02:22:41 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Cc: David Plowman Subject: [PATCH v1 1/1] gstreamer: Add sensor-config property Date: Mon, 23 Mar 2026 09:02:05 +0000 Message-ID: <20260323092237.3103-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260323092237.3103-1-david.plowman@raspberrypi.com> References: <20260323092237.3103-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The sensor-config property may optionally be specified to give the outputSize and bitDepth of the SensorConfiguration that is applied to the camera configuration. For example, use libcamerasrc sensor-config=2304x1296/10 to request the 10-bit 2304x1296 mode of a sensor. All three parameters, width, height and bit depth, must be present, or it will issue a warning and revert to automatic mode selection (as if there were no sensor-config at all). If a mode is requested that doesn't exist then camera configuration will fail and the pipeline won't start. Signed-off-by: David Plowman --- src/gstreamer/gstlibcamerasrc.cpp | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index a7241e9b..9eca65d1 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -141,6 +141,7 @@ struct _GstLibcameraSrc { GstTask *task; gchar *camera_name; + gchar *sensor_config; std::atomic pending_eos; @@ -152,6 +153,7 @@ struct _GstLibcameraSrc { enum { PROP_0, PROP_CAMERA_NAME, + PROP_SENSOR_CONFIG, PROP_LAST }; @@ -846,6 +848,23 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread, } g_assert(state->config_->size() == state->srcpads_.size()); + /* Apply optional sensor configuration. */ + if (self->sensor_config) { + unsigned int w = 0, h = 0, depth = 0; + if (std::sscanf(self->sensor_config, "%ux%u/%u", &w, &h, &depth) == 3 && w && h && depth) { + SensorConfiguration sensorCfg; + sensorCfg.outputSize = Size(w, h); + sensorCfg.bitDepth = depth; + state->config_->sensorConfig = sensorCfg; + } else { + GST_ELEMENT_WARNING(self, RESOURCE, SETTINGS, + ("Invalid sensor-config \"%s\", expected \"WIDTHxHEIGHT/DEPTH\"," + " ignoring", + self->sensor_config), + (nullptr)); + } + } + if (!gst_libcamera_src_negotiate(self)) { state->initControls_.clear(); GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED); @@ -934,6 +953,10 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id, g_free(self->camera_name); self->camera_name = g_value_dup_string(value); break; + case PROP_SENSOR_CONFIG: + g_free(self->sensor_config); + self->sensor_config = g_value_dup_string(value); + break; default: if (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec)) G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -953,6 +976,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value, case PROP_CAMERA_NAME: g_value_set_string(value, self->camera_name); break; + case PROP_SENSOR_CONFIG: + g_value_set_string(value, self->sensor_config); + break; default: if (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec)) G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -1040,6 +1066,7 @@ gst_libcamera_src_finalize(GObject *object) g_clear_object(&self->task); g_mutex_clear(&self->state->lock_); g_free(self->camera_name); + g_free(self->sensor_config); delete self->state; return klass->finalize(object); @@ -1162,6 +1189,17 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass) | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec); + spec = g_param_spec_string("sensor-config", "Sensor Config", + "Desired sensor configuration as \"WIDTHxHEIGHT/BITDEPTH\"" + " (e.g. \"2304x1296/10\"). Leave unset to let the pipeline" + " negotiate the sensor mode automatically.", + nullptr, + (GParamFlags)(GST_PARAM_MUTABLE_READY + | G_PARAM_CONSTRUCT + | G_PARAM_READWRITE + | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(object_class, PROP_SENSOR_CONFIG, spec); + GstCameraControls::installProperties(object_class, PROP_LAST); }