[{"id":38400,"web_url":"https://patchwork.libcamera.org/comment/38400/","msgid":"<e36dbf901fab43ded893d44bcf48aa25d1643291.camel@ndufresne.ca>","date":"2026-03-24T19:44:20","subject":"Re: [PATCH v2] gstreamer: Add sensor-config property","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Le mardi 24 mars 2026 à 08:53 +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=\"sensor/config,width=2304,height=1296,depth=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> As future-proofing, the SensorConfiguration's binning and increment\n> parameters may be specified, though libcamera currently ignores them.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/300\n> ---\n>  src/gstreamer/gstlibcamerasrc.cpp | 61 +++++++++++++++++++++++++++++++\n>  1 file changed, 61 insertions(+)\n> \n> diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> index a7241e9b..c7c183dd 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> +\tGstStructure *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,44 @@ 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\tgint w = 0, h = 0, depth = 0;\n> +\t\tif (!gst_structure_get_int(self->sensor_config, \"width\", &w) ||\n> +\t\t    !gst_structure_get_int(self->sensor_config, \"height\", &h) ||\n> +\t\t    !gst_structure_get_int(self->sensor_config, \"depth\", &depth) ||\n> +\t\t    w <= 0 || h <= 0 || depth <= 0) {\n> +\t\t\tGST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> +\t\t\t\t\t    (\"sensor-config requires non-zero width, height and depth\"\n> +\t\t\t\t\t     \" fields, ignoring\"),\n> +\t\t\t\t\t    (nullptr));\n> +\t\t} else {\n> +\t\t\tSensorConfiguration sensorCfg;\n> +\t\t\tsensorCfg.outputSize = Size(w, h);\n> +\t\t\tsensorCfg.bitDepth = depth;\n> +\n> +\t\t\t/* Optional binning (defaults to 1x1). */\n> +\t\t\tgint binX = 0, binY = 0;\n\nIt seems that you don't need to initialize these, leave it like this if the\ncompiler complains of course.\n\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"bin-x\", &binX) && binX > 0)\n> +\t\t\t\tsensorCfg.binning.binX = binX;\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"bin-y\", &binY) && binY > 0)\n> +\t\t\t\tsensorCfg.binning.binY = binY;\n> +\n> +\t\t\t/* Optional skipping (defaults to 1 for all increments). */\n> +\t\t\tgint xOddInc = 0, xEvenInc = 0, yOddInc = 0, yEvenInc = 0;\n\nSame.\n\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"x-odd-inc\", &xOddInc) && xOddInc > 0)\n> +\t\t\t\tsensorCfg.skipping.xOddInc = xOddInc;\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"x-even-inc\", &xEvenInc) && xEvenInc > 0)\n> +\t\t\t\tsensorCfg.skipping.xEvenInc = xEvenInc;\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"y-odd-inc\", &yOddInc) && yOddInc > 0)\n> +\t\t\t\tsensorCfg.skipping.yOddInc = yOddInc;\n> +\t\t\tif (gst_structure_get_int(self->sensor_config, \"y-even-inc\", &yEvenInc) && yEvenInc > 0)\n> +\t\t\t\tsensorCfg.skipping.yEvenInc = yEvenInc;\n> +\n> +\t\t\tstate->config_->sensorConfig = sensorCfg;\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 +974,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_clear_pointer(&self->sensor_config, gst_structure_free);\n> +\t\tself->sensor_config = gst_structure_copy((GstStructure *)g_value_get_boxed(value));\n\n\t\tself->sensor_config = (GstStructure *)g_value_dup_boxed(value);\n\n\nThat also fixes the assert when you try to set it back to NULL, since\ng_value_dup_boxed() will simply return NULL where gst_structure_copy() uses a\nfailsafe assert (still works, but looks ugly to see asserts).\n\n\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 +997,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_boxed(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 +1087,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_clear_pointer(&self->sensor_config, gst_structure_free);\n>  \tdelete self->state;\n>  \n>  \treturn klass->finalize(object);\n> @@ -1162,6 +1210,19 @@ 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_boxed(\"sensor-config\", \"Sensor Config\",\n> +\t\t\t\t  \"Desired sensor configuration as a GstStructure with mandatory \"\n> +\t\t\t\t  \"fields width, height and depth, and optional fields bin-x, bin-y, \"\n> +\t\t\t\t  \"x-odd-inc, x-even-inc, y-odd-inc, y-even-inc \"\n> +\t\t\t\t  \"(e.g. \\\"sensor/config,width=2304,height=1296,depth=10\\\"). \"\n> +\t\t\t\t  \"Leave unset to let the pipeline negotiate the sensor mode automatically.\",\n> +\t\t\t\t  GST_TYPE_STRUCTURE,\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\nWith these ajustements:\n\nReviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n\ncheers,\nNicolas","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 007DCBE086\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 24 Mar 2026 19:44:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 11AA562791;\n\tTue, 24 Mar 2026 20:44:26 +0100 (CET)","from mail-qk1-x742.google.com (mail-qk1-x742.google.com\n\t[IPv6:2607:f8b0:4864:20::742])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DFD3C62780\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 24 Mar 2026 20:44:24 +0100 (CET)","by mail-qk1-x742.google.com with SMTP id\n\taf79cd13be357-8cd8dbf4f2eso163722685a.2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 24 Mar 2026 12:44:24 -0700 (PDT)","from ?IPv6:2606:6d00:15:e06b::c41? ([2606:6d00:15:e06b::c41])\n\tby smtp.gmail.com with ESMTPSA id\n\taf79cd13be357-8cfc8f6791esm1135986685a.1.2026.03.24.12.44.22\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 24 Mar 2026 12:44:22 -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=\"PGppGd69\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20230601.gappssmtp.com; s=20230601; t=1774381464;\n\tx=1774986264; darn=lists.libcamera.org; \n\th=mime-version:user-agent:references:in-reply-to:date:to:from:subject\n\t:message-id:from:to:cc:subject:date:message-id:reply-to;\n\tbh=e3nkFB+V5NNZNwk2YKSMWTkHYdBQNkYjnLvll0ZBw/w=;\n\tb=PGppGd69vyj8IIUO5TD9vNaVqXmdS/qydat8J/WYdxNnwxgGSHOBN/qW7XDvQO+Ss5\n\tbP+5j+Z33nuXaZXxKqsSHXL/G+wif97K9uWgocnwj40j7BBfcz6EAsz0SSyz+q6PWzwq\n\tbIzOVnL3rbK1TOpIp1t+zpXTwDScpAiYimB3N3W8nWVbbAvtwUbFPuUT3tPLWMmQxSfb\n\tqOZvZ2zHQsSWMQm1q9EscMSGCChA3p74UptgRDUhZeUUdOkgZ7EhZfXIP03ghqZLzWJF\n\tNO5eTGVNDzLyV5pVez4VUOpKLePoqv7kWVYpAbkFZTe+XGXzichrxLfBus1+WEyg2YBk\n\t2Gwg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1774381464; x=1774986264;\n\th=mime-version:user-agent:references:in-reply-to:date:to:from:subject\n\t:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=e3nkFB+V5NNZNwk2YKSMWTkHYdBQNkYjnLvll0ZBw/w=;\n\tb=cABHcA2b8sRQCQHEAt+urwcuotKKMcOAn9f+yC6pT5klJD0Xa2Nh18JEIBuTrkwq9j\n\th9JhAfwJ2CN/2J2T+ckiLZ8gZNqZT8MvfUalIJMCoUSgwalNWAnlSkMhNUQMY0MHwvgB\n\tKUxc95XP2uBJG0Vbr4ZPTD8W/uEvmLjQzl3KfyRo4Cbcg8Er+dXj9vIy6o5dh807gL73\n\tCOZNz1ZSvxfA/qyP8lzfqT28JOH/BJOFtDQ46UNRfBNgECp7/V6u8PUWQLdJ7kzTWgy5\n\tpdNYYMgfsPqNHaucsnQuOlQb/Uwni6bw7E0Z8rVgJU/xrgtGmCbEwAHGKRVLY9S2D0/u\n\tbR2A==","X-Forwarded-Encrypted":"i=1;\n\tAJvYcCXNHuBZ75e1Gt0fL9NLdWwM6b2iePOiiplRTK+BaI7CIXVRlOttP69kILBo3RIi8zeR3AkrTOZ6Kf3IwauHob0=@lists.libcamera.org","X-Gm-Message-State":"AOJu0YzZFyqvi4HJn710mSfMV4nWx9RItMcsVuwCPlM5Wp/SOnc3ftSB\n\twH3YTlf2yj/6lbOsZEdd23VYDWH1C0IVYQbk5YzjP1iJKEdRFdyxiq0d5ndxEVAaV9U=","X-Gm-Gg":"ATEYQzxiY75M2D1ER90sz/WRiCZSAk6uZxj+qtu9jlwE4n6gmEuNSyDA2JmTjaDyjO7\n\tcVOqcc7/Y/6JXXEwyeV0yLlzHHda5hLDJ7QHh/wJuOtRX4olOrGFARv5kA7Iac4ajSmLnDRYrNy\n\tGRE4ZE1PlVici1BFrLKCY9fTLtTb7QWQPFJgm2r1yP4OzzXtgNwVhJ2vCIkkkBzGRkg0SlCw1dV\n\t7plSwMPcA/5QEekmF6dv7NtTbLNFq4aZr8IB0/rDWD1QhYxsSerbJpXiBHHBFavnza01m2oYlre\n\tqPOTgSXYr9QZt3hi0aomfbgEZ0Sjrsf7IT1NdCsdOePwiVx+XJXE565MNZl0cN++rOD9oPx0kbh\n\tL9a9sSo3EaqB//C7bOSVaaCAPFhB9HKoFhYVbTH1rfVRj9jiEmQTl7gPK5YmLjwFFYC55C1I3uT\n\t92bIYnRv/ECkg8t46YJb6VkmJB8zyX","X-Received":"by 2002:a05:620a:4802:b0:8cf:d62a:c807 with SMTP id\n\taf79cd13be357-8d000f1201dmr123496285a.17.1774381463454; \n\tTue, 24 Mar 2026 12:44:23 -0700 (PDT)","Message-ID":"<e36dbf901fab43ded893d44bcf48aa25d1643291.camel@ndufresne.ca>","Subject":"Re: [PATCH v2] 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":"Tue, 24 Mar 2026 15:44:20 -0400","In-Reply-To":"<20260324085612.14533-1-david.plowman@raspberrypi.com>","References":"<20260324085612.14533-1-david.plowman@raspberrypi.com>","Content-Type":"multipart/signed; micalg=\"pgp-sha512\";\n\tprotocol=\"application/pgp-signature\";\n\tboundary=\"=-cfAMqEfFjLVleUgJb5w/\"","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":38403,"web_url":"https://patchwork.libcamera.org/comment/38403/","msgid":"<CAHW6GY+hMFY-ccr39BU7NJHXfbRbOz08oOo-Urm7HKFOzcq66g@mail.gmail.com>","date":"2026-03-25T08:48:16","subject":"Re: [PATCH v2] 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\nOn Tue, 24 Mar 2026 at 19:44, Nicolas Dufresne <nicolas@ndufresne.ca> wrote:\n>\n> Le mardi 24 mars 2026 à 08:53 +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=\"sensor/config,width=2304,height=1296,depth=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> > As future-proofing, the SensorConfiguration's binning and increment\n> > parameters may be specified, though libcamera currently ignores them.\n> >\n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/300\n> > ---\n> >  src/gstreamer/gstlibcamerasrc.cpp | 61 +++++++++++++++++++++++++++++++\n> >  1 file changed, 61 insertions(+)\n> >\n> > diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp\n> > index a7241e9b..c7c183dd 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> > +     GstStructure *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,44 @@ 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> > +             gint w = 0, h = 0, depth = 0;\n> > +             if (!gst_structure_get_int(self->sensor_config, \"width\", &w) ||\n> > +                 !gst_structure_get_int(self->sensor_config, \"height\", &h) ||\n> > +                 !gst_structure_get_int(self->sensor_config, \"depth\", &depth) ||\n> > +                 w <= 0 || h <= 0 || depth <= 0) {\n> > +                     GST_ELEMENT_WARNING(self, RESOURCE, SETTINGS,\n> > +                                         (\"sensor-config requires non-zero width, height and depth\"\n> > +                                          \" fields, ignoring\"),\n> > +                                         (nullptr));\n> > +             } else {\n> > +                     SensorConfiguration sensorCfg;\n> > +                     sensorCfg.outputSize = Size(w, h);\n> > +                     sensorCfg.bitDepth = depth;\n> > +\n> > +                     /* Optional binning (defaults to 1x1). */\n> > +                     gint binX = 0, binY = 0;\n>\n> It seems that you don't need to initialize these, leave it like this if the\n> compiler complains of course.\n\nNo, the compiler seems happy so I'll make the change.\n\n>\n> > +                     if (gst_structure_get_int(self->sensor_config, \"bin-x\", &binX) && binX > 0)\n> > +                             sensorCfg.binning.binX = binX;\n> > +                     if (gst_structure_get_int(self->sensor_config, \"bin-y\", &binY) && binY > 0)\n> > +                             sensorCfg.binning.binY = binY;\n> > +\n> > +                     /* Optional skipping (defaults to 1 for all increments). */\n> > +                     gint xOddInc = 0, xEvenInc = 0, yOddInc = 0, yEvenInc = 0;\n>\n> Same.\n\nSame!\n\n>\n> > +                     if (gst_structure_get_int(self->sensor_config, \"x-odd-inc\", &xOddInc) && xOddInc > 0)\n> > +                             sensorCfg.skipping.xOddInc = xOddInc;\n> > +                     if (gst_structure_get_int(self->sensor_config, \"x-even-inc\", &xEvenInc) && xEvenInc > 0)\n> > +                             sensorCfg.skipping.xEvenInc = xEvenInc;\n> > +                     if (gst_structure_get_int(self->sensor_config, \"y-odd-inc\", &yOddInc) && yOddInc > 0)\n> > +                             sensorCfg.skipping.yOddInc = yOddInc;\n> > +                     if (gst_structure_get_int(self->sensor_config, \"y-even-inc\", &yEvenInc) && yEvenInc > 0)\n> > +                             sensorCfg.skipping.yEvenInc = yEvenInc;\n> > +\n> > +                     state->config_->sensorConfig = sensorCfg;\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 +974,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_clear_pointer(&self->sensor_config, gst_structure_free);\n> > +             self->sensor_config = gst_structure_copy((GstStructure *)g_value_get_boxed(value));\n>\n>                 self->sensor_config = (GstStructure *)g_value_dup_boxed(value);\n>\n>\n> That also fixes the assert when you try to set it back to NULL, since\n> g_value_dup_boxed() will simply return NULL where gst_structure_copy() uses a\n> failsafe assert (still works, but looks ugly to see asserts).\n\nGood to know. v3 incoming...\n\n>\n>\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 +997,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_boxed(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 +1087,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_clear_pointer(&self->sensor_config, gst_structure_free);\n> >       delete self->state;\n> >\n> >       return klass->finalize(object);\n> > @@ -1162,6 +1210,19 @@ 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_boxed(\"sensor-config\", \"Sensor Config\",\n> > +                               \"Desired sensor configuration as a GstStructure with mandatory \"\n> > +                               \"fields width, height and depth, and optional fields bin-x, bin-y, \"\n> > +                               \"x-odd-inc, x-even-inc, y-odd-inc, y-even-inc \"\n> > +                               \"(e.g. \\\"sensor/config,width=2304,height=1296,depth=10\\\"). \"\n> > +                               \"Leave unset to let the pipeline negotiate the sensor mode automatically.\",\n> > +                               GST_TYPE_STRUCTURE,\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> With these ajustements:\n>\n> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>\n\nThanks\nDavid\n\n>\n> cheers,\n> Nicolas","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 18AF8BE086\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 25 Mar 2026 08:48:30 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 45D05620FA;\n\tWed, 25 Mar 2026 09:48:29 +0100 (CET)","from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com\n\t[IPv6:2a00:1450:4864:20::62a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CD887620FA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 25 Mar 2026 09:48:27 +0100 (CET)","by mail-ej1-x62a.google.com with SMTP id\n\ta640c23a62f3a-b9382e59c0eso780408466b.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 25 Mar 2026 01:48:27 -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=\"kDcQ9404\"; dkim-atps=neutral","ARC-Seal":"i=1; a=rsa-sha256; t=1774428507; cv=none;\n\td=google.com; s=arc-20240605;\n\tb=XIHt1bE79SuoizmL3PLRdXhUJ1OVdO0z59wkrsKntkZntruRvgAnza2IAElRou7w4B\n\t2CUvcoPZFoFjYrvw/IszQrsLls9Ut7e4GI/V2Cp33XCSbhOsyIj9J7wCa8q4zv0II1zb\n\toeVC0TmCtsax0rmseIrgqr/aEsZXg7/9l0vY0ku57ZBSZI8LqsqElNWaUEdwSADZ381I\n\tFB5sA2KGeJVVP5hE2+gqw4gdHqtMa4di5el5rfdwKRYYpHvpBYUeiSI/A9V+khNqXvpK\n\tEqYrRUxbif0LojR+I4Iu9N3aReuz9+pTRjvQSSv4UXzQ/BqzlAYLAbLdIorc/FJeGU52\n\tFTiQ==","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=qODA/7JEkK2yY87gEujBn5oNDMyS4hUb/WBUIRe+iWs=;\n\tfh=d8+zo8pV0/m/b60f8il+KyfgQD9k6syIaaxOgkmf2uI=;\n\tb=ThrgB2emqb3Dtq2ZMH6iAM9agBWQeyuLPmTA8y42wx+xFHtQAO6aC3dkiH6TZwZyu6\n\tkroIykcrY2Qgkv6YLx0MHj3dxE/S+ZP6/McisDWi/P7+NlQkGAJkvneKNQj8MigqhYzF\n\trBM+e72AvGZkYWGVRPvkW67fO/vtUVVU66mJcOAdtoCBz6tV1yZQDNHJ4hmbefdymeyP\n\t/HIRaNOmXc51f5BNv36kfmV7iD/nirsZ2dBslAg7y6wv/R3N0nNwjo6Ug8ebsZOb/7Lz\n\tB4fw4ZY2Gfp0XOxzNisNmYCX7nMNcwqFeK2sCcgIdZSORw4upB1xPf8gZ0M9F1CdIycA\n\t0IYA==; 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=1774428507; x=1775033307;\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=qODA/7JEkK2yY87gEujBn5oNDMyS4hUb/WBUIRe+iWs=;\n\tb=kDcQ9404U/NUMVst6m6J0yi45hh66Mmb6nBqQaBbXeBqmFA3XEMuhURMDuFhZNMM+m\n\tInJ7QaZtXvOtjy9oSUqgUbRBMpD6V+EhjxVeps/TWbOnk2ZPEZj5wz9rADPE6vbbTaXU\n\tYbgj21GDXByTsswYO1dDjmtxnrXhUDfPd6gpM3OU04+SnJyTnT+dE9AaNwqgxp9B6IuY\n\tZHDrSuc+9qLEd5fmmw+tmJjyxXmtwPO0HgpKO+o/e6MbtNh7UEiHr0sTdL4A6nIwdHAb\n\teQ4C+NBbirQeccpuuMg8PbiEKToKSMdPrv59158gpp9r3uI2w9nmfroTzG9oWDtcSMMD\n\t35+w==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1774428507; x=1775033307;\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=qODA/7JEkK2yY87gEujBn5oNDMyS4hUb/WBUIRe+iWs=;\n\tb=F4xSsVG+GD2BQEZSDFt4oVAiqBOkiOrMX/Jt0hfAJysodlGshCI8loIiUvjumt7MXs\n\tui07XJyxFg/CHDKA3p28QiveAje5/WmB5j0Qf/id+2rNZjQ4PyB1vsMgun4zqKA1cNk3\n\tTXwMS9h5PJkKHCoBTqYFtZiMRQTI3p24erBRKfRKY+Fvpdg4tLUNns4+e1bC/hkPSmxC\n\tlhwxycv1YuStf8e4jAYkxmMG2C8W54ChwJm+DGn2kgXZHr0XUiibiLAQrB1xGz0TCi0W\n\t9IdxP9usMAg6iiXPDf/7Q6sBeMCjoUa6qicfoc7MTX6QJ2F+Dl6WDuVaOa9i5uKKZp7W\n\t07Cw==","X-Gm-Message-State":"AOJu0Yxk1xGK7yjB90JacNtxrO9K5p6pKedovy6cOsf3I1vbnm54rVzU\n\trMymEjQ4mNXHH+mbrap8r1H8U1vCGDuTfqNTXYKC3IaZ4UXHA5+FP7N7BGMBcHDX3FPH42ANl+X\n\tEQ+J/6D7DJeH0+t7xo3FIoLt3T4y9WD749P8VYFNFCQ==","X-Gm-Gg":"ATEYQzwUaoSB1HBVAI9Ea46CNegDA4ghhoXhBAviWRB8m/PTJtWiii21PYDxjcA6YQh\n\tWe4Ec0Jhsm/AOi4Pbo4iXi9Trv51FWYxa87odTaGDP3uEaLeVysr1wpeM1sO9TmK+SkvYpGB7C7\n\topfb+/Mx0aEIpl7NITQWUocStR4Fe1FwuhZNe2lLoepGrJKmc6eOBKfRC6dmmbiCd5F/iKKt67r\n\tEPwkHkdfISrkbKanHNjkmkNAHimi2uh7Zmf2VBKefrVSm2wn/rRSFV6HXdX8gCsoEwmSIdfYnYl\n\tY8FzGRk7Bh2HaKYAaU4yn3cDbYvnOU5fTHSPaZN/D0wlX72gX7N+hzY0YXnYUBEjezfHS/yrvot\n\tOs79HZOvfBt8WkQ0HRE+OhQWz","X-Received":"by 2002:a17:907:e101:b0:b98:8c46:fc44 with SMTP id\n\ta640c23a62f3a-b9a3f17005amr137624766b.2.1774428507132;\n\tWed, 25 Mar 2026 01:48:27 -0700 (PDT)","MIME-Version":"1.0","References":"<20260324085612.14533-1-david.plowman@raspberrypi.com>\n\t<e36dbf901fab43ded893d44bcf48aa25d1643291.camel@ndufresne.ca>","In-Reply-To":"<e36dbf901fab43ded893d44bcf48aa25d1643291.camel@ndufresne.ca>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Wed, 25 Mar 2026 08:48:16 +0000","X-Gm-Features":"AQROBzC0uPYNSsrHJml59PgEdhJ8xiyIdAVfZFWUg9UGVd_ipCTdPrEC7taa9x4","Message-ID":"<CAHW6GY+hMFY-ccr39BU7NJHXfbRbOz08oOo-Urm7HKFOzcq66g@mail.gmail.com>","Subject":"Re: [PATCH v2] 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>"}}]