[{"id":27890,"web_url":"https://patchwork.libcamera.org/comment/27890/","msgid":"<20230926213309.GG5854@pendragon.ideasonboard.com>","date":"2023-09-26T21:33:09","subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Thu, Sep 21, 2023 at 06:55:39PM +0200, Jacopo Mondi via libcamera-devel wrote:\n> Introduce SensorConfiguration in the libcamera API.\n> \n> The SensorConfiguration is part of the CameraConfiguration class\n> and allows applications to control the sensor settings.\n> \n> Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> Reviewed-by: Naushir Patuck <naush@raspberrypi.com>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  include/libcamera/camera.h |  27 +++++++\n>  src/libcamera/camera.cpp   | 144 +++++++++++++++++++++++++++++++++++++\n>  2 files changed, 171 insertions(+)\n> \n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 004bc89455f5..92a948e0f53b 100644\n> --- a/include/libcamera/camera.h\n> +++ b/include/libcamera/camera.h\n> @@ -9,6 +9,7 @@\n>  \n>  #include <initializer_list>\n>  #include <memory>\n> +#include <optional>\n>  #include <set>\n>  #include <stdint.h>\n>  #include <string>\n> @@ -19,6 +20,7 @@\n>  #include <libcamera/base/signal.h>\n>  \n>  #include <libcamera/controls.h>\n> +#include <libcamera/geometry.h>\n>  #include <libcamera/request.h>\n>  #include <libcamera/stream.h>\n>  #include <libcamera/transform.h>\n> @@ -30,6 +32,30 @@ class FrameBufferAllocator;\n>  class PipelineHandler;\n>  class Request;\n>  \n> +class SensorConfiguration\n> +{\n> +public:\n> +\tunsigned int bitDepth = 0;\n> +\n> +\tRectangle analogCrop;\n> +\n> +\tstruct {\n> +\t\tunsigned int binX = 1;\n> +\t\tunsigned int binY = 1;\n> +\t} binning;\n> +\n> +\tstruct {\n> +\t\tunsigned int xOddInc = 1;\n> +\t\tunsigned int xEvenInc = 1;\n> +\t\tunsigned int yOddInc = 1;\n> +\t\tunsigned int yEvenInc = 1;\n> +\t} skipping;\n> +\n> +\tSize outputSize;\n> +\n> +\tbool valid() const;\n\nWe call those functions isValid() in libcamera.\n\n> +};\n> +\n>  class CameraConfiguration\n>  {\n>  public:\n> @@ -66,6 +92,7 @@ public:\n>  \tbool empty() const;\n>  \tstd::size_t size() const;\n>  \n> +\tstd::optional<SensorConfiguration> sensorConfig;\n>  \tTransform transform;\n>  \n>  protected:\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 0eecee766f00..05a47444be89 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -97,6 +97,16 @@\n>   * implemented in the above order at the hardware level. The libcamera pipeline\n>   * handlers translate the pipeline model to the real hardware configuration.\n>   *\n> + * \\subsection camera-sensor-model Camera Sensor Model\n> + *\n> + * By default, libcamera configures the camera sensor automatically based on the\n> + * configuration of the streams. Applications may instead specify a manual\n> + * configuration for the camera sensor. This allows precise control of the frame\n> + * geometry and frame rate delivered by the sensor.\n> + *\n> + * More details about the camera sensor model implemented by libcamera are\n> + * available in the libcamera camera-sensor-model documentation page.\n> + *\n>   * \\subsection digital-zoom Digital Zoom\n>   *\n>   * Digital zoom is implemented as a combination of the cropping and scaling\n> @@ -111,6 +121,127 @@ namespace libcamera {\n>  \n>  LOG_DECLARE_CATEGORY(Camera)\n>  \n> +/**\n> + * \\class SensorConfiguration\n> + * \\brief Camera sensor configuration\n> + *\n> + * The SensorConfiguration class collects parameters to control the operations\n> + * of the camera sensor, accordingly to the abstract camera sensor model\n\ns/accordingly/according/\n\n> + * implemented by libcamera.\n> + *\n> + * \\todo Applications shall fully populate all fields of the\n> + * CameraConfiguration::sensorConfig class members before validating the\n> + * CameraConfiguration. If the SensorConfiguration is not fully populated, or if\n> + * any of its parameters cannot be applied to the sensor in use, the\n> + * CameraConfiguration validation process will fail and return\n> + * CameraConfiguration::Status::Invalid.\n\nI think we should implement this already, right away. To avoid delaying\nthis series I will submit a patch on top.\n\n> + *\n> + * Applications that populate the SensorConfiguration class members are\n> + * expected to be highly-specialized applications that know what sensor\n> + * they are operating with and what parameters are valid for the sensor in use.\n> + *\n> + * A detailed description of the abstract camera sensor model implemented by\n> + * libcamera and the description of its configuration parameters is available\n> + * in the libcamera documentation camera-sensor-model file.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::bitDepth\n> + * \\brief The sensor image format bit depth\n> + *\n> + * The number of bits (resolution) used to represent a pixel sample.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::analogCrop\n> + * \\brief The analog crop rectangle\n> + *\n> + * The selected portion of the active pixel array used to produce the image\n> + * frame.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::binning\n> + * \\brief Sensor binning configuration\n> + *\n> + * Refer to the camera-sensor-model documentation for an accurate description\n> + * of the binning operations. Disabled by default.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::binX\n> + * \\brief Horizontal binning factor\n> + *\n> + * The horizontal binning factor. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::binY\n> + * \\brief Vertical binning factor\n> + *\n> + * The vertical binning factor. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::skipping\n> + * \\brief The sensor skipping configuration\n> + *\n> + * Refer to the camera-sensor-model documentation for an accurate description\n> + * of the skipping operations.\n> + *\n> + * If no skipping is performed, all the structure fields should be\n> + * set to 1. Disabled by default.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::xOddInc\n> + * \\brief Horizontal increment for odd rows. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::xEvenInc\n> + * \\brief Horizontal increment for even rows. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::yOddInc\n> + * \\brief Vertical increment for odd columns. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::yEvenInc\n> + * \\brief Vertical increment for even columns. Default to 1.\n> + */\n> +\n> +/**\n> + * \\var SensorConfiguration::outputSize\n> + * \\brief The frame output (visible) size\n> + *\n> + * The size of the data frame as received by the host processor.\n> + */\n> +\n> +/**\n> + * \\brief Validate the sensor configuration\n\n* \\brief Check if the sensor configuration is valid\n\nto be consistent with the rest of the documentation.\n\n> + *\n> + * A sensor configuration is valid if it's fully populated.\n> + *\n> + * \\todo For now allow applications to populate the bitDepth and the outputSize\n> + * only as skipping and binnings factors are initialized to 1 and the analog\n> + * crop is ignored.\n\nI will fix this on top too.\n\n> + *\n> + * \\return True if the sensor configuration is valid, false otherwise.\n\ns/.$//\n\n> + */\n> +bool SensorConfiguration::valid() const\n> +{\n> +\tif (bitDepth && binning.binX && binning.binY &&\n> +\t    skipping.xOddInc && skipping.yOddInc &&\n> +\t    skipping.xEvenInc && skipping.yEvenInc &&\n> +\t    !outputSize.isNull())\n> +\t\treturn true;\n> +\n> +\treturn false;\n> +}\n> +\n>  /**\n>   * \\class CameraConfiguration\n>   * \\brief Hold configuration for streams of the camera\n> @@ -391,6 +522,19 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF\n>  \treturn status;\n>  }\n>  \n> +/**\n> + * \\var CameraConfiguration::sensorConfig\n> + * \\brief The camera sensor configuration\n> + *\n> + * The sensorConfig member allows control of the configuration of the camera\n> + * sensor. Refer to the camera-sensor-model documentation and to the\n> + * SensorConfiguration class documentation for details about the sensor\n> + * configuration process.\n> + *\n> + * The camera sensor configuration applies to all streams produced by a camera\n> + * from the same image source.\n\nI'd like to add\n\n * If sensorConfig is not set, the camera will configure the sensor\n * automatically based on the configuration of the streams.\n\nWe can rephrase the block as follows:\n\n * The sensorConfig member allows manual control of the configuration of the\n * camera sensor. By default, if sensorConfig is not set, the camera will\n * configure the sensor automatically based on the configuration of the streams.\n * Applications can override this by manually specifying the full sensor\n * configuration.\n *\n * Refer to the camera-sensor-model documentation and to the SensorConfiguration\n * class documentation for details about the sensor configuration process.\n *\n * The camera sensor configuration applies to all streams produced by a camera\n * from the same image source.\n\nIf those changes are fine with you, I can update the patch when pushing.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> + */\n> +\n>  /**\n>   * \\var CameraConfiguration::transform\n>   * \\brief User-specified transform to be applied to the image","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 251DAC326B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 26 Sep 2023 21:33:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 77C2662944;\n\tTue, 26 Sep 2023 23:33:00 +0200 (CEST)","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 45D3161E0E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 26 Sep 2023 23:32:59 +0200 (CEST)","from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi\n\t[213.243.189.158])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 13EE38C1;\n\tTue, 26 Sep 2023 23:31:17 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1695763980;\n\tbh=UTmhNE9WMs88+fkvlnBX/FZYvvYaOVmIXlOdNgHN6l0=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=qawVqfcRwQFZb5DBBxNbul0x2cuwqFAJ03AiSFovN4Su4HqUsrSJ86DgCVL89gkaz\n\tQCGv536Ptr+EgoEoBcNAhDnNhiuQxjoHgt99cIU0bmolQpE/TfQ7EJV1Z3+a3G+OBz\n\t0futuisOzyKs4HKAVvA4HJ1ehwSdwOr8yz/wZx+wmz9wgRhS7XkqwE9Qz4YAvTdfgQ\n\thNUKhtRsnW78jt+HGvLnvGCSYCCr3WeK+EGQ3+ekW7DmiI4RNBPXAF8EB3GOJA1wi8\n\tN6p2DxwGDOCSzAIMCxHZN+u2iz4f7C+7EA7nKW9m2WmHrcMGuhIfl7VIzMly01F8Pj\n\tYLuiUJnYkYoKw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1695763878;\n\tbh=UTmhNE9WMs88+fkvlnBX/FZYvvYaOVmIXlOdNgHN6l0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=khxgggM4Anqy6UODWuH0s1um3lCQ9XRVcsla7bmsw1GuCJWggZBjg1UEXgCBzVFBw\n\tnUcDwsfhRYXMHSE2lfoIdny9kfXDpVa7b59lRYBD/G/SwduScnuqstFG8BDL6p6rWy\n\t679RlOi6ewOSP2ABkHw7sJq47AlvybIk/EH9rO1U="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"khxgggM4\"; dkim-atps=neutral","Date":"Wed, 27 Sep 2023 00:33:09 +0300","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Message-ID":"<20230926213309.GG5854@pendragon.ideasonboard.com>","References":"<20230921165550.50956-1-jacopo.mondi@ideasonboard.com>\n\t<20230921165550.50956-3-jacopo.mondi@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20230921165550.50956-3-jacopo.mondi@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":27925,"web_url":"https://patchwork.libcamera.org/comment/27925/","msgid":"<3dc80c94168bbc839ffb878d4d5d63c2915e644a.camel@ndufresne.ca>","date":"2023-10-05T13:30:53","subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","submitter":{"id":30,"url":"https://patchwork.libcamera.org/api/people/30/","name":"Nicolas Dufresne","email":"nicolas@ndufresne.ca"},"content":"Hi,\n\nLe mercredi 27 septembre 2023 à 00:33 +0300, Laurent Pinchart via libcamera-\ndevel a écrit :\n> Hi Jacopo,\n> \n> Thank you for the patch.\n> \n> On Thu, Sep 21, 2023 at 06:55:39PM +0200, Jacopo Mondi via libcamera-devel wrote:\n> > Introduce SensorConfiguration in the libcamera API.\n> > \n> > The SensorConfiguration is part of the CameraConfiguration class\n> > and allows applications to control the sensor settings.\n> > \n> > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > Reviewed-by: Naushir Patuck <naush@raspberrypi.com>\n> > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > ---\n> >  include/libcamera/camera.h |  27 +++++++\n> >  src/libcamera/camera.cpp   | 144 +++++++++++++++++++++++++++++++++++++\n> >  2 files changed, 171 insertions(+)\n> > \n> > diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> > index 004bc89455f5..92a948e0f53b 100644\n> > --- a/include/libcamera/camera.h\n> > +++ b/include/libcamera/camera.h\n> > @@ -9,6 +9,7 @@\n> >  \n> >  #include <initializer_list>\n> >  #include <memory>\n> > +#include <optional>\n> >  #include <set>\n> >  #include <stdint.h>\n> >  #include <string>\n> > @@ -19,6 +20,7 @@\n> >  #include <libcamera/base/signal.h>\n> >  \n> >  #include <libcamera/controls.h>\n> > +#include <libcamera/geometry.h>\n> >  #include <libcamera/request.h>\n> >  #include <libcamera/stream.h>\n> >  #include <libcamera/transform.h>\n> > @@ -30,6 +32,30 @@ class FrameBufferAllocator;\n> >  class PipelineHandler;\n> >  class Request;\n> >  \n> > +class SensorConfiguration\n> > +{\n> > +public:\n> > +\tunsigned int bitDepth = 0;\n> > +\n> > +\tRectangle analogCrop;\n> > +\n> > +\tstruct {\n> > +\t\tunsigned int binX = 1;\n> > +\t\tunsigned int binY = 1;\n> > +\t} binning;\n> > +\n> > +\tstruct {\n> > +\t\tunsigned int xOddInc = 1;\n> > +\t\tunsigned int xEvenInc = 1;\n> > +\t\tunsigned int yOddInc = 1;\n> > +\t\tunsigned int yEvenInc = 1;\n> > +\t} skipping;\n> > +\n> > +\tSize outputSize;\n> > +\n> > +\tbool valid() const;\n> \n> We call those functions isValid() in libcamera.\n> \n> > +};\n> > +\n> >  class CameraConfiguration\n> >  {\n> >  public:\n> > @@ -66,6 +92,7 @@ public:\n> >  \tbool empty() const;\n> >  \tstd::size_t size() const;\n> >  \n> > +\tstd::optional<SensorConfiguration> sensorConfig;\n> >  \tTransform transform;\n> >  \n> >  protected:\n> > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> > index 0eecee766f00..05a47444be89 100644\n> > --- a/src/libcamera/camera.cpp\n> > +++ b/src/libcamera/camera.cpp\n> > @@ -97,6 +97,16 @@\n> >   * implemented in the above order at the hardware level. The libcamera pipeline\n> >   * handlers translate the pipeline model to the real hardware configuration.\n> >   *\n> > + * \\subsection camera-sensor-model Camera Sensor Model\n> > + *\n> > + * By default, libcamera configures the camera sensor automatically based on the\n> > + * configuration of the streams. Applications may instead specify a manual\n> > + * configuration for the camera sensor. This allows precise control of the frame\n> > + * geometry and frame rate delivered by the sensor.\n> > + *\n> > + * More details about the camera sensor model implemented by libcamera are\n> > + * available in the libcamera camera-sensor-model documentation page.\n> > + *\n> >   * \\subsection digital-zoom Digital Zoom\n> >   *\n> >   * Digital zoom is implemented as a combination of the cropping and scaling\n> > @@ -111,6 +121,127 @@ namespace libcamera {\n> >  \n> >  LOG_DECLARE_CATEGORY(Camera)\n> >  \n> > +/**\n> > + * \\class SensorConfiguration\n> > + * \\brief Camera sensor configuration\n> > + *\n> > + * The SensorConfiguration class collects parameters to control the operations\n> > + * of the camera sensor, accordingly to the abstract camera sensor model\n> \n> s/accordingly/according/\n> \n> > + * implemented by libcamera.\n> > + *\n> > + * \\todo Applications shall fully populate all fields of the\n> > + * CameraConfiguration::sensorConfig class members before validating the\n> > + * CameraConfiguration. If the SensorConfiguration is not fully populated, or if\n> > + * any of its parameters cannot be applied to the sensor in use, the\n> > + * CameraConfiguration validation process will fail and return\n> > + * CameraConfiguration::Status::Invalid.\n> \n> I think we should implement this already, right away. To avoid delaying\n> this series I will submit a patch on top.\n> \n> > + *\n> > + * Applications that populate the SensorConfiguration class members are\n> > + * expected to be highly-specialized applications that know what sensor\n> > + * they are operating with and what parameters are valid for the sensor in use.\n> > + *\n> > + * A detailed description of the abstract camera sensor model implemented by\n> > + * libcamera and the description of its configuration parameters is available\n> > + * in the libcamera documentation camera-sensor-model file.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::bitDepth\n> > + * \\brief The sensor image format bit depth\n> > + *\n> > + * The number of bits (resolution) used to represent a pixel sample.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::analogCrop\n> > + * \\brief The analog crop rectangle\n> > + *\n> > + * The selected portion of the active pixel array used to produce the image\n> > + * frame.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::binning\n> > + * \\brief Sensor binning configuration\n> > + *\n> > + * Refer to the camera-sensor-model documentation for an accurate description\n> > + * of the binning operations. Disabled by default.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::binX\n> > + * \\brief Horizontal binning factor\n> > + *\n> > + * The horizontal binning factor. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::binY\n> > + * \\brief Vertical binning factor\n> > + *\n> > + * The vertical binning factor. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::skipping\n> > + * \\brief The sensor skipping configuration\n> > + *\n> > + * Refer to the camera-sensor-model documentation for an accurate description\n> > + * of the skipping operations.\n> > + *\n> > + * If no skipping is performed, all the structure fields should be\n> > + * set to 1. Disabled by default.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::xOddInc\n> > + * \\brief Horizontal increment for odd rows. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::xEvenInc\n> > + * \\brief Horizontal increment for even rows. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::yOddInc\n> > + * \\brief Vertical increment for odd columns. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::yEvenInc\n> > + * \\brief Vertical increment for even columns. Default to 1.\n> > + */\n> > +\n> > +/**\n> > + * \\var SensorConfiguration::outputSize\n> > + * \\brief The frame output (visible) size\n> > + *\n> > + * The size of the data frame as received by the host processor.\n> > + */\n> > +\n> > +/**\n> > + * \\brief Validate the sensor configuration\n> \n> * \\brief Check if the sensor configuration is valid\n> \n> to be consistent with the rest of the documentation.\n> \n> > + *\n> > + * A sensor configuration is valid if it's fully populated.\n> > + *\n> > + * \\todo For now allow applications to populate the bitDepth and the outputSize\n> > + * only as skipping and binnings factors are initialized to 1 and the analog\n> > + * crop is ignored.\n> \n> I will fix this on top too.\n> \n> > + *\n> > + * \\return True if the sensor configuration is valid, false otherwise.\n> \n> s/.$//\n> \n> > + */\n> > +bool SensorConfiguration::valid() const\n> > +{\n> > +\tif (bitDepth && binning.binX && binning.binY &&\n> > +\t    skipping.xOddInc && skipping.yOddInc &&\n> > +\t    skipping.xEvenInc && skipping.yEvenInc &&\n> > +\t    !outputSize.isNull())\n> > +\t\treturn true;\n> > +\n> > +\treturn false;\n> > +}\n> > +\n> >  /**\n> >   * \\class CameraConfiguration\n> >   * \\brief Hold configuration for streams of the camera\n> > @@ -391,6 +522,19 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF\n> >  \treturn status;\n> >  }\n> >  \n> > +/**\n> > + * \\var CameraConfiguration::sensorConfig\n> > + * \\brief The camera sensor configuration\n> > + *\n> > + * The sensorConfig member allows control of the configuration of the camera\n> > + * sensor. Refer to the camera-sensor-model documentation and to the\n> > + * SensorConfiguration class documentation for details about the sensor\n> > + * configuration process.\n> > + *\n> > + * The camera sensor configuration applies to all streams produced by a camera\n> > + * from the same image source.\n> \n> I'd like to add\n> \n>  * If sensorConfig is not set, the camera will configure the sensor\n>  * automatically based on the configuration of the streams.\n> \n> We can rephrase the block as follows:\n> \n>  * The sensorConfig member allows manual control of the configuration of the\n>  * camera sensor. By default, if sensorConfig is not set, the camera will\n>  * configure the sensor automatically based on the configuration of the streams.\n>  * Applications can override this by manually specifying the full sensor\n>  * configuration.\n>  *\n>  * Refer to the camera-sensor-model documentation and to the SensorConfiguration\n>  * class documentation for details about the sensor configuration process.\n>  *\n>  * The camera sensor configuration applies to all streams produced by a camera\n>  * from the same image source.\n> \n> If those changes are fine with you, I can update the patch when pushing.\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nDid my first read of this, with considering the libcamera-app and gstreamer RFC\nfor sensor configuration. I think in order to actually solve someone problem, we\nneed a mechanism to retrieve the IPA chosen configuration after validation with\nautomatic configuration.\n\nThis implementation only focus on hardware aware software, so does not really\naddress any publicly discussed use cases. My general advise if you want to make\nnew API that are clearly useful, is to take one of the integration you control\nand demonstrate its usability. Just adding configuration is agreed valid, but is\nit usable by anyone using libcamera in real ?\n\nNicolas\n\n> \n> > + */\n> > +\n> >  /**\n> >   * \\var CameraConfiguration::transform\n> >   * \\brief User-specified transform to be applied to the image\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 4CA0CBD1F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  5 Oct 2023 13:30:59 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7C70F62963;\n\tThu,  5 Oct 2023 15:30:58 +0200 (CEST)","from mail-qt1-x832.google.com (mail-qt1-x832.google.com\n\t[IPv6:2607:f8b0:4864:20::832])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C905A61DE0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  5 Oct 2023 15:30:55 +0200 (CEST)","by mail-qt1-x832.google.com with SMTP id\n\td75a77b69052e-4181f8d82b9so5763961cf.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 05 Oct 2023 06:30:55 -0700 (PDT)","from nicolas-tpx395.localdomain ([2606:6d00:10:2a5::7a9])\n\tby smtp.gmail.com with ESMTPSA id\n\tfe5-20020a05622a4d4500b004166ab2e509sm468735qtb.92.2023.10.05.06.30.53\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 05 Oct 2023 06:30:53 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1696512658;\n\tbh=rh3NM8AP+2k1sp6IEuCqzSCoSLu4RNWQ/s7hcsCkz78=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=MWv1RyTHdEXs4MZAPX9p9RN6E3naWYXydR41IN7PHUEq6b40gY2ZRlM3/1vGW6Ci6\n\tRElz4nqpx9UeYxIM6WlIRKgQJBeT+yuyq1VOD6sse/Rvmsthr0glmw06/PIsSKFzk7\n\tdqIVIBGEiO8btyM9iOZchmhama27/ntBYvuzYmC79JiLs7jfu5kg1zTQEgnr5hixYk\n\tBoz9IHSy5ZYob3pBxuZ0H1e93iTDyjzHmp2CmbdCZqS+5mJJjJqb/QdegXbAPzoXpj\n\tapaqT1pBIOpaJToMxuHes8q2uIV9yRorQAh0jq/wP8PGcu0oxBxNFoUWt7YQCxds4M\n\t9wwL2t64Oj2sw==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ndufresne-ca.20230601.gappssmtp.com; s=20230601; t=1696512654;\n\tx=1697117454; darn=lists.libcamera.org; \n\th=mime-version:user-agent:content-transfer-encoding:references\n\t:in-reply-to:date:cc:to:from:subject:message-id:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=ya5pMvzYJcKNBmRYWTmC7qGnWt3Fl6nE6vucdOwj5zo=;\n\tb=WPsJ+8uztQ1gyNM/tEbkhlGDzN72YMs1A4wWT34w4rffuCYgqkW5MSYgOUga2fl/eL\n\tFvY/LCE2JPuvsd9TLKjpK/KW+bh2k3GSlLTayLEHvthvihldXs3mUAUz/7JrmOIqqTNA\n\tCb/uJ/uPo/GJD7LqW0qPqu1CDZoXV316HPXyDJIQP7JGDrRSrvYLtaRXygLvJFM6Z4MP\n\tZ5hDYxZAffsBvg217Th9Fn4g5hakYk5UxcElPCOgHsQOS2cUtEMHNA7cNF+cmBAQV7ic\n\tVtH2Lx/+u3YmgYja4c4tTIqJBcl+UiUPZGwhCRd5o3rO4LIzKh2KZH5dgFbz04j3iouL\n\tnOjg=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected)\n\theader.d=ndufresne-ca.20230601.gappssmtp.com\n\theader.i=@ndufresne-ca.20230601.gappssmtp.com header.b=\"WPsJ+8uz\"; \n\tdkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1696512654; x=1697117454;\n\th=mime-version:user-agent:content-transfer-encoding:references\n\t:in-reply-to:date:cc:to:from:subject:message-id:x-gm-message-state\n\t:from:to:cc:subject:date:message-id:reply-to;\n\tbh=ya5pMvzYJcKNBmRYWTmC7qGnWt3Fl6nE6vucdOwj5zo=;\n\tb=aA9BRNafPCZILC+DGVr3Uew9+bB2bAwkAnNXMLdHTSOcJRY09onAwR7WHlIC95NiMD\n\t2/GrSQgf69wZITO/RzxiVO3to5ZJFKUQ9+lJP+dLCAmrnHM6edwVTHUVQ1LHYb94ssnx\n\tZT1JMHuWMGWto2bPH9E4QhZysRhx0DHnNlfE33PPhOdDadZEH8iwA3dAO5+Ju6jPR7Ni\n\t7+PCp5ZZ2aP0uqAeh04d2iQ1/dRhNzLD45sRAnAqPJxWgIl8xX4G9LPhB/UrNMbWqjEU\n\tocSbRtfcOkdbI6q6mBf4HC3QFodIWE0qcnMcjXy/S9PZLYAPgu1bGjsiAQvfzk2yMCU5\n\t2lbg==","X-Gm-Message-State":"AOJu0Yz514zNhWQ4anbh1XBSFQWSFoIpNXxuoK94Jlv2Yf416ukSleWF\n\toRhVy3jr6PyaDsatgAgib2aRvmfmYQoBMymrSw0=","X-Google-Smtp-Source":"AGHT+IFDJnjaQ6IscdrPsiIANg7E1aMY3UnuubU4zCmnmmpOKYq2zsyW7Jv2VlG+XQxJLnSzfKCHow==","X-Received":"by 2002:a05:622a:81:b0:40a:fc6a:e87b with SMTP id\n\to1-20020a05622a008100b0040afc6ae87bmr5755242qtw.22.1696512654278; \n\tThu, 05 Oct 2023 06:30:54 -0700 (PDT)","Message-ID":"<3dc80c94168bbc839ffb878d4d5d63c2915e644a.camel@ndufresne.ca>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Jacopo Mondi\n\t<jacopo.mondi@ideasonboard.com>","Date":"Thu, 05 Oct 2023 09:30:53 -0400","In-Reply-To":"<20230926213309.GG5854@pendragon.ideasonboard.com>","References":"<20230921165550.50956-1-jacopo.mondi@ideasonboard.com>\n\t<20230921165550.50956-3-jacopo.mondi@ideasonboard.com>\n\t<20230926213309.GG5854@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Content-Transfer-Encoding":"quoted-printable","User-Agent":"Evolution 3.48.4 (3.48.4-1.fc38) ","MIME-Version":"1.0","Subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","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>","From":"Nicolas Dufresne via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":27990,"web_url":"https://patchwork.libcamera.org/comment/27990/","msgid":"<20231018222744.GQ1512@pendragon.ideasonboard.com>","date":"2023-10-18T22:27:44","subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Nicolas,\n\nOn Thu, Oct 05, 2023 at 09:30:53AM -0400, Nicolas Dufresne wrote:\n> Le mercredi 27 septembre 2023 à 00:33 +0300, Laurent Pinchart via libcamera-devel a écrit :\n> > On Thu, Sep 21, 2023 at 06:55:39PM +0200, Jacopo Mondi via libcamera-devel wrote:\n> > > Introduce SensorConfiguration in the libcamera API.\n> > > \n> > > The SensorConfiguration is part of the CameraConfiguration class\n> > > and allows applications to control the sensor settings.\n> > > \n> > > Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n> > > Reviewed-by: Naushir Patuck <naush@raspberrypi.com>\n> > > Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> > > ---\n> > >  include/libcamera/camera.h |  27 +++++++\n> > >  src/libcamera/camera.cpp   | 144 +++++++++++++++++++++++++++++++++++++\n> > >  2 files changed, 171 insertions(+)\n> > > \n> > > diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> > > index 004bc89455f5..92a948e0f53b 100644\n> > > --- a/include/libcamera/camera.h\n> > > +++ b/include/libcamera/camera.h\n> > > @@ -9,6 +9,7 @@\n> > >  \n> > >  #include <initializer_list>\n> > >  #include <memory>\n> > > +#include <optional>\n> > >  #include <set>\n> > >  #include <stdint.h>\n> > >  #include <string>\n> > > @@ -19,6 +20,7 @@\n> > >  #include <libcamera/base/signal.h>\n> > >  \n> > >  #include <libcamera/controls.h>\n> > > +#include <libcamera/geometry.h>\n> > >  #include <libcamera/request.h>\n> > >  #include <libcamera/stream.h>\n> > >  #include <libcamera/transform.h>\n> > > @@ -30,6 +32,30 @@ class FrameBufferAllocator;\n> > >  class PipelineHandler;\n> > >  class Request;\n> > >  \n> > > +class SensorConfiguration\n> > > +{\n> > > +public:\n> > > +\tunsigned int bitDepth = 0;\n> > > +\n> > > +\tRectangle analogCrop;\n> > > +\n> > > +\tstruct {\n> > > +\t\tunsigned int binX = 1;\n> > > +\t\tunsigned int binY = 1;\n> > > +\t} binning;\n> > > +\n> > > +\tstruct {\n> > > +\t\tunsigned int xOddInc = 1;\n> > > +\t\tunsigned int xEvenInc = 1;\n> > > +\t\tunsigned int yOddInc = 1;\n> > > +\t\tunsigned int yEvenInc = 1;\n> > > +\t} skipping;\n> > > +\n> > > +\tSize outputSize;\n> > > +\n> > > +\tbool valid() const;\n> > \n> > We call those functions isValid() in libcamera.\n> > \n> > > +};\n> > > +\n> > >  class CameraConfiguration\n> > >  {\n> > >  public:\n> > > @@ -66,6 +92,7 @@ public:\n> > >  \tbool empty() const;\n> > >  \tstd::size_t size() const;\n> > >  \n> > > +\tstd::optional<SensorConfiguration> sensorConfig;\n> > >  \tTransform transform;\n> > >  \n> > >  protected:\n> > > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> > > index 0eecee766f00..05a47444be89 100644\n> > > --- a/src/libcamera/camera.cpp\n> > > +++ b/src/libcamera/camera.cpp\n> > > @@ -97,6 +97,16 @@\n> > >   * implemented in the above order at the hardware level. The libcamera pipeline\n> > >   * handlers translate the pipeline model to the real hardware configuration.\n> > >   *\n> > > + * \\subsection camera-sensor-model Camera Sensor Model\n> > > + *\n> > > + * By default, libcamera configures the camera sensor automatically based on the\n> > > + * configuration of the streams. Applications may instead specify a manual\n> > > + * configuration for the camera sensor. This allows precise control of the frame\n> > > + * geometry and frame rate delivered by the sensor.\n> > > + *\n> > > + * More details about the camera sensor model implemented by libcamera are\n> > > + * available in the libcamera camera-sensor-model documentation page.\n> > > + *\n> > >   * \\subsection digital-zoom Digital Zoom\n> > >   *\n> > >   * Digital zoom is implemented as a combination of the cropping and scaling\n> > > @@ -111,6 +121,127 @@ namespace libcamera {\n> > >  \n> > >  LOG_DECLARE_CATEGORY(Camera)\n> > >  \n> > > +/**\n> > > + * \\class SensorConfiguration\n> > > + * \\brief Camera sensor configuration\n> > > + *\n> > > + * The SensorConfiguration class collects parameters to control the operations\n> > > + * of the camera sensor, accordingly to the abstract camera sensor model\n> > \n> > s/accordingly/according/\n> > \n> > > + * implemented by libcamera.\n> > > + *\n> > > + * \\todo Applications shall fully populate all fields of the\n> > > + * CameraConfiguration::sensorConfig class members before validating the\n> > > + * CameraConfiguration. If the SensorConfiguration is not fully populated, or if\n> > > + * any of its parameters cannot be applied to the sensor in use, the\n> > > + * CameraConfiguration validation process will fail and return\n> > > + * CameraConfiguration::Status::Invalid.\n> > \n> > I think we should implement this already, right away. To avoid delaying\n> > this series I will submit a patch on top.\n> > \n> > > + *\n> > > + * Applications that populate the SensorConfiguration class members are\n> > > + * expected to be highly-specialized applications that know what sensor\n> > > + * they are operating with and what parameters are valid for the sensor in use.\n> > > + *\n> > > + * A detailed description of the abstract camera sensor model implemented by\n> > > + * libcamera and the description of its configuration parameters is available\n> > > + * in the libcamera documentation camera-sensor-model file.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::bitDepth\n> > > + * \\brief The sensor image format bit depth\n> > > + *\n> > > + * The number of bits (resolution) used to represent a pixel sample.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::analogCrop\n> > > + * \\brief The analog crop rectangle\n> > > + *\n> > > + * The selected portion of the active pixel array used to produce the image\n> > > + * frame.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::binning\n> > > + * \\brief Sensor binning configuration\n> > > + *\n> > > + * Refer to the camera-sensor-model documentation for an accurate description\n> > > + * of the binning operations. Disabled by default.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::binX\n> > > + * \\brief Horizontal binning factor\n> > > + *\n> > > + * The horizontal binning factor. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::binY\n> > > + * \\brief Vertical binning factor\n> > > + *\n> > > + * The vertical binning factor. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::skipping\n> > > + * \\brief The sensor skipping configuration\n> > > + *\n> > > + * Refer to the camera-sensor-model documentation for an accurate description\n> > > + * of the skipping operations.\n> > > + *\n> > > + * If no skipping is performed, all the structure fields should be\n> > > + * set to 1. Disabled by default.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::xOddInc\n> > > + * \\brief Horizontal increment for odd rows. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::xEvenInc\n> > > + * \\brief Horizontal increment for even rows. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::yOddInc\n> > > + * \\brief Vertical increment for odd columns. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::yEvenInc\n> > > + * \\brief Vertical increment for even columns. Default to 1.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\var SensorConfiguration::outputSize\n> > > + * \\brief The frame output (visible) size\n> > > + *\n> > > + * The size of the data frame as received by the host processor.\n> > > + */\n> > > +\n> > > +/**\n> > > + * \\brief Validate the sensor configuration\n> > \n> > * \\brief Check if the sensor configuration is valid\n> > \n> > to be consistent with the rest of the documentation.\n> > \n> > > + *\n> > > + * A sensor configuration is valid if it's fully populated.\n> > > + *\n> > > + * \\todo For now allow applications to populate the bitDepth and the outputSize\n> > > + * only as skipping and binnings factors are initialized to 1 and the analog\n> > > + * crop is ignored.\n> > \n> > I will fix this on top too.\n> > \n> > > + *\n> > > + * \\return True if the sensor configuration is valid, false otherwise.\n> > \n> > s/.$//\n> > \n> > > + */\n> > > +bool SensorConfiguration::valid() const\n> > > +{\n> > > +\tif (bitDepth && binning.binX && binning.binY &&\n> > > +\t    skipping.xOddInc && skipping.yOddInc &&\n> > > +\t    skipping.xEvenInc && skipping.yEvenInc &&\n> > > +\t    !outputSize.isNull())\n> > > +\t\treturn true;\n> > > +\n> > > +\treturn false;\n> > > +}\n> > > +\n> > >  /**\n> > >   * \\class CameraConfiguration\n> > >   * \\brief Hold configuration for streams of the camera\n> > > @@ -391,6 +522,19 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF\n> > >  \treturn status;\n> > >  }\n> > >  \n> > > +/**\n> > > + * \\var CameraConfiguration::sensorConfig\n> > > + * \\brief The camera sensor configuration\n> > > + *\n> > > + * The sensorConfig member allows control of the configuration of the camera\n> > > + * sensor. Refer to the camera-sensor-model documentation and to the\n> > > + * SensorConfiguration class documentation for details about the sensor\n> > > + * configuration process.\n> > > + *\n> > > + * The camera sensor configuration applies to all streams produced by a camera\n> > > + * from the same image source.\n> > \n> > I'd like to add\n> > \n> >  * If sensorConfig is not set, the camera will configure the sensor\n> >  * automatically based on the configuration of the streams.\n> > \n> > We can rephrase the block as follows:\n> > \n> >  * The sensorConfig member allows manual control of the configuration of the\n> >  * camera sensor. By default, if sensorConfig is not set, the camera will\n> >  * configure the sensor automatically based on the configuration of the streams.\n> >  * Applications can override this by manually specifying the full sensor\n> >  * configuration.\n> >  *\n> >  * Refer to the camera-sensor-model documentation and to the SensorConfiguration\n> >  * class documentation for details about the sensor configuration process.\n> >  *\n> >  * The camera sensor configuration applies to all streams produced by a camera\n> >  * from the same image source.\n> > \n> > If those changes are fine with you, I can update the patch when pushing.\n> > \n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n> Did my first read of this, with considering the libcamera-app and gstreamer RFC\n> for sensor configuration. I think in order to actually solve someone problem, we\n> need a mechanism to retrieve the IPA chosen configuration after validation with\n> automatic configuration.\n> \n> This implementation only focus on hardware aware software, so does not really\n> address any publicly discussed use cases. My general advise if you want to make\n> new API that are clearly useful, is to take one of the integration you control\n> and demonstrate its usability. Just adding configuration is agreed valid, but is\n> it usable by anyone using libcamera in real ?\n\nI don't like this API much (I don't think this is a surprise to anyone,\nI've voiced that opinion already). I however think it's a step towards\nsolving the problem. We'll take further steps :-)\n\n> > > + */\n> > > +\n> > >  /**\n> > >   * \\var CameraConfiguration::transform\n> > >   * \\brief User-specified transform to be applied to the image","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 6E6A1BDCBD\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 Oct 2023 22:27:39 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B445B6296F;\n\tThu, 19 Oct 2023 00:27:38 +0200 (CEST)","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 A805D6295F\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 19 Oct 2023 00:27:37 +0200 (CEST)","from pendragon.ideasonboard.com (213-243-189-158.bb.dnainternet.fi\n\t[213.243.189.158])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D19C0291;\n\tThu, 19 Oct 2023 00:27:29 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1697668058;\n\tbh=D+Zdjc2sSOwheAY8kj2HZsuDK9SqiK4oYdZLu11Z1jk=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=3t2Pg0HWAKv+956aoUiLDf7BrcQqd19EOoejN4YRmRnjICHvR5bo6HkCxk6xd8Z//\n\t//EpywmOIaSm+CNk7CoRQi67oF5AQbyRuB2/S27RhgCgxpqp0He2+fBTgLFW0/meQD\n\t09Oh5qIwW04bJs8FCt4nUGjvcXScJU1+1RlUmDQpFvCg02PNIdqSWCWX6r+BNmG5G3\n\t9fuRyyB/wAf0W8EtFpiwqjEKDiTX7pzavNkp+Qhed/mhtdI1Z3B47FFjUrUGPtYm34\n\twbYFL66Iz97CB0V4gIOL04xrRYJhzg4+FICbslc8lsu4A7kSH3oP0346QCziTGncUv\n\tY/3lyEgooRbGA==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1697668050;\n\tbh=D+Zdjc2sSOwheAY8kj2HZsuDK9SqiK4oYdZLu11Z1jk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=LDuWMvusZSdntSodRB4ZHdy/zKofgur5R0L6b+0IB3WjftFR9AS9SoJiCiLmVZUyV\n\tXWukczDj9y2zZdIMcjZYem5jjU52DoRECNDmwF+6soC0bCzS6/iOqr+rJ0M9cfUpcc\n\t4mgUwTozJSYPhBL3OXFgqQP691/xus/++K5YaUvQ="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"LDuWMvus\"; dkim-atps=neutral","Date":"Thu, 19 Oct 2023 01:27:44 +0300","To":"Nicolas Dufresne <nicolas@ndufresne.ca>","Message-ID":"<20231018222744.GQ1512@pendragon.ideasonboard.com>","References":"<20230921165550.50956-1-jacopo.mondi@ideasonboard.com>\n\t<20230921165550.50956-3-jacopo.mondi@ideasonboard.com>\n\t<20230926213309.GG5854@pendragon.ideasonboard.com>\n\t<3dc80c94168bbc839ffb878d4d5d63c2915e644a.camel@ndufresne.ca>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<3dc80c94168bbc839ffb878d4d5d63c2915e644a.camel@ndufresne.ca>","Subject":"Re: [libcamera-devel] [PATCH v5 02/13] libcamera: camera: Introduce\n\tSensorConfiguration","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]