Show a patch.

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

{
    "id": 10436,
    "url": "https://patchwork.libcamera.org/api/patches/10436/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10436/",
    "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": "<20201116164918.2055-8-david.plowman@raspberrypi.com>",
    "date": "2020-11-16T16:49:15",
    "name": "[libcamera-devel,07/10] libcamera: ipa: raspberrypi: agc: Report fixed exposure/gain values during SwitchMode",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "3e55a59c434d86d94064c576e85c2aa9ea89460f",
    "submitter": {
        "id": 42,
        "url": "https://patchwork.libcamera.org/api/people/42/?format=api",
        "name": "David Plowman",
        "email": "david.plowman@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/10436/mbox/",
    "series": [
        {
            "id": 1464,
            "url": "https://patchwork.libcamera.org/api/series/1464/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1464",
            "date": "2020-11-16T16:49:08",
            "name": "Raspberry Pi AGC",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/1464/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/10436/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10436/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 9A5A1BE088\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Nov 2020 16:49:33 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 645FF632DC;\n\tMon, 16 Nov 2020 17:49:33 +0100 (CET)",
            "from mail-wr1-x431.google.com (mail-wr1-x431.google.com\n\t[IPv6:2a00:1450:4864:20::431])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9A2A8632C8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Nov 2020 17:49:31 +0100 (CET)",
            "by mail-wr1-x431.google.com with SMTP id p1so19376533wrf.12\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Nov 2020 08:49:31 -0800 (PST)",
            "from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\tq16sm23716973wrn.13.2020.11.16.08.49.30\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 16 Nov 2020 08:49:30 -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=\"kCOeB65J\"; 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=pV5Y4BC+e5WO5rCf4cwaFUFTslXt0uT26nNKHvbbNQI=;\n\tb=kCOeB65Jt5AOO+LZ9MqXg2LBwzbt9vz4MJPnrD38qKvuYUsXoOM0reyPFeegtXuFcV\n\t53KYf0eC4fguVS9+B/+/VJSFtRxp24xDso2Pj3BWRjDnbsHJ3fLCP6Ej+L8tXIbEUFGX\n\trzZSdhLKAVdKLymt4tAx3sQbixv5sbhZlzO61JksF/hevYfosLDD25tMaIlAdiGX6TLj\n\th9HIBYD39vPoN0irBvU1OCZDzVYl+9Q9OLim8AI5gy6ao+2zsyMaGNK5JRK0sRy1/cYD\n\td73U7JQX3Dcp7sA6UBsIyuuMqgPaeD9vfg5Q8TK2fJBy7Fzp/Y7b4HkYjNpmLZlunvsO\n\ttWHg==",
        "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=pV5Y4BC+e5WO5rCf4cwaFUFTslXt0uT26nNKHvbbNQI=;\n\tb=M0azA8AOhtRzIjLjjv02lBisJBzcb5J93FiU7I+YkXt9nnWC0woxd6jpqarHVsi9V2\n\tKzPUIGIupyCGKLe0fc6pblYggYmBTDnZDeErE/IuaLcH7g7fAZq6Ej5YjU3k0PpymiHg\n\tGQQNup593r/XdQGaciKiF7eSW+RdjYYuQx8QxM/7RuiU6HrLqXAmoetIhBZ/3thq9rL5\n\tPsqHzQUkYBtZ5jyXI7Od9Ca31XBZ2IL/uhb+6/8bCCoO5ayAa1hIZkjaR3OG0M4En7FO\n\tBXoPKWpRRmsnWc7du2KTnFTus7UCU8lBNCKIn8k1B79wwF3c7TeVtHLUizSf5qbysksx\n\t2l9Q==",
        "X-Gm-Message-State": "AOAM530nxP8Gxx18ChC6yIDIee9i3GQrf3B/1Wsy4Qhpdvx5+gmYzbFG\n\tyRW6KIt4cXTKmcov7BnNnkl3Ny9eFG9VmQ==",
        "X-Google-Smtp-Source": "ABdhPJwlewiG/ptox0APnvmUg8Uu+nc+/1b6K1zXwO8TwStwe5Q9b0y2GKxzThLURE6gjCq7TVrFXQ==",
        "X-Received": "by 2002:adf:db85:: with SMTP id\n\tu5mr20856672wri.155.1605545370919; \n\tMon, 16 Nov 2020 08:49:30 -0800 (PST)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 16 Nov 2020 16:49:15 +0000",
        "Message-Id": "<20201116164918.2055-8-david.plowman@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.20.1",
        "In-Reply-To": "<20201116164918.2055-1-david.plowman@raspberrypi.com>",
        "References": "<20201116164918.2055-1-david.plowman@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH 07/10] libcamera: ipa: raspberrypi: agc:\n\tReport 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>\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 6de56def..7c7944e8 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n@@ -147,6 +147,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@@ -222,14 +225,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@@ -475,20 +506,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",
        "07/10"
    ]
}