[{"id":27613,"web_url":"https://patchwork.libcamera.org/comment/27613/","msgid":"<CAEmqJPr4RF0GQBVM=aPWPDvqSm2Zjny+ZAxHUasie2E6nqZPbg@mail.gmail.com>","date":"2023-07-26T09:01:16","subject":"Re: [libcamera-devel] [PATCH 2/4] libcamera: camera: Introduce\n\tSensorConfiguration","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi Jacopo,\n\nThank you for your work.\n\nOn Mon, 24 Jul 2023 at 13:39, Jacopo Mondi via libcamera-devel\n<libcamera-devel@lists.libcamera.org> wrote:\n>\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> ---\n>  include/libcamera/camera.h |  43 +++++++++\n>  src/libcamera/camera.cpp   | 180 +++++++++++++++++++++++++++++++++++++\n>  2 files changed, 223 insertions(+)\n>\n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 004bc89455f5..b2aa8d467feb 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> +       unsigned int bitDepth = 0;\n> +\n> +       Rectangle analogCrop;\n> +\n> +       struct {\n> +               unsigned int binX = 1;\n> +               unsigned int binY = 1;\n> +       } binning;\n> +\n> +       struct {\n> +               unsigned int xOddInc = 1;\n> +               unsigned int xEvenInc = 1;\n> +               unsigned int yOddInc = 1;\n> +               unsigned int yEvenInc = 1;\n> +       } skipping;\n> +\n> +       Size outputSize;\n> +\n> +       bool valid() const\n> +       {\n> +               return validate() != Invalid;\n> +       }\n> +\n> +       explicit operator bool() const\n> +       {\n> +               return validate() == Populated;\n> +       }\n> +\n> +private:\n> +       enum Status {\n> +               Unpopulated,\n> +               Populated,\n> +               Invalid,\n> +       };\n> +\n> +       Status validate() const;\n> +};\n> +\n>  class CameraConfiguration\n>  {\n>  public:\n> @@ -66,6 +108,7 @@ public:\n>         bool empty() const;\n>         std::size_t size() const;\n>\n> +       SensorConfiguration sensorConfig;\n>         Transform transform;\n>\n>  protected:\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 0eecee766f00..b58d120cd802 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -97,6 +97,21 @@\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-mode Camera Sensor Model\n> + *\n> + * libcamera allows applications to control the configuration of the camera\n> + * sensor, particularly it allows to control the frame geometry and frame\n> + * delivery rate of the sensor.\n> + *\n> + * The camera sensor configuration applies to all streams produced by a camera\n> + * from the same image source.\n> + *\n> + * More details about the libcamera implemented camera sensor model are\n> + * available in the libcamera camera-sensor-model documentation page.\n> + *\n> + * The sensor configuration is specified by applications by populating the\n> + * CameraConfiguration::sensorConfig class member.\n> + *\n>   * \\subsection digital-zoom Digital Zoom\n>   *\n>   * Digital zoom is implemented as a combination of the cropping and scaling\n> @@ -111,6 +126,161 @@ 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 allows to populate\n\ns/allows to populate/allow applications to populate/ ?\n\n> + * 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::operator bool() 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 allows to populate\n\ns/allows to populate/allow applications to populate/ ?\n\nTypos aside\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n> + * 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> +       if (bitDepth && binning.binX && binning.binY &&\n> +           skipping.xOddInc && skipping.yOddInc &&\n> +           skipping.xEvenInc && skipping.yEvenInc &&\n> +           !outputSize.isNull())\n> +               return Populated;\n> +\n> +       if (!bitDepth &&\n> +           binning.binX <= 1 && binning.binY <= 1 &&\n> +           skipping.xOddInc <= 1 && skipping.yOddInc <= 1 &&\n> +           skipping.xEvenInc <= 1 && skipping.yEvenInc <= 1 &&\n> +           outputSize.isNull())\n> +               return Unpopulated;\n> +\n> +       return Invalid;\n> +}\n> +\n>  /**\n>   * \\class CameraConfiguration\n>   * \\brief Hold configuration for streams of the camera\n> @@ -391,6 +561,16 @@ CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF\n>         return status;\n>  }\n>\n> +/**\n> + * \\var CameraConfiguration::sensorConfig\n> + * \\brief The camera sensor configuration\n> + *\n> + * The sensorConfig field allows to control 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> +\n>  /**\n>   * \\var CameraConfiguration::transform\n>   * \\brief User-specified transform to be applied to the image\n> --\n> 2.40.1\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 9F78ABDC71\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 26 Jul 2023 09:01:34 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 08696628BA;\n\tWed, 26 Jul 2023 11:01:34 +0200 (CEST)","from mail-yw1-x1132.google.com (mail-yw1-x1132.google.com\n\t[IPv6:2607:f8b0:4864:20::1132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 56111628BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 26 Jul 2023 11:01:32 +0200 (CEST)","by mail-yw1-x1132.google.com with SMTP id\n\t00721157ae682-583f65806f8so37244887b3.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 26 Jul 2023 02:01:32 -0700 (PDT)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1690362094;\n\tbh=hYG3XlZtAaE11OpgnGmNI0VjIuNwJ9SN4SU7zBlL/pw=;\n\th=References:In-Reply-To:Date:To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=k7wFLHM+PKLdDwhSWEsH0XkGEOngeHd327FRce3vX1uK0Dm4d3HFyNU9JYkRnxhDn\n\tmoFCSFOGVyqOwwvc52OecVRnv60FjQTAjX5q1+iG4bjcnK4Jrv6qdifL+7akUicyhR\n\tJ2brcNjwxxRpRw40X/lDtvuuni1ywbkpiyRlcY4w2g67bBzPybTl/La/vA2zUUxJ2t\n\tncXw56B3atrf51r2cs5Oc/Q39v3A9g49F4e17owqihi0gvJRg+dWtNt32IeqBSjUMo\n\tQ29hGKXDqvMUmpTHQCPqBW5zfBho3jr4P9lZxrZIuYjD01B0z6JQbxXO6pxB+c59qk\n\tG2QSVjR31ruTg==","v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1690362091; x=1690966891;\n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:from:to:cc:subject:date:message-id:reply-to;\n\tbh=F1EcFCLkkXQw/gwCK+WfqNddL8w16AlmiCiyZdpWb/A=;\n\tb=Doti9uiYzO8CoB9HBl+OVn+BEx6SWdlzBcOAdiIf9rG98JQ3SztOAORKje84DQQkKR\n\tnqEJc0Almd2Igo2Takn0ZtNzequ+Xk+hgNaIlurcei+ejn5zM7PTLOc8h2bPc6qJXGtY\n\to9zrXxA0Ym2SgRHuXDtVDO0FB50dqPRYWxPYJ1utBjL5frEgvoJ2lJygXCkwNbgIIE8F\n\tiE0PQY/ftg5T2DrzKI3WhM3WLgdUi5fLNrrTKkbn4/FT5Ra4neyjkE6pdDtgii/QXkdj\n\t9XpKxFst/lYAlm1ClCI8RrOoNz5hFcntOPuYfgx+E9DBYZOwvxAbM74iYoFAS5v2oFvh\n\tuKHA=="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected) header.d=raspberrypi.com\n\theader.i=@raspberrypi.com\n\theader.b=\"Doti9uiY\"; dkim-atps=neutral","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20221208; t=1690362091; x=1690966891;\n\th=cc:to:subject:message-id:date:from:in-reply-to:references\n\t:mime-version:x-gm-message-state:from:to:cc:subject:date:message-id\n\t:reply-to;\n\tbh=F1EcFCLkkXQw/gwCK+WfqNddL8w16AlmiCiyZdpWb/A=;\n\tb=DCMTf/DbUa8lRbFPZ2YEPcmHLzRjgv51tfMbR1JzRoVJNmuFuaewU+cgtXyJCR51GW\n\t/UVvfiC71kGNFRncx+xeTV8FHz+Wt8VsX00S4cGYJR6rhSv86n52ng27OH22LbrKjOW5\n\tZuX3RGxj3/UAXGzcTAAgAhbHBqMLQQpxJ5gSJFF/yRB1gXW7bmCTrG+DQOu14tDAx6/n\n\tk1LeDGPzWr9yKa6k23GNdpaV9RI8b+vPF+tTfZpZJdHxbwxOhgOcmwsFEQCGO/Cc63g4\n\tMif/Ie+TphDb8+HKM9VofAtP2lt/8Aznt7bzi6XI9OLWLBi3bM7Nu42ha906wQ3eWTXI\n\tT9wg==","X-Gm-Message-State":"ABy/qLZfC3/Cx5zJHu3KNzfEMerbvzcBnhCafKPDFbgN2YEVSdMkPZ6Q\n\tn+dwrpBvEwHX/857GPS6rfeIqASW9NAv4yT2RnkkIC+xDuEy/OGgDEV8og==","X-Google-Smtp-Source":"APBJJlEdeG+hZdT6rlq7EClpJ9GZH+X0F2PFlhJim8wHiwiC/iVRED2wqxBdv368zp0RoDnL4AfFqiywRQU0JU5pruY=","X-Received":"by 2002:a81:8941:0:b0:57a:1246:5e5b with SMTP id\n\tz62-20020a818941000000b0057a12465e5bmr1711365ywf.38.1690362091082;\n\tWed, 26 Jul 2023 02:01:31 -0700 (PDT)","MIME-Version":"1.0","References":"<20230724123907.29086-1-jacopo.mondi@ideasonboard.com>\n\t<20230724123907.29086-3-jacopo.mondi@ideasonboard.com>","In-Reply-To":"<20230724123907.29086-3-jacopo.mondi@ideasonboard.com>","Date":"Wed, 26 Jul 2023 10:01:16 +0100","Message-ID":"<CAEmqJPr4RF0GQBVM=aPWPDvqSm2Zjny+ZAxHUasie2E6nqZPbg@mail.gmail.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Content-Type":"text/plain; charset=\"UTF-8\"","Subject":"Re: [libcamera-devel] [PATCH 2/4] 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":"Naushir Patuck via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Naushir Patuck <naush@raspberrypi.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]