Show a patch.

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

{
    "id": 10466,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/10466/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10466/",
    "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": "<20201123073804.3125-8-david.plowman@raspberrypi.com>",
    "date": "2020-11-23T07:38:01",
    "name": "[libcamera-devel,v2,07/10] libcamera: ipa: raspberrypi: agc: Report fixed exposure/gain values during SwitchMode",
    "commit_ref": "2fb5b298da8b965afb4cecbe17cbb24975e9f4db",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "5d25691faafdec5f26c0dd883659cc26f15f7a74",
    "submitter": {
        "id": 42,
        "url": "https://patchwork.libcamera.org/api/1.1/people/42/?format=api",
        "name": "David Plowman",
        "email": "david.plowman@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/10466/mbox/",
    "series": [
        {
            "id": 1475,
            "url": "https://patchwork.libcamera.org/api/1.1/series/1475/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1475",
            "date": "2020-11-23T07:37:54",
            "name": "Raspberry Pi AGC",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/1475/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/10466/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10466/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 E2799BE177\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Nov 2020 07:38:38 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9B47663327;\n\tMon, 23 Nov 2020 08:38:38 +0100 (CET)",
            "from mail-wr1-x436.google.com (mail-wr1-x436.google.com\n\t[IPv6:2a00:1450:4864:20::436])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E9EC6334E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Nov 2020 08:38:37 +0100 (CET)",
            "by mail-wr1-x436.google.com with SMTP id r17so17622056wrw.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 22 Nov 2020 23:38:37 -0800 (PST)",
            "from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\th15sm17841822wrw.15.2020.11.22.23.38.35\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 22 Nov 2020 23:38:35 -0800 (PST)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"WajKYdJ7\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=Xj/mIFBwOUaGUcNu8yackrW21gg3ew3bmgpzWscYFA8=;\n\tb=WajKYdJ7RUt1gRAoKxfphhvsFFBPZBjP8K8S0awtYcKOpqWVAOrjGCOiQNwEE7Lei1\n\tyS/lNVJME67gscnn2GNLO/3r6//+d4/wHSpoaW1G87ziDZZcokVB32kgaGhsYAFhrpDn\n\tyerdT4tgrK1iCfW7mPUbvEs0A2Xn9/QzT4ytYvZI5uW7M7zE/S6HrdM+Lxc6M9zSAgvg\n\tHrHk2iCgfLOz1og9x2idT7pLt0fbsFkmUyOcVA/+1hKM9v5bmbcPUJmhhzWXfoLT4/Vl\n\tTK4GXGbCHcX3AEc9NmmZpHQ6/3HujNQwOjynNzsnJF/aepI9B7dl1Zp+ALOEYSE1J2tF\n\tuJcQ==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=Xj/mIFBwOUaGUcNu8yackrW21gg3ew3bmgpzWscYFA8=;\n\tb=XLgRIxWdooiYWlK+x8pyAzpsPUH0N6fL2tZMReOseWpKjFFt/B5c5nOwZOG9kSQCko\n\tLgxpUP4IQKBKCW0FaHoY+uF7JOwlYRmi/rGm81WnBdRSxqbyO0Fe+kUsFqG4EMi6z68R\n\tPXwgLaZEAY/8BbN+34nI2ePhKbgubqgxSxMlh4+viT/UhrnfP9Otl0WGmC+faJL9l4BX\n\tEl2Z5Bx2gzvmJv19Nv6BxDlzU9pEHLzY4DqTy6bmT8kSXDyE0Fl/H4wd4OW2owQX6QiD\n\tK7WC90IcEfRO2AITe9cAwFcJDvq2hRW7YnqGiDikI5ag4pYT6iIsJnSVNTDl4LCPx6Qy\n\tc6MA==",
        "X-Gm-Message-State": "AOAM532RgjK1hR35JYvlIgtYV7Yi1CJVoaH/PethlXhiBZEzXKdR4BZc\n\t9zFssw+TKCGgh/FOw4zUSsd0tcvqAv+oCkbD",
        "X-Google-Smtp-Source": "ABdhPJyR5mSrU7FJgc22jTzRcwApcN1aA4qND0+vGJd3QRsMFnDVNC91Acl0KH7uez8R4c/D8NDhpw==",
        "X-Received": "by 2002:a5d:6452:: with SMTP id\n\td18mr29174412wrw.200.1606117116505; \n\tSun, 22 Nov 2020 23:38:36 -0800 (PST)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 23 Nov 2020 07:38:01 +0000",
        "Message-Id": "<20201123073804.3125-8-david.plowman@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.20.1",
        "In-Reply-To": "<20201123073804.3125-1-david.plowman@raspberrypi.com>",
        "References": "<20201123073804.3125-1-david.plowman@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH v2 07/10] libcamera: ipa: raspberrypi:\n\tagc: Report fixed exposure/gain values during SwitchMode",
        "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>",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "When an application has specified fixed exposure time and/or gain they\nmust be programmed into the sensor immediately, even before the sensor\nhas been started. For this to happen they must be written into the\nimage metadata when the SwitchMode method is invoked.\n\nWe also make the default exposure/gain, when nothing has been set,\ncustomisable in the tuning file.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n---\n src/ipa/raspberrypi/controller/rpi/agc.cpp | 74 +++++++++++++++++-----\n src/ipa/raspberrypi/controller/rpi/agc.hpp |  2 +\n 2 files changed, 60 insertions(+), 16 deletions(-)",
    "diff": "diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp\nindex 4cf98e66..2533727e 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n@@ -145,6 +145,9 @@ void AgcConfig::Read(boost::property_tree::ptree const &params)\n \tfast_reduce_threshold =\n \t\tparams.get<double>(\"fast_reduce_threshold\", 0.4);\n \tbase_ev = params.get<double>(\"base_ev\", 1.0);\n+\t// Start with quite a low value as ramping up is easier than ramping down.\n+\tdefault_exposure_time = params.get<double>(\"default_exposure_time\", 1000);\n+\tdefault_analogue_gain = params.get<double>(\"default_analogue_gain\", 1.0);\n }\n \n Agc::Agc(Controller *controller)\n@@ -220,14 +223,42 @@ void Agc::SetConstraintMode(std::string const &constraint_mode_name)\n void Agc::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,\n \t\t     Metadata *metadata)\n {\n-\t// On a mode switch, it's possible the exposure profile could change,\n-\t// so we run through the dividing up of exposure/gain again and\n-\t// write the results into the metadata we've been given.\n-\tif (status_.total_exposure_value) {\n-\t\thousekeepConfig();\n+\thousekeepConfig();\n+\n+\tif (fixed_shutter_ != 0.0 && fixed_analogue_gain_ != 0.0) {\n+\t\t// We're going to reset the algorithm here with these fixed values.\n+\n+\t\tfetchAwbStatus(metadata);\n+\t\tdouble min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });\n+\t\tASSERT(min_colour_gain != 0.0);\n+\n+\t\t// This is the equivalent of computeTargetExposure and applyDigitalGain.\n+\t\ttarget_.total_exposure_no_dg = fixed_shutter_ * fixed_analogue_gain_;\n+\t\ttarget_.total_exposure = target_.total_exposure_no_dg / min_colour_gain;\n+\n+\t\t// Equivalent of filterExposure. This resets any \"history\".\n+\t\tfiltered_ = target_;\n+\n+\t\t// Equivalent of divideUpExposure.\n+\t\tfiltered_.shutter = fixed_shutter_;\n+\t\tfiltered_.analogue_gain = fixed_analogue_gain_;\n+\t} else if (status_.total_exposure_value) {\n+\t\t// On a mode switch, it's possible the exposure profile could change,\n+\t\t// or a fixed exposure/gain might be set so we divide up the exposure/\n+\t\t// gain again, but we don't change any target values.\n \t\tdivideUpExposure();\n-\t\twriteAndFinish(metadata, false);\n+\t} else {\n+\t\t// We come through here on startup, when at least one of the shutter\n+\t\t// or gain has not been fixed. We must still write those values out so\n+\t\t// that they will be applied immediately. We supply some arbitrary defaults\n+\t\t// for any that weren't set.\n+\n+\t\t// Equivalent of divideUpExposure.\n+\t\tfiltered_.shutter = fixed_shutter_ ? fixed_shutter_ : config_.default_exposure_time;\n+\t\tfiltered_.analogue_gain = fixed_analogue_gain_ ? fixed_analogue_gain_ : config_.default_analogue_gain;\n \t}\n+\n+\twriteAndFinish(metadata, false);\n }\n \n void Agc::Prepare(Metadata *image_metadata)\n@@ -472,20 +503,31 @@ void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *image_metadata,\n \n void Agc::computeTargetExposure(double gain)\n {\n-\t// The statistics reflect the image without digital gain, so the final\n-\t// total exposure we're aiming for is:\n-\ttarget_.total_exposure = current_.total_exposure_no_dg * gain;\n-\t// The final target exposure is also limited to what the exposure\n-\t// mode allows.\n-\tdouble max_total_exposure =\n-\t\t(status_.fixed_shutter != 0.0\n+\tif (status_.fixed_shutter != 0.0 && status_.fixed_analogue_gain != 0.0) {\n+\t\t// When ag and shutter are both fixed, we need to drive the\n+\t\t// total exposure so that we end up with a digital gain of at least\n+\t\t// 1/min_colour_gain. Otherwise we'd desaturate channels causing\n+\t\t// white to go cyan or magenta.\n+\t\tdouble min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });\n+\t\tASSERT(min_colour_gain != 0.0);\n+\t\ttarget_.total_exposure =\n+\t\t\tstatus_.fixed_shutter * status_.fixed_analogue_gain / min_colour_gain;\n+\t} else {\n+\t\t// The statistics reflect the image without digital gain, so the final\n+\t\t// total exposure we're aiming for is:\n+\t\ttarget_.total_exposure = current_.total_exposure_no_dg * gain;\n+\t\t// The final target exposure is also limited to what the exposure\n+\t\t// mode allows.\n+\t\tdouble max_total_exposure =\n+\t\t\t(status_.fixed_shutter != 0.0\n \t\t\t ? status_.fixed_shutter\n \t\t\t : exposure_mode_->shutter.back()) *\n-\t\t(status_.fixed_analogue_gain != 0.0\n+\t\t\t(status_.fixed_analogue_gain != 0.0\n \t\t\t ? status_.fixed_analogue_gain\n \t\t\t : exposure_mode_->gain.back());\n-\ttarget_.total_exposure = std::min(target_.total_exposure,\n-\t\t\t\t\t  max_total_exposure);\n+\t\ttarget_.total_exposure = std::min(target_.total_exposure,\n+\t\t\t\t\t\t  max_total_exposure);\n+\t}\n \tLOG(RPiAgc, Debug) << \"Target total_exposure \" << target_.total_exposure;\n }\n \ndiff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp\nindex e7ac480f..859a9650 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp\n@@ -60,6 +60,8 @@ struct AgcConfig {\n \tstd::string default_exposure_mode;\n \tstd::string default_constraint_mode;\n \tdouble base_ev;\n+\tdouble default_exposure_time;\n+\tdouble default_analogue_gain;\n };\n \n class Agc : public AgcAlgorithm\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "07/10"
    ]
}