[{"id":27830,"web_url":"https://patchwork.libcamera.org/comment/27830/","msgid":"<20230921121512.GB19112@pendragon.ideasonboard.com>","date":"2023-09-21T12:15:12","subject":"Re: [libcamera-devel] [PATCH v4 02/12] 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 Sat, Sep 16, 2023 at 02:19:20PM +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 |  43 +++++++++\n>  src/libcamera/camera.cpp   | 183 +++++++++++++++++++++++++++++++++++++\n>  2 files changed, 226 insertions(+)\n> \n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 004bc89455f5..c4f9aa869489 100644\n> --- a/include/libcamera/camera.h\n> +++ b/include/libcamera/camera.h\n> @@ -19,6 +19,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 +31,47 @@ 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> +\t{\n> +\t\treturn validate() != Invalid;\n> +\t}\n> +\n> +\tbool populated() const\n> +\t{\n> +\t\treturn validate() == Populated;\n> +\t}\n> +\n> +private:\n> +\tenum Status {\n> +\t\tUnpopulated,\n> +\t\tPopulated,\n> +\t\tInvalid,\n> +\t};\n> +\n> +\tStatus validate() const;\n> +};\n> +\n>  class CameraConfiguration\n>  {\n>  public:\n> @@ -66,6 +108,7 @@ public:\n>  \tbool empty() const;\n>  \tstd::size_t size() const;\n>  \n> +\tSensorConfiguration sensorConfig;\n>  \tTransform transform;\n>  \n>  protected:\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 0eecee766f00..3d8098239a7f 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,166 @@ 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> + * 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> + * 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> + * \\enum SensorConfiguration::Status\n> + * \\brief The sensor configuration validation status\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> + * \\fn SensorConfiguration::valid() const\n> + * \\brief Validate the SensorConfiguration\n> + *\n> + * Validate the sensor configuration.\n> + *\n> + * \\todo A sensor configuration is valid (or well-formed) if it's either\n> + * completely un-populated or fully populated. For now allow applications to\n> + * populate the bitDepth and the outputSize only.\n> + *\n> + * \\return True if the SensorConfiguration is either fully populated or\n> + * un-populated, false otherwise\n> + */\n> +\n> +/**\n> + * \\fn SensorConfiguration::populated() const\n> + * \\brief Test if a SensorConfiguration is fully populated\n> + * \\return True if the SensorConfiguration is fully populated\n> + */\n> +\n> +/**\n> + * \\brief Validate the sensor configuration\n> + *\n> + * \\todo A sensor configuration is valid (or well-formed) if it's either\n> + * completely un-populated or fully populated. For now allow applications to\n> + * populate the bitDepth and the outputSize only.\n> + *\n> + * \\return The sensor configuration status\n> + * \\retval Unpopulated The sensor configuration is fully unpopulated\n> + * \\retval Populated The sensor configuration is fully populated\n> + * \\retval Invalid The sensor configuration is invalid (not fully populated\n> + * and not fully unpopulated)\n> + */\n> +SensorConfiguration::Status SensorConfiguration::validate() 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 Populated;\n> +\n> +\t/*\n> +\t * By default the binning and skipping factors are initialized to 1, but\n> +\t * a zero-initialized SensorConfiguration is considered unpopulated\n> +\t * as well.\n> +\t */\n> +\tif (!bitDepth &&\n> +\t    binning.binX <= 1 && binning.binY <= 1 &&\n> +\t    skipping.xOddInc <= 1 && skipping.yOddInc <= 1 &&\n> +\t    skipping.xEvenInc <= 1 && skipping.yEvenInc <= 1 &&\n> +\t    outputSize.isNull())\n> +\t\treturn Unpopulated;\n> +\n> +\treturn Invalid;\n> +}\n> +\n>  /**\n>   * \\class CameraConfiguration\n>   * \\brief Hold configuration for streams of the camera\n> @@ -391,6 +561,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 field allows control of the configuration of the camera\n\ns/field/member/\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\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> +\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 B5729BE080\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 21 Sep 2023 12:15:02 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6DAD962945;\n\tThu, 21 Sep 2023 14:15:02 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A65CC62931\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 21 Sep 2023 14:15:00 +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 343611257;\n\tThu, 21 Sep 2023 14:13:23 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1695298502;\n\tbh=HX1N5I7KHT/rak62pUF1CQplXKWIbk6JTNR5HW0wHlI=;\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=3JH1JKZKwmgv3g5MrM3ez27tt0GG3V5Mm8v1T2wF4jFQ8X7sZ6ethxLhtKqFfyKIH\n\tu2hP+9NeqH4kdvEUJEg6oWbqte+ynFs5tqmpChHIKGq/75DhuMFm3lBce+EolrmyBz\n\tzyEBnXS6sIkAzbcNXvKngIbN7b9iidEYt8nHgsbDED7EZXvO6pExiUNqgtXpFuM0iC\n\tjicYH8HDdr1q7IIkwaIPwIKSfDoNXrjK2qm+x3ZIe7rO4FHGe9KW1bvrciKTZwZLzi\n\tYLs82Gumvw7SUEEllhMpBDU3draChdRTi7MNDVIiLg+mjlYvitRPKA00C+u3zWPVP4\n\tEqnEijPFyN1NQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1695298403;\n\tbh=HX1N5I7KHT/rak62pUF1CQplXKWIbk6JTNR5HW0wHlI=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=q2Ea++R4w+oQw9D+HpyrEwkJAzkgnm0V10x9QQ8BsPPkoR61+Y2ZOXIWzMZnmC4ZB\n\tWscupC5OB6GoFMYt+Egl/oQBEio9GhdmVtWO586/C5sP+vS+pyp1PsUngkI+x8G6JX\n\tUDiQskIxP7SjlvcsuYmjzJ2gmXuQn4Nl4+nwIc5Y="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"q2Ea++R4\"; dkim-atps=neutral","Date":"Thu, 21 Sep 2023 15:15:12 +0300","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Message-ID":"<20230921121512.GB19112@pendragon.ideasonboard.com>","References":"<20230916121930.29490-1-jacopo.mondi@ideasonboard.com>\n\t<20230916121930.29490-3-jacopo.mondi@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20230916121930.29490-3-jacopo.mondi@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 02/12] 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":27831,"web_url":"https://patchwork.libcamera.org/comment/27831/","msgid":"<20230921121838.GA25640@pendragon.ideasonboard.com>","date":"2023-09-21T12:18:38","subject":"Re: [libcamera-devel] [PATCH v4 02/12] 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":"On Thu, Sep 21, 2023 at 03:15:14PM +0300, Laurent Pinchart wrote:\n> Hi Jacopo,\n> \n> Thank you for the patch.\n> \n> On Sat, Sep 16, 2023 at 02:19:20PM +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 |  43 +++++++++\n> >  src/libcamera/camera.cpp   | 183 +++++++++++++++++++++++++++++++++++++\n> >  2 files changed, 226 insertions(+)\n> > \n> > diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> > index 004bc89455f5..c4f9aa869489 100644\n> > --- a/include/libcamera/camera.h\n> > +++ b/include/libcamera/camera.h\n> > @@ -19,6 +19,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 +31,47 @@ 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> > +\t{\n> > +\t\treturn validate() != Invalid;\n> > +\t}\n> > +\n> > +\tbool populated() const\n> > +\t{\n> > +\t\treturn validate() == Populated;\n> > +\t}\n> > +\n> > +private:\n> > +\tenum Status {\n> > +\t\tUnpopulated,\n> > +\t\tPopulated,\n> > +\t\tInvalid,\n> > +\t};\n> > +\n> > +\tStatus validate() const;\n> > +};\n> > +\n> >  class CameraConfiguration\n> >  {\n> >  public:\n> > @@ -66,6 +108,7 @@ public:\n> >  \tbool empty() const;\n> >  \tstd::size_t size() const;\n> >  \n> > +\tSensorConfiguration sensorConfig;\n> >  \tTransform transform;\n> >  \n> >  protected:\n> > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> > index 0eecee766f00..3d8098239a7f 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,166 @@ 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> > + * 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> > + * 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> > + * \\enum SensorConfiguration::Status\n> > + * \\brief The sensor configuration validation status\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> > + * \\fn SensorConfiguration::valid() const\n> > + * \\brief Validate the SensorConfiguration\n> > + *\n> > + * Validate the sensor configuration.\n> > + *\n> > + * \\todo A sensor configuration is valid (or well-formed) if it's either\n> > + * completely un-populated or fully populated. For now allow applications to\n> > + * populate the bitDepth and the outputSize only.\n> > + *\n> > + * \\return True if the SensorConfiguration is either fully populated or\n> > + * un-populated, false otherwise\n> > + */\n> > +\n> > +/**\n> > + * \\fn SensorConfiguration::populated() const\n> > + * \\brief Test if a SensorConfiguration is fully populated\n> > + * \\return True if the SensorConfiguration is fully populated\n> > + */\n> > +\n> > +/**\n> > + * \\brief Validate the sensor configuration\n> > + *\n> > + * \\todo A sensor configuration is valid (or well-formed) if it's either\n> > + * completely un-populated or fully populated. For now allow applications to\n> > + * populate the bitDepth and the outputSize only.\n> > + *\n> > + * \\return The sensor configuration status\n> > + * \\retval Unpopulated The sensor configuration is fully unpopulated\n> > + * \\retval Populated The sensor configuration is fully populated\n> > + * \\retval Invalid The sensor configuration is invalid (not fully populated\n> > + * and not fully unpopulated)\n> > + */\n> > +SensorConfiguration::Status SensorConfiguration::validate() 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 Populated;\n> > +\n> > +\t/*\n> > +\t * By default the binning and skipping factors are initialized to 1, but\n> > +\t * a zero-initialized SensorConfiguration is considered unpopulated\n> > +\t * as well.\n> > +\t */\n> > +\tif (!bitDepth &&\n> > +\t    binning.binX <= 1 && binning.binY <= 1 &&\n> > +\t    skipping.xOddInc <= 1 && skipping.yOddInc <= 1 &&\n> > +\t    skipping.xEvenInc <= 1 && skipping.yEvenInc <= 1 &&\n> > +\t    outputSize.isNull())\n> > +\t\treturn Unpopulated;\n\nActually, stupid question, but wouldn't it be better to handled the\nunpopulated case using a std::optional<SensorConfiguration> in the\nCameraConfiguration class ?\n\n> > +\n> > +\treturn Invalid;\n> > +}\n> > +\n> >  /**\n> >   * \\class CameraConfiguration\n> >   * \\brief Hold configuration for streams of the camera\n> > @@ -391,6 +561,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 field allows control of the configuration of the camera\n> \n> s/field/member/\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \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> > +\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 043DCC326B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 21 Sep 2023 12:18:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4CA9062945;\n\tThu, 21 Sep 2023 14:18:28 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 8191962931\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 21 Sep 2023 14:18:26 +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 DD9761257;\n\tThu, 21 Sep 2023 14:16:48 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1695298708;\n\tbh=mYFQeRZAlIcpbBule6nj0d4H2+wHOVt5AERn2+/IjX0=;\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=dElxtiIVaqgQtpsr63rHtr6gqb0Ozpm+j45HMsmWuaeX+aEEQN4ifnv+Lhkz9CjVf\n\tRIzc6Mrd1LZ5bSij/E8JenYEkRtLb+fPX64zEmNAEwT8sorB3/vS9QRZPfTeqTJnUs\n\tiWUVNHgIP9ln85ns2Z8uSStbyDWEHAt2aSVW/Td3QvJ7mFjpt33pqt68J+DCOAKDm5\n\tZX+PnK6uh9CR/l6RvwuE2czHFE5CC8MnKY9SfczWgZu12KGjbPL4g+Mew2+BNng9Af\n\t8LitOpXEBxkUEqTbB39dC6HypgBrWeBEnHvfZp9BC4Dx7SyT0sQrCp4xa7uOmdUUuv\n\tyo7JIURLLBNXg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1695298609;\n\tbh=mYFQeRZAlIcpbBule6nj0d4H2+wHOVt5AERn2+/IjX0=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=UirbXPxs5dfrg90GSEzQIrdd5CZcMKUnYXc4j6JJRnBpW+4pFA3uW14zflahXsRIu\n\t4R1qa+pCGvtSxc2bHjE5G8xXqjOv0lY21R0AQ4bR29gIwIwXlzrIKjjACbTD4qtZTW\n\t2HjYmE6zjv8wD0Cwll4j/ud/ccYlOS5UJb58sCMA="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"UirbXPxs\"; dkim-atps=neutral","Date":"Thu, 21 Sep 2023 15:18:38 +0300","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Message-ID":"<20230921121838.GA25640@pendragon.ideasonboard.com>","References":"<20230916121930.29490-1-jacopo.mondi@ideasonboard.com>\n\t<20230916121930.29490-3-jacopo.mondi@ideasonboard.com>\n\t<20230921121512.GB19112@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20230921121512.GB19112@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v4 02/12] 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>"}}]