Show a patch.

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

{
    "id": 17677,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/17677/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/17677/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/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": "<20221024055543.116040-2-nicholas@rothemail.net>",
    "date": "2022-10-24T05:55:33",
    "name": "[libcamera-devel,01/11] Fixes Bug 156, which breaks libcamera on Android < 12.",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "f584491fe853fb251415fc78dcee33b1387eb849",
    "submitter": {
        "id": 97,
        "url": "https://patchwork.libcamera.org/api/1.1/people/97/?format=api",
        "name": "Nicolas Dufresne via libcamera-devel",
        "email": "libcamera-devel@lists.libcamera.org"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/17677/mbox/",
    "series": [
        {
            "id": 3575,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3575/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3575",
            "date": "2022-10-24T05:55:33",
            "name": "[libcamera-devel,01/11] Fixes Bug 156, which breaks libcamera on Android < 12.",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/3575/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/17677/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/17677/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 78E41BD16B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 24 Oct 2022 05:55:53 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3F6A062EEC;\n\tMon, 24 Oct 2022 07:55:53 +0200 (CEST)",
            "from mail-ot1-x333.google.com (mail-ot1-x333.google.com\n\t[IPv6:2607:f8b0:4864:20::333])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C46F261F4C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 24 Oct 2022 07:55:51 +0200 (CEST)",
            "by mail-ot1-x333.google.com with SMTP id\n\tbr15-20020a056830390f00b0061c9d73b8bdso5361922otb.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 23 Oct 2022 22:55:51 -0700 (PDT)",
            "from nroth-pc.attlocal.net\n\t([2600:1700:20:20c0:7bc3:aed3:676f:10a0])\n\tby smtp.gmail.com with ESMTPSA id\n\tx15-20020a9d628f000000b0066193df8edasm3980278otk.34.2022.10.23.22.55.49\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 23 Oct 2022 22:55:49 -0700 (PDT)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1666590953;\n\tbh=2DJHBIv3lJ1ncEjTiHiFNMOOJnyb+5sStiN4rc78Rzs=;\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=iQkXxcdkTcP1JOoiaDV6oPXCPVGCJxNCoga1gAaUXOmQYpnx/mPsqiuPAMYY7Isgl\n\tW1ZkJqVTA57c423Q+5Uj4sXhkLO6x51JRXG3RLG2vGF5rTpfmfIHEw1NKMipw81mXn\n\tLzsI7kiX4p+AOKmsXLOSWkrYbZ7V/5iidRRnvLAbTsipWF7om5jCs9i/3PLVXziGF4\n\t9gRllde19RVJHWuaWb1lWTnfIUStHhT9FJOZBHUS6oqod17I/o6/quN2E2a+0+ulpK\n\t8uusJaXlE25Xo1grX0kD/qPKgkrqrQzm3KwwHsWEniV3Zme2b9E1pu9z0oWZZoutCE\n\tDFZ4J/vXi6xmw==",
            "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=rothemail-net.20210112.gappssmtp.com; s=20210112;\n\th=content-transfer-encoding:mime-version:reply-to:references\n\t:in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=9rplnuUN0pnsIlI3cmDpVxuZ3BxsKKTvsZ2YHWy1u2E=;\n\tb=T7bvSu+sYZ+j/4XjWP00dW8fH131PWir0TDkanUfUb+kKuGDHAg2aNkOX5zK1EbYbh\n\tGEBj/LXehlWk/99YYApSaJQcZ1MEMnIPfYlnSZXPmxKOgW7UvBkDZLiI/cVzaPRj0DkX\n\tN8W186sqqT6Ogffv2930F0uo4ziztbKOk7DI3ah7OheXtkYEJCKjK4p5wE+1i1h/8ptV\n\tlAC5AZ6oqHH2oQ0ByktaYPf5Q0t0/z4o4ZvR3UpDy1XHG2uaiAGr2wfwpF2EK0O2Y0W9\n\tvMrB66/PPZkPzsIZYal8sOj41o59ZHYoBOTA+EUiXDkXjVguLLyqlqwFbtiCgNhpLS+3\n\tCuTQ=="
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected)\n\theader.d=rothemail-net.20210112.gappssmtp.com\n\theader.i=@rothemail-net.20210112.gappssmtp.com header.b=\"T7bvSu+s\"; \n\tdkim-atps=neutral",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20210112;\n\th=content-transfer-encoding:mime-version:reply-to:references\n\t:in-reply-to:message-id:date:subject:cc:to:from:x-gm-message-state\n\t:from:to:cc:subject:date:message-id:reply-to;\n\tbh=9rplnuUN0pnsIlI3cmDpVxuZ3BxsKKTvsZ2YHWy1u2E=;\n\tb=vfv0+9/rj7phsgP5Ops8HsJrJY2jxTWY3uPJZfhWFCguQD6QOfTD/fYbqGx8nkWWzz\n\tZnGN5rKtoectz3yRsj6ZuJwgGMzI67fkZWy4KPxJbEG3g9gmGb8Qpzy8nL5TVXaQKRKM\n\tM0MJIm+vX4fC7GKM9KPZzP84jlgh4N8hYE5zVpJZnzJ/rVmwR8bifnKo2bPFs7aWxYa/\n\tqPLxSJMc2AoC3wO1npMIYJoR72dmOzh/WD0GVjWKxMQDkXTvIqC4owLuqPU0JVERVFHp\n\tVXxhIoYslNW8tk3wDVFF7zAFwoJKOAbcDNxQPCJprAxmQxIf95Fc2bo0ZJQ2iyxZW+Is\n\tSFAw==",
        "X-Gm-Message-State": "ACrzQf2eHG0hFETdvMtOpqThye7AXtnJcVt0Hwx3jBHiqfu+06XvpSUW\n\tvB8la/gXf/LROF7dTFyXcWxJV1IsOPDcE+yh",
        "X-Google-Smtp-Source": "AMsMyM6DZCVIkXT9K+HvkFjqmlj2Y43DoxOTWtah64pohKtUmlFq/TqiwoP/zi/r/ZzravC9NtsJKg==",
        "X-Received": "by 2002:a05:6830:148e:b0:661:9422:f0e1 with SMTP id\n\ts14-20020a056830148e00b006619422f0e1mr16471640otq.205.1666590950213; \n\tSun, 23 Oct 2022 22:55:50 -0700 (PDT)",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 24 Oct 2022 00:55:33 -0500",
        "Message-Id": "<20221024055543.116040-2-nicholas@rothemail.net>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20221024055543.116040-1-nicholas@rothemail.net>",
        "References": "<20221024055543.116040-1-nicholas@rothemail.net>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH 01/11] Fixes Bug 156,\n\twhich breaks libcamera on Android < 12.",
        "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": "Nicholas Roth via libcamera-devel <libcamera-devel@lists.libcamera.org>",
        "Reply-To": "libcamera-devel@lists.libcamera.org",
        "Cc": "nicholas@rothemail.net",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "From: Nicholas Roth <nicholas@rothemail.net>\n\n---\n src/ipa/ipu3/algorithms/agc.cpp            | 18 ++++++++++++++----\n src/ipa/raspberrypi/cam_helper.cpp         |  9 ++++++---\n src/ipa/raspberrypi/cam_helper_imx296.cpp  |  5 ++++-\n src/ipa/raspberrypi/controller/rpi/agc.cpp | 18 ++++++++++++++----\n src/ipa/raspberrypi/controller/rpi/lux.cpp |  5 ++++-\n src/ipa/rkisp1/algorithms/agc.cpp          | 22 ++++++++++++++++++----\n 6 files changed, 60 insertions(+), 17 deletions(-)",
    "diff": "diff --git a/src/ipa/ipu3/algorithms/agc.cpp b/src/ipa/ipu3/algorithms/agc.cpp\nindex a1a3c38f..80c551bb 100644\n--- a/src/ipa/ipu3/algorithms/agc.cpp\n+++ b/src/ipa/ipu3/algorithms/agc.cpp\n@@ -100,7 +100,10 @@ int Agc::configure(IPAContext &context,\n \n \t/* Configure the default exposure and gain. */\n \tactiveState.agc.gain = std::max(minAnalogueGain_, kMinAnalogueGain);\n-\tactiveState.agc.exposure = 10ms / configuration.sensor.lineDuration;\n+\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\tdouble ten_millis = utils::Duration(10ms).get<std::nano>();\n+\tactiveState.agc.exposure = ten_millis /\n+\t\tconfiguration.sensor.lineDuration.get<std::nano>();\n \n \tframeCount_ = 0;\n \treturn 0;\n@@ -238,11 +241,16 @@ void Agc::computeExposure(IPAContext &context, IPAFrameContext &frameContext,\n \t *\n \t * Push the shutter time up to the maximum first, and only then\n \t * increase the gain.\n+\t *\n+\t * TODO(Bug 156): Workaround for LLVM bug.\n \t */\n+\tdouble exposureValueDouble = exposureValue.get<std::nano>();\n+\tutils::Duration shutterTimeRaw(exposureValueDouble / minAnalogueGain_);\n \tutils::Duration shutterTime =\n-\t\tstd::clamp<utils::Duration>(exposureValue / minAnalogueGain_,\n+\t\tstd::clamp<utils::Duration>(shutterTimeRaw,\n \t\t\t\t\t    minShutterSpeed_, maxShutterSpeed_);\n-\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n+\tdouble shutterTimeDouble = shutterTime.get<std::nano>();\n+\tdouble stepGain = std::clamp(exposureValueDouble / shutterTimeDouble,\n \t\t\t\t     minAnalogueGain_, maxAnalogueGain_);\n \tLOG(IPU3Agc, Debug) << \"Divided up shutter and gain are \"\n \t\t\t    << shutterTime << \" and \"\n@@ -250,7 +258,9 @@ void Agc::computeExposure(IPAContext &context, IPAFrameContext &frameContext,\n \n \tIPAActiveState &activeState = context.activeState;\n \t/* Update the estimated exposure and gain. */\n-\tactiveState.agc.exposure = shutterTime / configuration.sensor.lineDuration;\n+\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\tdouble lineDurationDouble = configuration.sensor.lineDuration.get<std::nano>();\n+\tactiveState.agc.exposure = shutterTimeDouble / lineDurationDouble;\n \tactiveState.agc.gain = stepGain;\n }\n \ndiff --git a/src/ipa/raspberrypi/cam_helper.cpp b/src/ipa/raspberrypi/cam_helper.cpp\nindex d90ac1de..31a9a1ef 100644\n--- a/src/ipa/raspberrypi/cam_helper.cpp\n+++ b/src/ipa/raspberrypi/cam_helper.cpp\n@@ -63,7 +63,8 @@ void CamHelper::process([[maybe_unused]] StatisticsPtr &stats,\n \n uint32_t CamHelper::exposureLines(const Duration exposure, const Duration lineLength) const\n {\n-\treturn exposure / lineLength;\n+\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\treturn exposure.get<std::nano>() / lineLength.get<std::nano>();\n }\n \n Duration CamHelper::exposure(uint32_t exposureLines, const Duration lineLength) const\n@@ -84,9 +85,11 @@ std::pair<uint32_t, uint32_t> CamHelper::getBlanking(Duration &exposure,\n \t *\n \t * frameLengthMax gets calculated on the smallest line length as we do\n \t * not want to extend that unless absolutely necessary.\n+\t *\n+\t * TODO(Bug 156): Workaround for LLVM bug.\n \t */\n-\tframeLengthMin = minFrameDuration / mode_.minLineLength;\n-\tframeLengthMax = maxFrameDuration / mode_.minLineLength;\n+\tframeLengthMin = minFrameDuration.get<std::nano>() / mode_.minLineLength.get<std::nano>();\n+\tframeLengthMax = maxFrameDuration.get<std::nano>() / mode_.minLineLength.get<std::nano>();\n \n \t/*\n \t * Watch out for (exposureLines + frameIntegrationDiff_) overflowing a\ndiff --git a/src/ipa/raspberrypi/cam_helper_imx296.cpp b/src/ipa/raspberrypi/cam_helper_imx296.cpp\nindex ecb845e7..e48f5cf2 100644\n--- a/src/ipa/raspberrypi/cam_helper_imx296.cpp\n+++ b/src/ipa/raspberrypi/cam_helper_imx296.cpp\n@@ -57,7 +57,10 @@ double CamHelperImx296::gain(uint32_t gainCode) const\n uint32_t CamHelperImx296::exposureLines(const Duration exposure,\n \t\t\t\t\t[[maybe_unused]] const Duration lineLength) const\n {\n-\treturn std::max<uint32_t>(minExposureLines, (exposure - 14.26us) / timePerLine);\n+\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\tdouble exposureTime = Duration(exposure - 14.26us).get<std::nano>();\n+\tdouble timePerLineNano = timePerLine.get<std::nano>();\n+\treturn std::max<uint32_t>(minExposureLines, exposureTime / timePerLineNano);\n }\n \n Duration CamHelperImx296::exposure(uint32_t exposureLines,\ndiff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp\nindex bd54a639..720ba788 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n@@ -418,7 +418,10 @@ void Agc::prepare(Metadata *imageMetadata)\n \t\t\tDuration actualExposure = deviceStatus.shutterSpeed *\n \t\t\t\t\t\t  deviceStatus.analogueGain;\n \t\t\tif (actualExposure) {\n-\t\t\t\tstatus_.digitalGain = status_.totalExposureValue / actualExposure;\n+\t\t\t\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\t\t\t\tdouble totalExposureDouble = status_.totalExposureValue.get<std::nano>();\n+\t\t\t\tdouble actualExposureDouble = actualExposure.get<std::nano>();\n+\t\t\t\tstatus_.digitalGain = totalExposureDouble / actualExposureDouble;\n \t\t\t\tLOG(RPiAgc, Debug) << \"Want total exposure \" << status_.totalExposureValue;\n \t\t\t\t/*\n \t\t\t\t * Never ask for a gain < 1.0, and also impose\n@@ -823,7 +826,10 @@ void Agc::divideUpExposure()\n \t\t\t}\n \t\t\tif (status_.fixedAnalogueGain == 0.0) {\n \t\t\t\tif (exposureMode_->gain[stage] * shutterTime >= exposureValue) {\n-\t\t\t\t\tanalogueGain = exposureValue / shutterTime;\n+\t\t\t\t\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\t\t\t\t\tdouble exposureDouble = exposureValue.get<std::nano>();\n+\t\t\t\t\tdouble shutterTimeDouble = shutterTime.get<std::nano>();\n+\t\t\t\t\tanalogueGain = exposureDouble / shutterTimeDouble;\n \t\t\t\t\tbreak;\n \t\t\t\t}\n \t\t\t\tanalogueGain = exposureMode_->gain[stage];\n@@ -838,10 +844,14 @@ void Agc::divideUpExposure()\n \t */\n \tif (!status_.fixedShutter && !status_.fixedAnalogueGain &&\n \t    status_.flickerPeriod) {\n-\t\tint flickerPeriods = shutterTime / status_.flickerPeriod;\n+\t\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\t\tdouble shutterTimeDouble = shutterTime.get<std::nano>();\n+\t\tdouble flickerPeriod = status_.flickerPeriod.get<std::nano>();\n+\t\tint flickerPeriods = shutterTimeDouble / flickerPeriod;\n \t\tif (flickerPeriods) {\n \t\t\tDuration newShutterTime = flickerPeriods * status_.flickerPeriod;\n-\t\t\tanalogueGain *= shutterTime / newShutterTime;\n+\t\t\tdouble newShutterTimeDouble = newShutterTime.get<std::nano>();\n+\t\t\tanalogueGain *= shutterTimeDouble / newShutterTimeDouble;\n \t\t\t/*\n \t\t\t * We should still not allow the ag to go over the\n \t\t\t * largest value in the exposure mode. Note that this\ndiff --git a/src/ipa/raspberrypi/controller/rpi/lux.cpp b/src/ipa/raspberrypi/controller/rpi/lux.cpp\nindex 9759186a..49303409 100644\n--- a/src/ipa/raspberrypi/controller/rpi/lux.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/lux.cpp\n@@ -93,8 +93,11 @@ void Lux::process(StatisticsPtr &stats, Metadata *imageMetadata)\n \t\t/* add .5 to reflect the mid-points of bins */\n \t\tdouble currentY = sum / (double)num + .5;\n \t\tdouble gainRatio = referenceGain_ / currentGain;\n+\t\t/* TODO(Bug 156): Workaround for LLVM bug. */\n+\t\tdouble referenceShutterSpeedDouble = referenceShutterSpeed_.get<std::nano>();\n+\t\tdouble deviceShutterSpeed = deviceStatus.shutterSpeed.get<std::nano>();\n \t\tdouble shutterSpeedRatio =\n-\t\t\treferenceShutterSpeed_ / deviceStatus.shutterSpeed;\n+\t\t\treferenceShutterSpeedDouble / deviceShutterSpeed;\n \t\tdouble apertureRatio = referenceAperture_ / currentAperture;\n \t\tdouble yRatio = currentY * (65536 / numBins) / referenceY_;\n \t\tdouble estimatedLux = shutterSpeedRatio * gainRatio *\ndiff --git a/src/ipa/rkisp1/algorithms/agc.cpp b/src/ipa/rkisp1/algorithms/agc.cpp\nindex 04062a36..3ea0b732 100644\n--- a/src/ipa/rkisp1/algorithms/agc.cpp\n+++ b/src/ipa/rkisp1/algorithms/agc.cpp\n@@ -74,7 +74,13 @@ int Agc::configure(IPAContext &context, const IPACameraSensorInfo &configInfo)\n {\n \t/* Configure the default exposure and gain. */\n \tcontext.activeState.agc.gain = std::max(context.configuration.agc.minAnalogueGain, kMinAnalogueGain);\n-\tcontext.activeState.agc.exposure = 10ms / context.configuration.sensor.lineDuration;\n+\t/* TODO(Bug 156): Explicit division of ticks (e.g., `x.get<std::nano>() /\n+\t * y.get<std::nano>()` as opposed to `x / y`) is a workaround for\n+\t * LLVM bug 41130 and should be reverted once we no longer target\n+\t * Android 11 / sdk30 since it compromises unit safety and readability. */\n+\tconstexpr libcamera::utils::Duration ten_millis(10ms);\n+\tlong double exposure = ten_millis.get<std::nano>() / context.configuration.sensor.lineDuration.get<std::nano>();\n+\tcontext.activeState.agc.exposure = uint32_t(exposure);\n \n \t/*\n \t * According to the RkISP1 documentation:\n@@ -211,17 +217,25 @@ void Agc::computeExposure(IPAContext &context, IPAFrameContext &frameContext,\n \t/*\n \t * Push the shutter time up to the maximum first, and only then\n \t * increase the gain.\n+\t *\n+\t * TODO(Bug 156): Explicit division of ticks (e.g., `x.get<std::nano>() /\n+\t * y.get<std::nano>()` as opposed to `x / y`) is a workaround for\n+\t * LLVM bug 41130 and should be reverted once we no longer target\n+\t * Android 11 / sdk30 since it compromises unit safety and readability.\n \t */\n-\tutils::Duration shutterTime = std::clamp<utils::Duration>(exposureValue / minAnalogueGain,\n+\tutils::Duration shutterTimeUnclamped(exposureValue.get<std::nano>() / minAnalogueGain);\n+\tutils::Duration shutterTime = std::clamp<utils::Duration>(shutterTimeUnclamped,\n \t\t\t\t\t\t\t\t  minShutterSpeed, maxShutterSpeed);\n-\tdouble stepGain = std::clamp(exposureValue / shutterTime,\n+\tdouble stepGainUnclamped = exposureValue.get<std::nano>() / shutterTime.get<std::nano>();\n+\tdouble stepGain = std::clamp(stepGainUnclamped,\n \t\t\t\t     minAnalogueGain, maxAnalogueGain);\n \tLOG(RkISP1Agc, Debug) << \"Divided up shutter and gain are \"\n \t\t\t      << shutterTime << \" and \"\n \t\t\t      << stepGain;\n \n \t/* Update the estimated exposure and gain. */\n-\tactiveState.agc.exposure = shutterTime / configuration.sensor.lineDuration;\n+\tactiveState.agc.exposure = uint32_t(shutterTime.get<std::nano>() /\n+\t\tconfiguration.sensor.lineDuration.get<std::nano>());\n \tactiveState.agc.gain = stepGain;\n }\n \n",
    "prefixes": [
        "libcamera-devel",
        "01/11"
    ]
}