[{"id":38376,"web_url":"https://patchwork.libcamera.org/comment/38376/","msgid":"<fb300f1b-1dcf-497f-83e4-3d38e13e36fd@ideasonboard.com>","date":"2026-03-23T09:51:54","subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"Hi\n\n2026. 03. 23. 10:02 keltezéssel, David Plowman írta:\n> The sensor-config property may optionally be specified to give the\n> outputSize and bitDepth of the SensorConfiguration that is applied to\n> the camera configuration. For example, use\n> \n> libcamerasrc sensor-config=2304x1296/10\n> \n> to request the 10-bit 2304x1296 mode of a sensor.\n> \n> All three parameters, width, height and bit depth, must be present, or\n> it will issue a warning and revert to automatic mode selection (as if\n> there were no sensor-config at all).\n> \n> If a mode is requested that doesn't exist then camera configuration\n> will fail and the pipeline won't start.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n\nI think you can add `Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/300`.\n\nAnd have you seen this previous attempt?\nhttps://patchwork.libcamera.org/cover/18458/\n\n\nRegards,\nBarnabás Pőcze\n\n\n>   src/gstreamer/gstlibcamerasrc.cpp | 38 +++++++++++++++++++++++++++++++\n>   1 file changed, 38 insertions(+)\n> \n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index a7241e9b..9eca65d1 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -141,6 +141,7 @@ struct _GstLibcameraSrc {\n>   \tGstTask *task;\n> \n>   \tgchar *camera_name;\n> +\tgchar *sensor_config;\n> \n>   \tstd::atomic<GstEvent *> pending_eos;\n> \n> @@ -152,6 +153,7 @@ struct _GstLibcameraSrc {\n>   enum {\n>   \tPROP_0,\n>   \tPROP_CAMERA_NAME,\n> +\tPROP_SENSOR_CONFIG,\n>   \tPROP_LAST\n>   };\n> \n> @@ -846,6 +848,23 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n>   \t}\n>   \tg_assert(state->config_->size() == state->srcpads_.size());\n> \n> +\t/* Apply optional sensor configuration. */\n> +\tif (self->sensor_config) {\n> +\t\tunsigned int w = 0, h = 0, depth = 0;\n> +\t\tif (std::sscanf(self->sensor_config, \"%ux%u/%u\", &w, &h, &depth) == 3 && w && h && depth) {\n> +\t\t\tSensorConfiguration sensorCfg;\n> +\t\t\tsensorCfg.outputSize = Size(w, h);\n> +\t\t\tsensorCfg.bitDepth = depth;\n> +\t\t\tstate->config_->sensorConfig = sensorCfg;\n> +\t\t} else {\n> +\t\t\tGST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> +\t\t\t\t\t    (\"Invalid sensor-config \\\"%s\\\", expected \\\"WIDTHxHEIGHT/DEPTH\\\",\"\n> +\t\t\t\t\t     \" ignoring\",\n> +\t\t\t\t\t     self->sensor_config),\n> +\t\t\t\t\t    (nullptr));\n> +\t\t}\n> +\t}\n> +\n>   \tif (!gst_libcamera_src_negotiate(self)) {\n>   \t\tstate->initControls_.clear();\n>   \t\tGST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED);\n> @@ -934,6 +953,10 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,\n>   \t\tg_free(self->camera_name);\n>   \t\tself->camera_name = g_value_dup_string(value);\n>   \t\tbreak;\n> +\tcase PROP_SENSOR_CONFIG:\n> +\t\tg_free(self->sensor_config);\n> +\t\tself->sensor_config = g_value_dup_string(value);\n> +\t\tbreak;\n>   \tdefault:\n>   \t\tif (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec))\n>   \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n> @@ -953,6 +976,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,\n>   \tcase PROP_CAMERA_NAME:\n>   \t\tg_value_set_string(value, self->camera_name);\n>   \t\tbreak;\n> +\tcase PROP_SENSOR_CONFIG:\n> +\t\tg_value_set_string(value, self->sensor_config);\n> +\t\tbreak;\n>   \tdefault:\n>   \t\tif (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec))\n>   \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n> @@ -1040,6 +1066,7 @@ gst_libcamera_src_finalize(GObject *object)\n>   \tg_clear_object(&self->task);\n>   \tg_mutex_clear(&self->state->lock_);\n>   \tg_free(self->camera_name);\n> +\tg_free(self->sensor_config);\n>   \tdelete self->state;\n> \n>   \treturn klass->finalize(object);\n> @@ -1162,6 +1189,17 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)\n>   \t\t\t\t\t\t\t     | G_PARAM_STATIC_STRINGS));\n>   \tg_object_class_install_property(object_class, PROP_CAMERA_NAME, spec);\n> \n> +\tspec = g_param_spec_string(\"sensor-config\", \"Sensor Config\",\n> +\t\t\t\t   \"Desired sensor configuration as \\\"WIDTHxHEIGHT/BITDEPTH\\\"\"\n> +\t\t\t\t   \" (e.g. \\\"2304x1296/10\\\"). Leave unset to let the pipeline\"\n> +\t\t\t\t   \" negotiate the sensor mode automatically.\",\n> +\t\t\t\t   nullptr,\n> +\t\t\t\t   (GParamFlags)(GST_PARAM_MUTABLE_READY\n> +\t\t\t\t\t\t | G_PARAM_CONSTRUCT\n> +\t\t\t\t\t\t | G_PARAM_READWRITE\n> +\t\t\t\t\t\t | G_PARAM_STATIC_STRINGS));\n> +\tg_object_class_install_property(object_class, PROP_SENSOR_CONFIG, spec);\n> +\n>   \tGstCameraControls::installProperties(object_class, PROP_LAST);\n>   }\n> \n> --\n> 2.47.3\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 31A63BE086\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Mar 2026 09:52:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9E85A62745;\n\tMon, 23 Mar 2026 10:51:59 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6029562737\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 10:51:58 +0100 (CET)","from [192.168.33.33] (185.221.143.129.nat.pool.zt.hu\n\t[185.221.143.129])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id E2B3B874;\n\tMon, 23 Mar 2026 10:50:41 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"TAvvzded\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1774259442;\n\tbh=/BmLoDpfsjgQLxx8aQ8qyzlHlyJkgGwX5Zh4lzwJwc0=;\n\th=Date:Subject:To:References:From:In-Reply-To:From;\n\tb=TAvvzdedb/0WHEsz8txZWFkx6DGTq9GEcpGCbWvj0OgPGqIGpTaN11FKB4I19Lxh9\n\tDF5RhJ4htG67QdWxLnygGlp9lQ2uUWK6/kdBLbBUDF38zhyNDGfYLLnzF//5IWH8eR\n\txr803jccSQn0N9pcOMFTg1eGnFBRZSFjdvT+g+3A=","Message-ID":"<fb300f1b-1dcf-497f-83e4-3d38e13e36fd@ideasonboard.com>","Date":"Mon, 23 Mar 2026 10:51:54 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","To":"David Plowman <david.plowman@raspberrypi.com>,\n\tlibcamera-devel@lists.libcamera.org","References":"<20260323092237.3103-1-david.plowman@raspberrypi.com>\n\t<6pEMMfN6H3NqES0y5PNZ3p3h2_s9q41jeNqfCOqeXRODi5wyvWQOFytqdk8fIoiM32I0ojGVjfaKAZHtWCqQqw==@protonmail.internalid>\n\t<20260323092237.3103-2-david.plowman@raspberrypi.com>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260323092237.3103-2-david.plowman@raspberrypi.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38377,"web_url":"https://patchwork.libcamera.org/comment/38377/","msgid":"<CAHW6GYLXwT1Qz-48tR=J8MTqBW5QzP5ob-X6hA8zoNbN+kdvtQ@mail.gmail.com>","date":"2026-03-23T10:07:45","subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi Barnabas\n\nOn Mon, 23 Mar 2026 at 09:51, Barnabás Pőcze\n<barnabas.pocze@ideasonboard.com> wrote:\n>\n> Hi\n>\n> 2026. 03. 23. 10:02 keltezéssel, David Plowman írta:\n> > The sensor-config property may optionally be specified to give the\n> > outputSize and bitDepth of the SensorConfiguration that is applied to\n> > the camera configuration. For example, use\n> >\n> > libcamerasrc sensor-config=2304x1296/10\n> >\n> > to request the 10-bit 2304x1296 mode of a sensor.\n> >\n> > All three parameters, width, height and bit depth, must be present, or\n> > it will issue a warning and revert to automatic mode selection (as if\n> > there were no sensor-config at all).\n> >\n> > If a mode is requested that doesn't exist then camera configuration\n> > will fail and the pipeline won't start.\n> >\n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n>\n> I think you can add `Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/300`.\n\nAh, I hadn't seen that. Yes, I think it does close that issue, so I\ncan add that.\n\n>\n> And have you seen this previous attempt?\n> https://patchwork.libcamera.org/cover/18458/\n\nThe discussion here is a little bit broader, and there's a wish, for\nexample, to be able to select a mode using framerate. That's more\ndifficult, of course, because we can't easily enumerate everything\nabout all the different modes. The intent here was simply to follow\nthe original SensorConfiguration design - you get the numbers exactly\nright, or it fails. For Pi users that's not so bad because it's easy\nenough to look up what you want (\"rpicam-hello --list-cameras\"), but\nmore generally there remains a wider problem here.\n\nThanks for the info!\nDavid\n\n>\n>\n> Regards,\n> Barnabás Pőcze\n>\n>\n> >   src/gstreamer/gstlibcamerasrc.cpp | 38 +++++++++++++++++++++++++++++++\n> >   1 file changed, 38 insertions(+)\n> >\n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index a7241e9b..9eca65d1 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -141,6 +141,7 @@ struct _GstLibcameraSrc {\n> >       GstTask *task;\n> >\n> >       gchar *camera_name;\n> > +     gchar *sensor_config;\n> >\n> >       std::atomic<GstEvent *> pending_eos;\n> >\n> > @@ -152,6 +153,7 @@ struct _GstLibcameraSrc {\n> >   enum {\n> >       PROP_0,\n> >       PROP_CAMERA_NAME,\n> > +     PROP_SENSOR_CONFIG,\n> >       PROP_LAST\n> >   };\n> >\n> > @@ -846,6 +848,23 @@ gst_libcamera_src_task_enter(GstTask *task, [[maybe_unused]] GThread *thread,\n> >       }\n> >       g_assert(state->config_->size() == state->srcpads_.size());\n> >\n> > +     /* Apply optional sensor configuration. */\n> > +     if (self->sensor_config) {\n> > +             unsigned int w = 0, h = 0, depth = 0;\n> > +             if (std::sscanf(self->sensor_config, \"%ux%u/%u\", &w, &h, &depth) == 3 && w && h && depth) {\n> > +                     SensorConfiguration sensorCfg;\n> > +                     sensorCfg.outputSize = Size(w, h);\n> > +                     sensorCfg.bitDepth = depth;\n> > +                     state->config_->sensorConfig = sensorCfg;\n> > +             } else {\n> > +                     GST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> > +                                         (\"Invalid sensor-config \\\"%s\\\", expected \\\"WIDTHxHEIGHT/DEPTH\\\",\"\n> > +                                          \" ignoring\",\n> > +                                          self->sensor_config),\n> > +                                         (nullptr));\n> > +             }\n> > +     }\n> > +\n> >       if (!gst_libcamera_src_negotiate(self)) {\n> >               state->initControls_.clear();\n> >               GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED);\n> > @@ -934,6 +953,10 @@ gst_libcamera_src_set_property(GObject *object, guint prop_id,\n> >               g_free(self->camera_name);\n> >               self->camera_name = g_value_dup_string(value);\n> >               break;\n> > +     case PROP_SENSOR_CONFIG:\n> > +             g_free(self->sensor_config);\n> > +             self->sensor_config = g_value_dup_string(value);\n> > +             break;\n> >       default:\n> >               if (!state->controls_.setProperty(prop_id - PROP_LAST, value, pspec))\n> >                       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n> > @@ -953,6 +976,9 @@ gst_libcamera_src_get_property(GObject *object, guint prop_id, GValue *value,\n> >       case PROP_CAMERA_NAME:\n> >               g_value_set_string(value, self->camera_name);\n> >               break;\n> > +     case PROP_SENSOR_CONFIG:\n> > +             g_value_set_string(value, self->sensor_config);\n> > +             break;\n> >       default:\n> >               if (!state->controls_.getProperty(prop_id - PROP_LAST, value, pspec))\n> >                       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);\n> > @@ -1040,6 +1066,7 @@ gst_libcamera_src_finalize(GObject *object)\n> >       g_clear_object(&self->task);\n> >       g_mutex_clear(&self->state->lock_);\n> >       g_free(self->camera_name);\n> > +     g_free(self->sensor_config);\n> >       delete self->state;\n> >\n> >       return klass->finalize(object);\n> > @@ -1162,6 +1189,17 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass *klass)\n> >                                                            | G_PARAM_STATIC_STRINGS));\n> >       g_object_class_install_property(object_class, PROP_CAMERA_NAME, spec);\n> >\n> > +     spec = g_param_spec_string(\"sensor-config\", \"Sensor Config\",\n> > +                                \"Desired sensor configuration as \\\"WIDTHxHEIGHT/BITDEPTH\\\"\"\n> > +                                \" (e.g. \\\"2304x1296/10\\\"). Leave unset to let the pipeline\"\n> > +                                \" negotiate the sensor mode automatically.\",\n> > +                                nullptr,\n> > +                                (GParamFlags)(GST_PARAM_MUTABLE_READY\n> > +                                              | G_PARAM_CONSTRUCT\n> > +                                              | G_PARAM_READWRITE\n> > +                                              | G_PARAM_STATIC_STRINGS));\n> > +     g_object_class_install_property(object_class, PROP_SENSOR_CONFIG, spec);\n> > +\n> >       GstCameraControls::installProperties(object_class, PROP_LAST);\n> >   }\n> >\n> > --\n> > 2.47.3\n> >\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 039A5BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Mar 2026 10:07:58 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 5252C62737;\n\tMon, 23 Mar 2026 11:07:58 +0100 (CET)","from mail-ej1-x632.google.com (mail-ej1-x632.google.com\n\t[IPv6:2a00:1450:4864:20::632])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D55B662737\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 11:07:56 +0100 (CET)","by mail-ej1-x632.google.com with SMTP id\n\ta640c23a62f3a-b97a9f4b4dcso12430966b.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 03:07:56 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"ZIGZc7o8\"; dkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1774260476; cv=none;\n\td=google.com; s=arc-20240605;\n\tb=eP1NL/w6eUXk/G5ak8NAz6aB7zU8qj35Lmeac5dThomhH+xYzdkq7kcmFoSVLuintX\n\tUnSWHpkOm0VgamxudiPQvxyQWQVAYpD9wsQNoF3NtuhEYTQCSuXYWyFJFCf87eyZvok5\n\t29dnwvVXxDj+w4H5d5UXU3TPl9eu798emnBdvAtZVQhH03MfFpAhGX4P993fguiaaZOf\n\tiS4xzJETBQMPEkDNvF7CQ3YYwBTatqR+X+o1yFtKNfKVwzABJziq2v8H15nkpgH8KWQ+\n\tn5c/fcOBIxgeDTgWnUYWG1PRGAQ1BYkvdToEMwxXnX143bmTd6KgI/Q+R6c7INMJDUiO\n\tyKMA==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=arc-20240605; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:dkim-signature;\n\tbh=S3SB/9/c/QN5QlGVAAALASd0WspUhk3P9s2RDeSkkEo=;\n\tfh=6eMZ9Peh5oKJMXVlU5do7GxLXGl0cSCd64pkjvWpyo4=;\n\tb=F6J0i4+vo1Zj5W+uGzAnKOKDilaFHF5/wT1tqDNtE8zCyok1t2hsNXGR6M2wIe4N6I\n\txtJQLnfokSb355BTPjg0anDv/5RxwfXtQ7ihL3Q0rZWC1CNP9nhcJZW1bQxMx5uc90aq\n\tUexClN0gceThfRRvcnashza2GUZ4Zb7ZLcblzEG4CUatZwkocUlFqPNntZqG0YIBPJLN\n\tyTCJmq9kUrmcbH4wZdz1WV3HK0JFT5ZGh2f9C4/vLKl9bzg0Iv2AKSsZORS+BAa0pWHr\n\t3s6xqSHrC9Rj1kIaa7esynkOMqEF7ZSthpe7SoJBec+BBsXJuN1lhRomjoiv9C3qbpp/\n\t9LDg==; darn=lists.libcamera.org","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1774260476; x=1774865276;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=S3SB/9/c/QN5QlGVAAALASd0WspUhk3P9s2RDeSkkEo=;\n\tb=ZIGZc7o8K9fgXOHHNQdtEugNGjmScqv4k9d/du+nocwXEdq4azxUImZ/7QqHWvUacp\n\tLGYefhmZu7gU3oR37BIQobAj125Lx5HSWLUTivtW3o55lvfLrL0lTsia8pK9acQZxDk0\n\tvhXyAMJewMi8ZbN/Zwg1d58QIPlH56zoeIW0LwPSK0jSXpXJ2cIjOL5i8ycxjLWW4dqS\n\tqeEOg3r81Gj4b7b0PzyijOr0gtEibzHtd1H/uYDD6cxiep9TIullVy5Csyx1QSHMuaz8\n\tv0z1DVjrhWzrjt0p53FLV63Vj9o1SM9I7Q/xYgTg3AjwMXqeWy67lsuZb6ADVGmgUYem\n\t5joA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1774260476; x=1774865276;\n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=S3SB/9/c/QN5QlGVAAALASd0WspUhk3P9s2RDeSkkEo=;\n\tb=sK0DwdkbTMI3k1OjYVTv9zVZgxV0rMsMRfd0emX2NeLdOW32CfDyRIs/kk9M07bZFo\n\tgZblwWfUtDU3yqacHY9UpVzGHlfGP1EskW15VYZJOwkYYHk4XwrblmIjRglxHL6lj0mM\n\tIumLc5tjza7dP84Czxet6TlKvNV99op9DZLKDten6ZL3ssWbYoSfHNmwuhi3XjhzieoS\n\tM2cH4BLlabF2FovAPHhcIoNiUpHfavzztjamsXEmB40f3EUgmJIScZhjug00cPmMsUUb\n\tMEW9UZ7K9h6Co7GMBXp5VNP4HlgIXlhjVcIzhCvXPHZKaASTzgCTycGIC2Ezze+VNd3z\n\t7KnQ==","X-Gm-Message-State":"AOJu0Yy+hLY8zNpgkdFwV+EDL2C67d5ehKyXXOLkmKf1vP5jjdAfCMzJ\n\tE9H21qKlX7dC668ZyF1EhB7/Jsnwk4HIMSdmhRi+jn+Ld8qMYTRT/bPOwAdM+P08qiJqea7foNt\n\tIo544f2fV9pzCcvrotyfIbd2qKZCh3BO6HkdvIO0R8deYlyXAi6F9","X-Gm-Gg":"ATEYQzx1Vuo/CdAhcqkNo787KYsXCQgBfvw1qmuoA6kj82sy3A3xwFHrqFJO0TXM7ZN\n\tA8NE9nBv8VPm3rhmVykRzbQWTso1mTJlUwHf04qlvs1wHvXmuLdZg4ZBQpbWm+BSQe72kEwOPRH\n\tJXe9Knqj4WXOlHsneM0SedVVxpA7lLkYXok94BlHQOVHMsGN6P1opQA1yqxp/V0kuiiQVkbT5tu\n\tD5hwyjQdjfRtaCZGZMtbxPyGp6IjdbLtfulX6w3noJ7XhFbw86xp/v4KFMN16jFOgHRok2RrBW5\n\t/qTwxYlyPnigWNQxHEmG7ALouIibLDwkjCY1n2+xV8Z9evroOft2RsjLO94LzEYSsz/p6XU7P7d\n\tDuEf0OELZm0Dp83ZYqdeIrBNU","X-Received":"by 2002:a17:907:8b89:b0:b98:2df5:9bd6 with SMTP id\n\ta640c23a62f3a-b982f21b8e2mr780871866b.7.1774260476180;\n\tMon, 23 Mar 2026 03:07:56 -0700 (PDT)","MIME-Version":"1.0","References":"<20260323092237.3103-1-david.plowman@raspberrypi.com>\n\t<6pEMMfN6H3NqES0y5PNZ3p3h2_s9q41jeNqfCOqeXRODi5wyvWQOFytqdk8fIoiM32I0ojGVjfaKAZHtWCqQqw==@protonmail.internalid>\n\t<20260323092237.3103-2-david.plowman@raspberrypi.com>\n\t<fb300f1b-1dcf-497f-83e4-3d38e13e36fd@ideasonboard.com>","In-Reply-To":"<fb300f1b-1dcf-497f-83e4-3d38e13e36fd@ideasonboard.com>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Mon, 23 Mar 2026 10:07:45 +0000","X-Gm-Features":"AQROBzBJGworElg1jx69QT22Ps9DqbEHRTTSD33TflyCGbKJX8p0FSKMSIRsSPc","Message-ID":"<CAHW6GYLXwT1Qz-48tR=J8MTqBW5QzP5ob-X6hA8zoNbN+kdvtQ@mail.gmail.com>","Subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38378,"web_url":"https://patchwork.libcamera.org/comment/38378/","msgid":"<4192bec443951ae7f474d5b5686be0ff1f9ca8dd.camel@ndufresne.ca>","date":"2026-03-23T12:56:33","subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Hi David,\n\nLe lundi 23 mars 2026 à 09:02 +0000, David Plowman a écrit :\n> The sensor-config property may optionally be specified to give the\n> outputSize and bitDepth of the SensorConfiguration that is applied to\n> the camera configuration. For example, use\n> \n> libcamerasrc sensor-config=2304x1296/10\n> \n> to request the 10-bit 2304x1296 mode of a sensor.\n> \n> All three parameters, width, height and bit depth, must be present, or\n> it will issue a warning and revert to automatic mode selection (as if\n> there were no sensor-config at all).\n\nAny reason to not allow setting the binning and the skipping too ? \n\n> \n> If a mode is requested that doesn't exist then camera configuration\n> will fail and the pipeline won't start.\n\nThat I'm ok with, as we discussed in past thread, the SensorConfig is not an\nequivalent of the mode enumeration hacks from the libcamera-app (and my previous\nattempts). Its a one time configuration for users that knows what they are\ndoing.\n\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  src/gstreamer/gstlibcamerasrc.cpp | 38 +++++++++++++++++++++++++++++++\n>  1 file changed, 38 insertions(+)\n> \n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp\n> b/src/gstreamer/gstlibcamerasrc.cpp\n> index a7241e9b..9eca65d1 100644\n> --- a/src/gstreamer/gstlibcamerasrc.cpp\n> +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> @@ -141,6 +141,7 @@ struct _GstLibcameraSrc {\n>  \tGstTask *task;\n>  \n>  \tgchar *camera_name;\n> +\tgchar *sensor_config;\n>  \n>  \tstd::atomic<GstEvent *> pending_eos;\n>  \n> @@ -152,6 +153,7 @@ struct _GstLibcameraSrc {\n>  enum {\n>  \tPROP_0,\n>  \tPROP_CAMERA_NAME,\n> +\tPROP_SENSOR_CONFIG,\n>  \tPROP_LAST\n>  };\n>  \n> @@ -846,6 +848,23 @@ gst_libcamera_src_task_enter(GstTask *task,\n> [[maybe_unused]] GThread *thread,\n>  \t}\n>  \tg_assert(state->config_->size() == state->srcpads_.size());\n>  \n> +\t/* Apply optional sensor configuration. */\n> +\tif (self->sensor_config) {\n> +\t\tunsigned int w = 0, h = 0, depth = 0;\n> +\t\tif (std::sscanf(self->sensor_config, \"%ux%u/%u\", &w, &h,\n> &depth) == 3 && w && h && depth) {\n> +\t\t\tSensorConfiguration sensorCfg;\n> +\t\t\tsensorCfg.outputSize = Size(w, h);\n> +\t\t\tsensorCfg.bitDepth = depth;\n> +\t\t\tstate->config_->sensorConfig = sensorCfg;\n> +\t\t} else {\n> +\t\t\tGST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> +\t\t\t\t\t    (\"Invalid sensor-config \\\"%s\\\",\n> expected \\\"WIDTHxHEIGHT/DEPTH\\\",\"\n> +\t\t\t\t\t     \" ignoring\",\n> +\t\t\t\t\t     self->sensor_config),\n> +\t\t\t\t\t    (nullptr));\n> +\t\t}\n> +\t}\n> +\n>  \tif (!gst_libcamera_src_negotiate(self)) {\n>  \t\tstate->initControls_.clear();\n>  \t\tGST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED);\n> @@ -934,6 +953,10 @@ gst_libcamera_src_set_property(GObject *object, guint\n> prop_id,\n>  \t\tg_free(self->camera_name);\n>  \t\tself->camera_name = g_value_dup_string(value);\n>  \t\tbreak;\n> +\tcase PROP_SENSOR_CONFIG:\n> +\t\tg_free(self->sensor_config);\n> +\t\tself->sensor_config = g_value_dup_string(value);\n> +\t\tbreak;\n>  \tdefault:\n>  \t\tif (!state->controls_.setProperty(prop_id - PROP_LAST, value,\n> pspec))\n>  \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id,\n> pspec);\n> @@ -953,6 +976,9 @@ gst_libcamera_src_get_property(GObject *object, guint\n> prop_id, GValue *value,\n>  \tcase PROP_CAMERA_NAME:\n>  \t\tg_value_set_string(value, self->camera_name);\n>  \t\tbreak;\n> +\tcase PROP_SENSOR_CONFIG:\n> +\t\tg_value_set_string(value, self->sensor_config);\n> +\t\tbreak;\n>  \tdefault:\n>  \t\tif (!state->controls_.getProperty(prop_id - PROP_LAST, value,\n> pspec))\n>  \t\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id,\n> pspec);\n> @@ -1040,6 +1066,7 @@ gst_libcamera_src_finalize(GObject *object)\n>  \tg_clear_object(&self->task);\n>  \tg_mutex_clear(&self->state->lock_);\n>  \tg_free(self->camera_name);\n> +\tg_free(self->sensor_config);\n>  \tdelete self->state;\n>  \n>  \treturn klass->finalize(object);\n> @@ -1162,6 +1189,17 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass\n> *klass)\n>  \t\t\t\t\t\t\t     |\n> G_PARAM_STATIC_STRINGS));\n>  \tg_object_class_install_property(object_class, PROP_CAMERA_NAME,\n> spec);\n>  \n> +\tspec = g_param_spec_string(\"sensor-config\", \"Sensor Config\",\n> +\t\t\t\t   \"Desired sensor configuration as\n> \\\"WIDTHxHEIGHT/BITDEPTH\\\"\"\n> +\t\t\t\t   \" (e.g. \\\"2304x1296/10\\\"). Leave unset to\n> let the pipeline\"\n> +\t\t\t\t   \" negotiate the sensor mode\n> automatically.\",\n> +\t\t\t\t   nullptr,\n> +\t\t\t\t   (GParamFlags)(GST_PARAM_MUTABLE_READY\n> +\t\t\t\t\t\t | G_PARAM_CONSTRUCT\n> +\t\t\t\t\t\t | G_PARAM_READWRITE\n> +\t\t\t\t\t\t | G_PARAM_STATIC_STRINGS));\n\nMy recommendation would be to stay away from string parsing. As it is today, if\na new configuration parameter is added (and it is already missing binning and \nskipping parameters), maintaining backward compatibility will be a nightmare.\n\nI'd like to suggest to use a GstStructure instead. This allow for key/value\npairs. You can make width/height/depth mandatory, while allowing for defaults\nvalues on binning and skipping and future additions. Defaults to any future\nadditions will be required anyway to maintain backward compatibility at\nlibcamera level.\n\nThe GstStructure have full serialization support, the only odd part is the\nstructure name, which we can either ignore or fixate. So typically:\n\n  sensor/config,width=X,height=Y,depth=Z\n\ngst_util_set_object_arg() (or when used inside gst-launch for testing) can be\nused to pass this as strings, but this is optional.\n\ncheers,\nNicolas\n\n> +\tg_object_class_install_property(object_class, PROP_SENSOR_CONFIG,\n> spec);\n> +\n>  \tGstCameraControls::installProperties(object_class, PROP_LAST);\n>  }\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7F4C4BD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Mar 2026 12:56:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7E0786275B;\n\tMon, 23 Mar 2026 13:56:39 +0100 (CET)","from mail-qv1-xf2a.google.com (mail-qv1-xf2a.google.com\n\t[IPv6:2607:f8b0:4864:20::f2a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0CAE362647\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 13:56:38 +0100 (CET)","by mail-qv1-xf2a.google.com with SMTP id\n\t6a1803df08f44-899a9f445cbso49690246d6.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 05:56:37 -0700 (PDT)","from ?IPv6:2606:6d00:15:e06b::5ac? ([2606:6d00:15:e06b::5ac])\n\tby smtp.gmail.com with ESMTPSA id\n\t6a1803df08f44-89c85335771sm83683266d6.30.2026.03.23.05.56.35\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 23 Mar 2026 05:56:35 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=ndufresne-ca.20230601.gappssmtp.com\n\theader.i=@ndufresne-ca.20230601.gappssmtp.com\n\theader.b=\"p2TX+hbq\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20230601.gappssmtp.com; s=20230601; t=1774270597;\n\tx=1774875397; darn=lists.libcamera.org; \n\th=mime-version:user-agent:autocrypt:references:in-reply-to:date:to\n\t:from:subject:message-id:from:to:cc:subject:date:message-id:reply-to; \n\tbh=dv8Tj+Outy98zrA/et2zb2zrxXltjdhj398qUQy2PAo=;\n\tb=p2TX+hbqStwuSh7YXjkRD4XDzrCN+AoejcwbSHRrkA/Ru8IKWCsxBs8l2RSKh4j+pK\n\tC1cc2qDX7n8CC3CoWjI5usf2l1LvZmsTju5gOAREbs80LGpTntG6VPssRdmihADIU5VB\n\tQLeXK2izKDlkJh51kafMvXXfY3L9QDnCzqj3WK4RJz1wzVtu1gmB0nwEbAyqomFvs3VT\n\t5RWXr6GVfBOOQa8mvr9h8Tu/r0IHhNsC/A6EwqBekr9bWNVTf1SJKF9RfOLeWlPpLTRD\n\tZMNdMdrKQTMPaMWYL5VB6SB57eFYEe5dRMpslhJJcVZ6P/ZTwSiNBvyJaU9WiarVLgUg\n\tufqw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1774270597; x=1774875397;\n\th=mime-version:user-agent:autocrypt:references:in-reply-to:date:to\n\t:from:subject:message-id:x-gm-gg:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=dv8Tj+Outy98zrA/et2zb2zrxXltjdhj398qUQy2PAo=;\n\tb=egHc+gSYQ1mR4q28C+8/lxOj/th/jPZam1RWEb8s1biTgOMoGSnYRGIMWlES/vdkx0\n\tIMLmy6vKfJm9lEnHb8Bl8BAkKvu5/Aeh8z7KQ7MdAPbHOSniLP/wecZz3DgO/KiRJmen\n\tay63+ZhCAfKYhg5HM7B2U74vEFuaSwuc6vq5lmNfGxk9iPQDh06cIFcO+i9h7n1yU3Yf\n\tofAIlBGFCheZ7NSQVJ6hiJHnqp0mOZCr5YqS5rFSuJEwyixYsdQcYslWOWodho2lYHfE\n\tQOcbw2d7IV5JfzXG+QHhgnR09Xg8Ty07lt8F8Ddhfmxano6zEFRWMHOtStc/ki6KACwQ\n\tceWQ==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCV2dIJ4mVicoBKKHwlPC57UvjoqprtOYJuyfzRNFKUGQfITtAaaQ0Zg5Ve24DQA9/p835DK8tX8z5vQaeydXuw=@lists.libcamera.org","X-Gm-Message-State":"AOJu0Yyjq1WIlgvasL3vhT8kdrElEWDPUcWP1KB4TpZroeaBMSWGqPYJ\n\tV0j/EVUjgpTokqKPFQPTVLDlLNV08ABIdhqERB4vudOwslYQATtpaIQWhO7SgF1U7jmAb6CnWmy\n\tnpcnj+60=","X-Gm-Gg":"ATEYQzzc6u2a1QshvNxuokLimmK/fRGog+7kBV7Mnc9PAQTxXD1qmVP8shAgzZftfdz\n\tcX+GmfwO1KQ6PlV6iOOfu+fuWQH+WZbIRyQ7+id+b2JrTbdXbzV0rm1l1kub8eTL7PkRtikMl8t\n\tFFDzmv3Jvuql/Uk7BOtdOGm9EIytRA9PNV6/KHcBGn1FHEMXWrizuYDyFwn/tB7f6sx7akYdvCa\n\tzK8cKKXg6iEwOOBHELSUeb4Va9Q5lbGqaSFEaytgsrHZt9g8oW+IrTYMOIf06J9AQjBDmuKBy8B\n\t0NVj0Aij/qETlX3xqCcDcl5OoiF4TRdjUufYhTnADt3wQveAbK53rq+I0SBHj6awCFwbGQ0QL6Q\n\tbr4gxSJyoT/dckAyVoYtDAUwvUso1mY+SkH0Kbgql/gw976R7UrLyi1oANkk5tss9J/wABzRL2X\n\twNPz82L0eMisxkFRXsyyU+dTxK2DZT","X-Received":"by 2002:a05:6214:2dc9:b0:89a:1321:2ac1 with SMTP id\n\t6a1803df08f44-89c85a57d57mr181418816d6.34.1774270596238; \n\tMon, 23 Mar 2026 05:56:36 -0700 (PDT)","Message-ID":"<4192bec443951ae7f474d5b5686be0ff1f9ca8dd.camel@ndufresne.ca>","Subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","From":"Nicolas Dufresne <nicolas@ndufresne.ca>","To":"David Plowman <david.plowman@raspberrypi.com>, \n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 23 Mar 2026 08:56:33 -0400","In-Reply-To":"<20260323092237.3103-2-david.plowman@raspberrypi.com>","References":"<20260323092237.3103-1-david.plowman@raspberrypi.com>\n\t<20260323092237.3103-2-david.plowman@raspberrypi.com>","Autocrypt":"addr=nicolas@ndufresne.ca; prefer-encrypt=mutual;\n\tkeydata=mDMEaCN2ixYJKwYBBAHaRw8BAQdAM0EHepTful3JOIzcPv6ekHOenE1u0vDG1gdHFrChD\n\t/e0J05pY29sYXMgRHVmcmVzbmUgPG5pY29sYXNAbmR1ZnJlc25lLmNhPoicBBMWCgBEAhsDBQsJCA\n\tcCAiICBhUKCQgLAgQWAgMBAh4HAheABQkJZfd1FiEE7w1SgRXEw8IaBG8S2UGUUSlgcvQFAmibrjo\n\tCGQEACgkQ2UGUUSlgcvQlQwD/RjpU1SZYcKG6pnfnQ8ivgtTkGDRUJ8gP3fK7+XUjRNIA/iXfhXMN\n\tabIWxO2oCXKf3TdD7aQ4070KO6zSxIcxgNQFtDFOaWNvbGFzIER1ZnJlc25lIDxuaWNvbGFzLmR1Z\n\tnJlc25lQGNvbGxhYm9yYS5jb20+iJkEExYKAEECGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4\n\tAWIQTvDVKBFcTDwhoEbxLZQZRRKWBy9AUCaCyyxgUJCWX3dQAKCRDZQZRRKWBy9ARJAP96pFmLffZ\n\tsmBUpkyVBfFAf+zq6BJt769R0al3kHvUKdgD9G7KAHuioxD2v6SX7idpIazjzx8b8rfzwTWyOQWHC\n\tAAS0LU5pY29sYXMgRHVmcmVzbmUgPG5pY29sYXMuZHVmcmVzbmVAZ21haWwuY29tPoiZBBMWCgBBF\n\tiEE7w1SgRXEw8IaBG8S2UGUUSlgcvQFAmibrGYCGwMFCQll93UFCwkIBwICIgIGFQoJCAsCBBYCAw\n\tECHgcCF4AACgkQ2UGUUSlgcvRObgD/YnQjfi4+L8f4fI7p1pPMTwRTcaRdy6aqkKEmKsCArzQBAK8\n\tbRLv9QjuqsE6oQZra/RB4widZPvphs78H0P6NmpIJ","Content-Type":"multipart/signed; micalg=\"pgp-sha512\";\n\tprotocol=\"application/pgp-signature\";\n\tboundary=\"=-HTR4UBIF8uy5o180UaNY\"","User-Agent":"Evolution 3.58.3 (3.58.3-1.fc43) ","MIME-Version":"1.0","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38380,"web_url":"https://patchwork.libcamera.org/comment/38380/","msgid":"<CAHW6GY+V37zGPRKS4smnCd_Na-9FPP38gkUK0N94=RfX1nscDg@mail.gmail.com>","date":"2026-03-23T16:12:47","subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi Nicolas\n\nThanks for the comments!\n\nOn Mon, 23 Mar 2026 at 12:56, Nicolas Dufresne <nicolas@ndufresne.ca> wrote:\n>\n> Hi David,\n>\n> Le lundi 23 mars 2026 à 09:02 +0000, David Plowman a écrit :\n> > The sensor-config property may optionally be specified to give the\n> > outputSize and bitDepth of the SensorConfiguration that is applied to\n> > the camera configuration. For example, use\n> >\n> > libcamerasrc sensor-config=2304x1296/10\n> >\n> > to request the 10-bit 2304x1296 mode of a sensor.\n> >\n> > All three parameters, width, height and bit depth, must be present, or\n> > it will issue a warning and revert to automatic mode selection (as if\n> > there were no sensor-config at all).\n>\n> Any reason to not allow setting the binning and the skipping too ?\n\nI guess because they're not used and I'm a bit lazy! But I can add\nthem, and it sounds like it might be easier if I switch over to this\nGstStructure.\n\n>\n> >\n> > If a mode is requested that doesn't exist then camera configuration\n> > will fail and the pipeline won't start.\n>\n> That I'm ok with, as we discussed in past thread, the SensorConfig is not an\n> equivalent of the mode enumeration hacks from the libcamera-app (and my previous\n> attempts). Its a one time configuration for users that knows what they are\n> doing.\n>\n> >\n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n> >  src/gstreamer/gstlibcamerasrc.cpp | 38 +++++++++++++++++++++++++++++++\n> >  1 file changed, 38 insertions(+)\n> >\n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp\n> > b/src/gstreamer/gstlibcamerasrc.cpp\n> > index a7241e9b..9eca65d1 100644\n> > --- a/src/gstreamer/gstlibcamerasrc.cpp\n> > +++ b/src/gstreamer/gstlibcamerasrc.cpp\n> > @@ -141,6 +141,7 @@ struct _GstLibcameraSrc {\n> >       GstTask *task;\n> >\n> >       gchar *camera_name;\n> > +     gchar *sensor_config;\n> >\n> >       std::atomic<GstEvent *> pending_eos;\n> >\n> > @@ -152,6 +153,7 @@ struct _GstLibcameraSrc {\n> >  enum {\n> >       PROP_0,\n> >       PROP_CAMERA_NAME,\n> > +     PROP_SENSOR_CONFIG,\n> >       PROP_LAST\n> >  };\n> >\n> > @@ -846,6 +848,23 @@ gst_libcamera_src_task_enter(GstTask *task,\n> > [[maybe_unused]] GThread *thread,\n> >       }\n> >       g_assert(state->config_->size() == state->srcpads_.size());\n> >\n> > +     /* Apply optional sensor configuration. */\n> > +     if (self->sensor_config) {\n> > +             unsigned int w = 0, h = 0, depth = 0;\n> > +             if (std::sscanf(self->sensor_config, \"%ux%u/%u\", &w, &h,\n> > &depth) == 3 && w && h && depth) {\n> > +                     SensorConfiguration sensorCfg;\n> > +                     sensorCfg.outputSize = Size(w, h);\n> > +                     sensorCfg.bitDepth = depth;\n> > +                     state->config_->sensorConfig = sensorCfg;\n> > +             } else {\n> > +                     GST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> > +                                         (\"Invalid sensor-config \\\"%s\\\",\n> > expected \\\"WIDTHxHEIGHT/DEPTH\\\",\"\n> > +                                          \" ignoring\",\n> > +                                          self->sensor_config),\n> > +                                         (nullptr));\n> > +             }\n> > +     }\n> > +\n> >       if (!gst_libcamera_src_negotiate(self)) {\n> >               state->initControls_.clear();\n> >               GST_ELEMENT_FLOW_ERROR(self, GST_FLOW_NOT_NEGOTIATED);\n> > @@ -934,6 +953,10 @@ gst_libcamera_src_set_property(GObject *object, guint\n> > prop_id,\n> >               g_free(self->camera_name);\n> >               self->camera_name = g_value_dup_string(value);\n> >               break;\n> > +     case PROP_SENSOR_CONFIG:\n> > +             g_free(self->sensor_config);\n> > +             self->sensor_config = g_value_dup_string(value);\n> > +             break;\n> >       default:\n> >               if (!state->controls_.setProperty(prop_id - PROP_LAST, value,\n> > pspec))\n> >                       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id,\n> > pspec);\n> > @@ -953,6 +976,9 @@ gst_libcamera_src_get_property(GObject *object, guint\n> > prop_id, GValue *value,\n> >       case PROP_CAMERA_NAME:\n> >               g_value_set_string(value, self->camera_name);\n> >               break;\n> > +     case PROP_SENSOR_CONFIG:\n> > +             g_value_set_string(value, self->sensor_config);\n> > +             break;\n> >       default:\n> >               if (!state->controls_.getProperty(prop_id - PROP_LAST, value,\n> > pspec))\n> >                       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id,\n> > pspec);\n> > @@ -1040,6 +1066,7 @@ gst_libcamera_src_finalize(GObject *object)\n> >       g_clear_object(&self->task);\n> >       g_mutex_clear(&self->state->lock_);\n> >       g_free(self->camera_name);\n> > +     g_free(self->sensor_config);\n> >       delete self->state;\n> >\n> >       return klass->finalize(object);\n> > @@ -1162,6 +1189,17 @@ gst_libcamera_src_class_init(GstLibcameraSrcClass\n> > *klass)\n> >                                                            |\n> > G_PARAM_STATIC_STRINGS));\n> >       g_object_class_install_property(object_class, PROP_CAMERA_NAME,\n> > spec);\n> >\n> > +     spec = g_param_spec_string(\"sensor-config\", \"Sensor Config\",\n> > +                                \"Desired sensor configuration as\n> > \\\"WIDTHxHEIGHT/BITDEPTH\\\"\"\n> > +                                \" (e.g. \\\"2304x1296/10\\\"). Leave unset to\n> > let the pipeline\"\n> > +                                \" negotiate the sensor mode\n> > automatically.\",\n> > +                                nullptr,\n> > +                                (GParamFlags)(GST_PARAM_MUTABLE_READY\n> > +                                              | G_PARAM_CONSTRUCT\n> > +                                              | G_PARAM_READWRITE\n> > +                                              | G_PARAM_STATIC_STRINGS));\n>\n> My recommendation would be to stay away from string parsing. As it is today, if\n> a new configuration parameter is added (and it is already missing binning and\n> skipping parameters), maintaining backward compatibility will be a nightmare.\n>\n> I'd like to suggest to use a GstStructure instead. This allow for key/value\n> pairs. You can make width/height/depth mandatory, while allowing for defaults\n> values on binning and skipping and future additions. Defaults to any future\n> additions will be required anyway to maintain backward compatibility at\n> libcamera level.\n>\n> The GstStructure have full serialization support, the only odd part is the\n> structure name, which we can either ignore or fixate. So typically:\n>\n>   sensor/config,width=X,height=Y,depth=Z\n>\n> gst_util_set_object_arg() (or when used inside gst-launch for testing) can be\n> used to pass this as strings, but this is optional.\n\nOK, that sounds good. I'll look that up and post a v2.\n\nThanks!\nDavid\n\n>\n> cheers,\n> Nicolas\n>\n> > +     g_object_class_install_property(object_class, PROP_SENSOR_CONFIG,\n> > spec);\n> > +\n> >       GstCameraControls::installProperties(object_class, PROP_LAST);\n> >  }\n> >","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0F83ABD87C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Mar 2026 16:13:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 14F5162760;\n\tMon, 23 Mar 2026 17:13:01 +0100 (CET)","from mail-ej1-x636.google.com (mail-ej1-x636.google.com\n\t[IPv6:2a00:1450:4864:20::636])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 664EE62647\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 17:12:59 +0100 (CET)","by mail-ej1-x636.google.com with SMTP id\n\ta640c23a62f3a-b980b35534eso712932266b.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Mar 2026 09:12:59 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"Floh693A\"; dkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1774282379; cv=none;\n\td=google.com; s=arc-20240605;\n\tb=aPPfvxy+Klg1WaCVVaFeO8ZkblusQlYmkTrjm+7LJSXyId8bHq6F3A/AJUtbEHK2I8\n\tIqHb1q+3ji14KYv3E/pIVNUPmAfspj8XYr7QkZ9OdU+yhyIUBZktgJD4ZnWRL3yvZUDp\n\tDKfJgtT5sXNzZASy1P1uyWXIY85A29uj7EQNrMoWl7JzOyAGWbbPLheZEEUo8iTcgBMa\n\ttxt2gehtRn54DRRjb3IkqvToCYiLbCJV8WMsGslynbUZswP2QhVm0PS7CY+Glcr7exYv\n\tq8OCG7xDiwe1PRRHMiyrwnzznL2gYrLJG7+h/LRctz4i8lWuveNghWERIRs77CxC083I\n\tD9mQ==","ARC-Message-Signature":"i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com;\n\ts=arc-20240605; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:dkim-signature;\n\tbh=6C5SBSw2MFAvN735mKLHmaRmjJUYFv+Zdzvg2hWCNts=;\n\tfh=d8+zo8pV0/m/b60f8il+KyfgQD9k6syIaaxOgkmf2uI=;\n\tb=Qu7Eo2aGjUZ++fz/5CUf7BoGyLinR3AJ1eCIpACOgTcUN9xZkHRn/2Y/jALmo2bqAM\n\tTZhnX6nI/j48QdwuOxDqLeAF0LaAhfIx7i1FQRDwaLOHLng7qPfKUT1AT+Ru6+wv9FjY\n\tV2HZDv/aXjH7VKEpZgeFeMsjJYQxgGVvfsuTY9X4E1EUlZeHluG9dc1o6qB8UMW6HZ5H\n\tphChR8DDDZObgSWhyPZsI3/Q3fUYSVKozFI7cVbxc4+iNuB47DHFX0SHsz3K3jKBOF45\n\tElVKlzbUjIKiBeCEkuEacDcXOweOPuGm44PecTyKnQIzepBofqLCjuwhC46PYx4kETLA\n\t6eCg==; darn=lists.libcamera.org","ARC-Authentication-Results":"i=1; mx.google.com; arc=none","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1774282379; x=1774887179;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=6C5SBSw2MFAvN735mKLHmaRmjJUYFv+Zdzvg2hWCNts=;\n\tb=Floh693AJZ6TQgzWFoyK1I1M8dfXLIfgB2gomI+UyxiagoFRiBcFGuficCN92Lv+sQ\n\tsDYl0IqmLVA1Lf8bTM81sXERwuVaCV1LRwj7gSx8JJwNcwsS2LonrzuoTZAdqg7qgvFB\n\tQo4d6N9eM7KG9CSepk3RO3g1KSeLK42QdxQ57xtZkxMMIAC4N9ytr0ClG5MQ4+i7uyLr\n\tBcUfZvjNKPJxE9h+eOWWdFfk1BihimTQdXza/TGvF5NjItFnIyYHYBWpCkxEu7hOMIsT\n\tzE8omwZTu7Nzac44L23u3w6PB+v2T15/S03U+NCNA0JEwlt/OnD/rjlHw4beeSIcyLas\n\tGGpA==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1774282379; x=1774887179;\n\th=content-transfer-encoding:cc:to:subject:message-id:date:from\n\t:in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=6C5SBSw2MFAvN735mKLHmaRmjJUYFv+Zdzvg2hWCNts=;\n\tb=dFuWvdwP4FclnqDmY/7rWabtnj9pGwgbg+2v9jvU9x1HrM+H68/65k2tC9RvRGWiCh\n\t8uGozAAL2jaL2a0lt1LW+Q1mfiwQ9ryH86JMaslc3IAhPMrJTgAFP0MuEl5qG9g3QBEp\n\tWuuQXYPY4aACZYtv9zeCWlNvLJBuwvHRQllXY3wCyqKHzea33TjB5P9Mf/mP0qA+4CHx\n\twyhBXzR3UXHYxrzN9jOTWsnYnqmyQMjplgwKOypg5b81fEPkbYmnd8DCzCu/+wDl8cyK\n\t4OqOEQoYp0q0tb4CyN4xTrQ8aXcnYdto9zo/7J+uKNm7UdFBGW6Vu5gcTnF17KXvzx8v\n\t/1wQ==","X-Gm-Message-State":"AOJu0Yyk1SiX2eGbS3f2w/LS8vO6nsqnpVqKwKSLJ1RmKLkeK46lJgsc\n\t0r0L+uzgVOxgsReRFT+T0WWuCl+8hFHB/rq6kTdsxFln980Unr+HicYkxldTqY3opPSiY4aXIQU\n\tcALJGxu+ZOTdq0if8h+u5xUaLIb1r4QCDM31DygNytQ==","X-Gm-Gg":"ATEYQzyBXpaa+AnDse8WcFKqqqKx1g5OevsUhtXZjBc1JnpaTGL/JvWBcHbs17a/UiP\n\tgdyj1r/keay/XK72LZJMf+5cM4gf2hHM/s+ZiOgRU4AnGiut8d+1l63RQs2ntsewnZwAreYPED+\n\txN2Z7/NV+Na1tti/xU+gvRl4pImYza9FNeuwCSKmpTPnaplQ2DgrTMa5aSH416DJNvEGt/noNs+\n\t5t51Kqvyj7JC+KBWJvxeLmogZ6ABMOeuq2P4fwb0zUmIDpZ1SHcw1XcZ8XYvy3WY0RFuO0Yxe9n\n\tEVjuxd7OXWHMqQk8FasAHwBobc2INbJ3qH+JHLkCEg24fpra0iVoqcXFoFJez7nrF07znOCMupO\n\tDHqzD7dS8sM1YwU/dhpkJAx5c","X-Received":"by 2002:a17:907:a01:b0:b98:5955:1341 with SMTP id\n\ta640c23a62f3a-b9886321acbmr12334666b.3.1774282378585; Mon, 23 Mar 2026\n\t09:12:58 -0700 (PDT)","MIME-Version":"1.0","References":"<20260323092237.3103-1-david.plowman@raspberrypi.com>\n\t<20260323092237.3103-2-david.plowman@raspberrypi.com>\n\t<4192bec443951ae7f474d5b5686be0ff1f9ca8dd.camel@ndufresne.ca>","In-Reply-To":"<4192bec443951ae7f474d5b5686be0ff1f9ca8dd.camel@ndufresne.ca>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Mon, 23 Mar 2026 16:12:47 +0000","X-Gm-Features":"AQROBzApTyo5eIUFrz93UjWeYVJCxz9LIIOxsk2UWgRfFuksWoUeIcZF7jiscMI","Message-ID":"<CAHW6GY+V37zGPRKS4smnCd_Na-9FPP38gkUK0N94=RfX1nscDg@mail.gmail.com>","Subject":"Re: [PATCH v1 1/1] gstreamer: Add sensor-config property","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]