Show a patch.

GET /api/patches/15361/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 15361,
    "url": "https://patchwork.libcamera.org/api/patches/15361/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/15361/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220210114316.1151170-4-jeanmichel.hautbois@ideasonboard.com>",
    "date": "2022-02-10T11:43:16",
    "name": "[libcamera-devel,v3,3/3] ipa: ipu3: agc: Introduce lineDuration in IPASessionConfiguration",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "37f86b2c9e1a525d3b01ae2b35ed018f30fa67d8",
    "submitter": {
        "id": 75,
        "url": "https://patchwork.libcamera.org/api/people/75/?format=api",
        "name": "Jean-Michel Hautbois",
        "email": "jeanmichel.hautbois@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/15361/mbox/",
    "series": [
        {
            "id": 2928,
            "url": "https://patchwork.libcamera.org/api/series/2928/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=2928",
            "date": "2022-02-10T11:43:13",
            "name": "ipa: ipu3: Misc clean up",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/2928/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/15361/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/15361/checks/",
    "tags": {},
    "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 AD310C3257\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 10 Feb 2022 11:43:25 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4C2F5610F9;\n\tThu, 10 Feb 2022 12:43:24 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0673B610E2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 10 Feb 2022 12:43:21 +0100 (CET)",
            "from tatooine.ideasonboard.com (unknown\n\t[IPv6:2a01:e0a:169:7140:c44d:925d:d63:5b07])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B280193;\n\tThu, 10 Feb 2022 12:43:20 +0100 (CET)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Rm9oEoQ8\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1644493400;\n\tbh=5Ood8bPvug09NQJE7HHBjouVJ9MxDTxC/e0juSi7tfE=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=Rm9oEoQ8DbRngwr1b445O+vHvAuQ0GB14KOqFEjImM78NuvkgPoSoZw+flYPULazp\n\tQtN2ehcEuSbTyfeedeoqxvRpvBiike12iJ+uVpe2tSXCHTj62JwLzt0HdbJPL0os+u\n\tAvYElmivMbHiM2chi8KxSosvHLNaBXhPro97OvR0=",
        "From": "Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Thu, 10 Feb 2022 12:43:16 +0100",
        "Message-Id": "<20220210114316.1151170-4-jeanmichel.hautbois@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.32.0",
        "In-Reply-To": "<20220210114316.1151170-1-jeanmichel.hautbois@ideasonboard.com>",
        "References": "<20220210114316.1151170-1-jeanmichel.hautbois@ideasonboard.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v3 3/3] ipa: ipu3: agc: Introduce\n\tlineDuration in IPASessionConfiguration",
        "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>"
    },
    "content": "Instead of having a local cached value for line duration, store it in\nthe IPASessionConfiguration::sensor structure.\nWhile at it, configure the default analogue gain and shutter speed to\ncontrolled fixed values.\n\nThe latter is set to be 10ms as it will in most cases be close to the\none needed, making the AGC faster to converge.\n\nSigned-off-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com>\n---\n src/ipa/ipu3/algorithms/agc.cpp | 25 +++++++++++++++----------\n src/ipa/ipu3/algorithms/agc.h   |  3 +--\n src/ipa/ipu3/ipa_context.cpp    |  8 ++++++++\n src/ipa/ipu3/ipa_context.h      |  4 ++++\n src/ipa/ipu3/ipu3.cpp           | 27 ++++++++++++++-------------\n 5 files changed, 42 insertions(+), 25 deletions(-)",
    "diff": "diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\nindex a929085c..95720ca6 100644\n--- a/src/ipa/ipu3/algorithms/agc.cpp\n+++ b/src/ipa/ipu3/algorithms/agc.cpp\n@@ -71,7 +71,7 @@ static constexpr uint32_t kNumStartupFrames = 10;\n static constexpr double kRelativeLuminanceTarget = 0.16;\n \n Agc::Agc()\n-\t: frameCount_(0), lineDuration_(0s), minShutterSpeed_(0s),\n+\t: frameCount_(0), minShutterSpeed_(0s),\n \t  maxShutterSpeed_(0s), filteredExposure_(0s)\n {\n }\n@@ -85,11 +85,14 @@ Agc::Agc()\n  */\n int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)\n {\n-\tstride_ = context.configuration.grid.stride;\n+\tIPASessionConfiguration &configuration = context.configuration;\n+\tIPAFrameContext &frameContext = context.frameContext;\n+\n+\tstride_ = configuration.grid.stride;\n \n \t/* \\todo use the IPAContext to provide the limits */\n-\tlineDuration_ = configInfo.sensorInfo.lineLength * 1.0s\n-\t\t      / configInfo.sensorInfo.pixelRate;\n+\tconfiguration.sensor.lineDuration = configInfo.sensorInfo.lineLength * 1.0s\n+\t\t\t\t\t  / configInfo.sensorInfo.pixelRate;\n \n \tminShutterSpeed_ = context.configuration.agc.minShutterSpeed;\n \tmaxShutterSpeed_ = std::min(context.configuration.agc.maxShutterSpeed,\n@@ -99,8 +102,8 @@ int Agc::configure(IPAContext &context, const IPAConfigInfo &configInfo)\n \tmaxAnalogueGain_ = std::min(context.configuration.agc.maxAnalogueGain, kMaxAnalogueGain);\n \n \t/* Configure the default exposure and gain. */\n-\tcontext.frameContext.agc.gain = minAnalogueGain_;\n-\tcontext.frameContext.agc.exposure = minShutterSpeed_ / lineDuration_;\n+\tframeContext.agc.gain = std::max(minAnalogueGain_, kMinAnalogueGain);\n+\tframeContext.agc.exposure = 10ms / configuration.sensor.lineDuration;\n \n \treturn 0;\n }\n@@ -182,9 +185,11 @@ utils::Duration Agc::filterExposure(utils::Duration exposureValue)\n  * \\param[in] yGain The gain calculated based on the relative luminance target\n  * \\param[in] iqMeanGain The gain calculated based on the relative luminance target\n  */\n-void Agc::computeExposure(IPAFrameContext &frameContext, double yGain,\n+void Agc::computeExposure(IPAContext &context, double yGain,\n \t\t\t  double iqMeanGain)\n {\n+\tconst IPASessionConfiguration &configuration = context.configuration;\n+\tIPAFrameContext &frameContext = context.frameContext;\n \t/* Get the effective exposure and gain applied on the sensor. */\n \tuint32_t exposure = frameContext.sensor.exposure;\n \tdouble analogueGain = frameContext.sensor.gain;\n@@ -200,7 +205,7 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain,\n \t/* extracted from Rpi::Agc::computeTargetExposure */\n \n \t/* Calculate the shutter time in seconds */\n-\tutils::Duration currentShutter = exposure * lineDuration_;\n+\tutils::Duration currentShutter = exposure * configuration.sensor.lineDuration;\n \n \t/*\n \t * Update the exposure value for the next computation using the values\n@@ -247,7 +252,7 @@ void Agc::computeExposure(IPAFrameContext &frameContext, double yGain,\n \t\t\t    << stepGain;\n \n \t/* Update the estimated exposure and gain. */\n-\tframeContext.agc.exposure = shutterTime / lineDuration_;\n+\tframeContext.agc.exposure = shutterTime / configuration.sensor.lineDuration;\n \tframeContext.agc.gain = stepGain;\n }\n \n@@ -354,7 +359,7 @@ void Agc::process(IPAContext &context, const ipu3_uapi_stats_3a *stats)\n \t\t\tbreak;\n \t}\n \n-\tcomputeExposure(context.frameContext, yGain, iqMeanGain);\n+\tcomputeExposure(context, yGain, iqMeanGain);\n \tframeCount_++;\n }\n \ndiff --git a/src/ipa/ipu3/algorithms/agc.h b/src/ipa/ipu3/algorithms/agc.h\nindex 84bfe045..ad705605 100644\n--- a/src/ipa/ipu3/algorithms/agc.h\n+++ b/src/ipa/ipu3/algorithms/agc.h\n@@ -34,7 +34,7 @@ private:\n \tdouble measureBrightness(const ipu3_uapi_stats_3a *stats,\n \t\t\t\t const ipu3_uapi_grid_config &grid) const;\n \tutils::Duration filterExposure(utils::Duration currentExposure);\n-\tvoid computeExposure(IPAFrameContext &frameContext, double yGain,\n+\tvoid computeExposure(IPAContext &context, double yGain,\n \t\t\t     double iqMeanGain);\n \tdouble estimateLuminance(IPAFrameContext &frameContext,\n \t\t\t\t const ipu3_uapi_grid_config &grid,\n@@ -43,7 +43,6 @@ private:\n \n \tuint64_t frameCount_;\n \n-\tutils::Duration lineDuration_;\n \tutils::Duration minShutterSpeed_;\n \tutils::Duration maxShutterSpeed_;\n \ndiff --git a/src/ipa/ipu3/ipa_context.cpp b/src/ipa/ipu3/ipa_context.cpp\nindex 86794ac1..9c4ec936 100644\n--- a/src/ipa/ipu3/ipa_context.cpp\n+++ b/src/ipa/ipu3/ipa_context.cpp\n@@ -86,6 +86,14 @@ namespace libcamera::ipa::ipu3 {\n  * \\brief Maximum analogue gain supported with the configured sensor\n  */\n \n+/**\n+ * \\var IPASessionConfiguration::sensor\n+ * \\brief Sensor-specific configuration of the IPA\n+ *\n+ * \\var IPASessionConfiguration::sensor.lineDuration\n+ * \\brief Line duration in microseconds\n+ */\n+\n /**\n  * \\var IPAFrameContext::agc\n  * \\brief Context for the Automatic Gain Control algorithm\ndiff --git a/src/ipa/ipu3/ipa_context.h b/src/ipa/ipu3/ipa_context.h\nindex c6dc0814..e7c49828 100644\n--- a/src/ipa/ipu3/ipa_context.h\n+++ b/src/ipa/ipu3/ipa_context.h\n@@ -31,6 +31,10 @@ struct IPASessionConfiguration {\n \t\tdouble minAnalogueGain;\n \t\tdouble maxAnalogueGain;\n \t} agc;\n+\n+\tstruct {\n+\t\tutils::Duration lineDuration;\n+\t} sensor;\n };\n \n struct IPAFrameContext {\ndiff --git a/src/ipa/ipu3/ipu3.cpp b/src/ipa/ipu3/ipu3.cpp\nindex c0c29416..b137c66c 100644\n--- a/src/ipa/ipu3/ipu3.cpp\n+++ b/src/ipa/ipu3/ipu3.cpp\n@@ -173,8 +173,6 @@ private:\n \tuint32_t minGain_;\n \tuint32_t maxGain_;\n \n-\tutils::Duration lineDuration_;\n-\n \t/* Interface to the Camera Helper */\n \tstd::unique_ptr<CameraSensorHelper> camHelper_;\n \n@@ -206,8 +204,8 @@ void IPAIPU3::updateSessionConfiguration(const ControlInfoMap &sensorControls)\n \t *\n \t * \\todo take VBLANK into account for maximum shutter speed\n \t */\n-\tcontext_.configuration.agc.minShutterSpeed = minExposure * lineDuration_;\n-\tcontext_.configuration.agc.maxShutterSpeed = maxExposure * lineDuration_;\n+\tcontext_.configuration.agc.minShutterSpeed = minExposure * context_.configuration.sensor.lineDuration;\n+\tcontext_.configuration.agc.maxShutterSpeed = maxExposure * context_.configuration.sensor.lineDuration;\n \tcontext_.configuration.agc.minAnalogueGain = camHelper_->gain(minGain);\n \tcontext_.configuration.agc.maxAnalogueGain = camHelper_->gain(maxGain);\n }\n@@ -229,6 +227,7 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo,\n \t\t\t     ControlInfoMap *ipaControls)\n {\n \tControlInfoMap::Map controls{};\n+\tdouble lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();\n \n \t/*\n \t * Compute exposure time limits by using line length and pixel rate\n@@ -237,9 +236,9 @@ void IPAIPU3::updateControls(const IPACameraSensorInfo &sensorInfo,\n \t * microseconds.\n \t */\n \tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n-\tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration_.get<std::micro>();\n-\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration_.get<std::micro>();\n-\tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration_.get<std::micro>();\n+\tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;\n+\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;\n+\tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;\n \tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n \t\t\t\t\t\t\tdefExposure);\n \n@@ -293,6 +292,10 @@ int IPAIPU3::init(const IPASettings &settings,\n \t\treturn -ENODEV;\n \t}\n \n+\t/* Clean context */\n+\tcontext_ = {};\n+\tcontext_.configuration.sensor.lineDuration = sensorInfo.lineLength * 1.0s / sensorInfo.pixelRate;\n+\n \t/* Construct our Algorithms */\n \talgorithms_.push_back(std::make_unique<algorithms::Agc>());\n \talgorithms_.push_back(std::make_unique<algorithms::Awb>());\n@@ -454,12 +457,9 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo,\n \n \tdefVBlank_ = itVBlank->second.def().get<int32_t>();\n \n-\t/* Clean context at configuration */\n-\tcontext_ = {};\n-\n \tcalculateBdsGrid(configInfo.bdsOutputSize);\n \n-\tlineDuration_ = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate;\n+\tcontext_.configuration.sensor.lineDuration = sensorInfo_.lineLength * 1.0s / sensorInfo_.pixelRate;\n \n \t/* Update the camera controls using the new sensor settings. */\n \tupdateControls(sensorInfo_, ctrls_, ipaControls);\n@@ -620,6 +620,7 @@ void IPAIPU3::parseStatistics(unsigned int frame,\n \t\t\t      [[maybe_unused]] int64_t frameTimestamp,\n \t\t\t      const ipu3_uapi_stats_3a *stats)\n {\n+\tdouble lineDuration = context_.configuration.sensor.lineDuration.get<std::micro>();\n \tControlList ctrls(controls::controls);\n \n \tfor (auto const &algo : algorithms_)\n@@ -628,14 +629,14 @@ void IPAIPU3::parseStatistics(unsigned int frame,\n \tsetControls(frame);\n \n \t/* \\todo Use VBlank value calculated from each frame exposure. */\n-\tint64_t frameDuration = (defVBlank_ + sensorInfo_.outputSize.height) * lineDuration_.get<std::micro>();\n+\tint64_t frameDuration = (defVBlank_ + sensorInfo_.outputSize.height) * lineDuration;\n \tctrls.set(controls::FrameDuration, frameDuration);\n \n \tctrls.set(controls::AnalogueGain, context_.frameContext.sensor.gain);\n \n \tctrls.set(controls::ColourTemperature, context_.frameContext.awb.temperatureK);\n \n-\tctrls.set(controls::ExposureTime, context_.frameContext.sensor.exposure * lineDuration_.get<std::micro>());\n+\tctrls.set(controls::ExposureTime, context_.frameContext.sensor.exposure * lineDuration);\n \n \t/*\n \t * \\todo The Metadata provides a path to getting extended data\n",
    "prefixes": [
        "libcamera-devel",
        "v3",
        "3/3"
    ]
}