Show a patch.

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

{
    "id": 10464,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/10464/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10464/",
    "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-6-david.plowman@raspberrypi.com>",
    "date": "2020-11-23T07:37:59",
    "name": "[libcamera-devel,v2,05/10] libcamera: ipa: raspberrypi: agc: Fetch AWB status only once",
    "commit_ref": "f185a168335edaebb5f661070d579b819bbc4ad2",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "0d88ba24ba5d763a8da64eca50e0503539423fb5",
    "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/10464/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/10464/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10464/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 E0683BE08A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 23 Nov 2020 07:38:37 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 91BFC632EE;\n\tMon, 23 Nov 2020 08:38:37 +0100 (CET)",
            "from mail-wr1-x434.google.com (mail-wr1-x434.google.com\n\t[IPv6:2a00:1450:4864:20::434])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 230C760332\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 23 Nov 2020 08:38:35 +0100 (CET)",
            "by mail-wr1-x434.google.com with SMTP id l1so17534141wrb.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 22 Nov 2020 23:38:35 -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.33\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSun, 22 Nov 2020 23:38:34 -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=\"GSQ6mQRn\"; 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=V8Nsaokvnt+3p3VR7LiNfq4cMjAbzSycTM1hXK3GrGw=;\n\tb=GSQ6mQRncupg35/N1SMZdUxl0Dtl1n5vsMLy2Kw8sPspXOc/MK16OlUWrkzcwN4hBw\n\txeGNntViTck3j+ENpyuEe12cEwVTJTZpJCYKw7dwLYnJsNW/aRboi2WcBAKc8eVDTRPQ\n\t1HJOkv9qEyPoqh9KEotPwH45PYo3U2q9d/o1lkrHYo56BrrjWRC743ihWssLWKJJZmZf\n\tSMvoCpXY6EBu3WOZtXmAfyoH+cB35111uUxQOMVZ771x7ZD9v0YGIl1t9AokO3aV2OfH\n\tY3yvsOjgLELqGNb3p8V9qAYIqiIO8RE1hC6tmxgB98P4nTMThztrd3HQFidKa5ODj+Q+\n\tO/YQ==",
        "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=V8Nsaokvnt+3p3VR7LiNfq4cMjAbzSycTM1hXK3GrGw=;\n\tb=W2S6rDJHwLwn49hQC0ccg/h87HwLMGNnIfa79psyPajvXCBfnCe023MbCvZ/6Nk9Mb\n\tdkAOQUo+jbJP4OpbfKuh8pHot89n/D3/brC/pA4oAqr+2dYGUCn1wPIDPQ5p7Ra75PMv\n\tYlfJo79o3iLarLgM7viYKf89k0jSFUXsjNOAPZTQe8045PFD4KnOUKHPhZWrJS1YSyLq\n\toaoZQjefUSpG00+eZvISvZTYo1JPfnk73ajiwkjALYJ81EBROtxRZgjfef3PWMBIMChL\n\tAtnz7r6zWx0FLd6cxkhVrF/YmFjFsGLVzwoOw9wDtuvV1mUK4e5PDApCYjq8CXKpuOR1\n\tUsoA==",
        "X-Gm-Message-State": "AOAM533fTB3B1+Pkt5kq7R4dH6kgJI1bQ8Hg+Tn6UWFgLCMG3udkGsIY\n\tNoKtiR5SeyCfJU12yJczYpejh4CIrGjIog26",
        "X-Google-Smtp-Source": "ABdhPJwjXCMsbm0hPZwqQLY5NgPXcOY3OFyNdvm7Vhw0hCmN3CLVTkF6EpwbTSLSw+T0Lg0B0rIhXA==",
        "X-Received": "by 2002:a5d:69d1:: with SMTP id\n\ts17mr30048175wrw.104.1606117114547; \n\tSun, 22 Nov 2020 23:38:34 -0800 (PST)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 23 Nov 2020 07:37:59 +0000",
        "Message-Id": "<20201123073804.3125-6-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 05/10] libcamera: ipa: raspberrypi:\n\tagc: Fetch AWB status only once",
        "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": "Introduce a function to fetch the AwbStatus (fetchAwbStatus), and call\nit unconditionally at the top of Prepare so that both Prepare and\nProcess know thereafter that it's been done.\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 | 35 +++++++++++-----------\n src/ipa/raspberrypi/controller/rpi/agc.hpp |  5 ++--\n 2 files changed, 21 insertions(+), 19 deletions(-)",
    "diff": "diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp\nindex f0c70a0a..4cf98e66 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n@@ -235,6 +235,8 @@ void Agc::Prepare(Metadata *image_metadata)\n \tint lock_count = lock_count_;\n \tlock_count_ = 0;\n \tstatus_.digital_gain = 1.0;\n+\tfetchAwbStatus(image_metadata); // always fetch it so that Process knows it's been done\n+\n \tif (status_.total_exposure_value) {\n \t\t// Process has run, so we have meaningful values.\n \t\tDeviceStatus device_status;\n@@ -300,7 +302,7 @@ void Agc::Process(StatisticsPtr &stats, Metadata *image_metadata)\n \t// Some of the exposure has to be applied as digital gain, so work out\n \t// what that is. This function also tells us whether it's decided to\n \t// \"desaturate\" the image more quickly.\n-\tbool desaturate = applyDigitalGain(image_metadata, gain, target_Y);\n+\tbool desaturate = applyDigitalGain(gain, target_Y);\n \t// The results have to be filtered so as not to change too rapidly.\n \tfilterExposure(desaturate);\n \t// The last thing is to divide up the exposure value into a shutter time\n@@ -377,14 +379,19 @@ void Agc::fetchCurrentExposure(Metadata *image_metadata)\n \tcurrent_.total_exposure_no_dg = current_.shutter * current_.analogue_gain;\n }\n \n-static double compute_initial_Y(bcm2835_isp_stats *stats, Metadata *image_metadata,\n+void Agc::fetchAwbStatus(Metadata *image_metadata)\n+{\n+\tawb_.gain_r = 1.0; // in case not found in metadata\n+\tawb_.gain_g = 1.0;\n+\tawb_.gain_b = 1.0;\n+\tif (image_metadata->Get(\"awb.status\", awb_) != 0)\n+\t\tLOG(RPiAgc, Warning) << \"Agc: no AWB status found\";\n+}\n+\n+static double compute_initial_Y(bcm2835_isp_stats *stats, AwbStatus const &awb,\n \t\t\t\tdouble weights[])\n {\n \tbcm2835_isp_stats_region *regions = stats->agc_stats;\n-\tstruct AwbStatus awb;\n-\tawb.gain_r = awb.gain_g = awb.gain_b = 1.0; // in case no metadata\n-\tif (image_metadata->Get(\"awb.status\", awb) != 0)\n-\t\tLOG(RPiAgc, Warning) << \"Agc: no AWB status found\";\n \t// Note how the calculation below means that equal weights give you\n \t// \"average\" metering (i.e. all pixels equally important).\n \tdouble R_sum = 0, G_sum = 0, B_sum = 0, pixel_sum = 0;\n@@ -436,7 +443,7 @@ void Agc::computeGain(bcm2835_isp_stats *statistics, Metadata *image_metadata,\n \ttarget_Y =\n \t\tconfig_.Y_target.Eval(config_.Y_target.Domain().Clip(lux.lux));\n \ttarget_Y = std::min(EV_GAIN_Y_TARGET_LIMIT, target_Y * ev_gain);\n-\tdouble initial_Y = compute_initial_Y(statistics, image_metadata,\n+\tdouble initial_Y = compute_initial_Y(statistics, awb_,\n \t\t\t\t\t     metering_mode_->weights);\n \tgain = std::min(10.0, target_Y / (initial_Y + .001));\n \tLOG(RPiAgc, Debug) << \"Initially Y \" << initial_Y << \" target \" << target_Y\n@@ -482,19 +489,13 @@ void Agc::computeTargetExposure(double gain)\n \tLOG(RPiAgc, Debug) << \"Target total_exposure \" << target_.total_exposure;\n }\n \n-bool Agc::applyDigitalGain(Metadata *image_metadata, double gain,\n-\t\t\t   double target_Y)\n+bool Agc::applyDigitalGain(double gain, double target_Y)\n {\n-\tdouble dg = 1.0;\n+\tdouble min_colour_gain = std::min({ awb_.gain_r, awb_.gain_g, awb_.gain_b, 1.0 });\n+\tASSERT(min_colour_gain != 0.0);\n+\tdouble dg = 1.0 / min_colour_gain;\n \t// I think this pipeline subtracts black level and rescales before we\n \t// get the stats, so no need to worry about it.\n-\tstruct AwbStatus awb;\n-\tif (image_metadata->Get(\"awb.status\", awb) == 0) {\n-\t\tdouble min_gain = std::min(awb.gain_r,\n-\t\t\t\t\t   std::min(awb.gain_g, awb.gain_b));\n-\t\tdg *= std::max(1.0, 1.0 / min_gain);\n-\t} else\n-\t\tLOG(RPiAgc, Warning) << \"Agc: no AWB status found\";\n \tLOG(RPiAgc, Debug) << \"after AWB, target dg \" << dg << \" gain \" << gain\n \t\t\t   << \" target_Y \" << target_Y;\n \t// Finally, if we're trying to reduce exposure but the target_Y is\ndiff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp\nindex 2442fc03..e7ac480f 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp\n@@ -83,11 +83,11 @@ private:\n \tAgcConfig config_;\n \tvoid housekeepConfig();\n \tvoid fetchCurrentExposure(Metadata *image_metadata);\n+\tvoid fetchAwbStatus(Metadata *image_metadata);\n \tvoid computeGain(bcm2835_isp_stats *statistics, Metadata *image_metadata,\n \t\t\t double &gain, double &target_Y);\n \tvoid computeTargetExposure(double gain);\n-\tbool applyDigitalGain(Metadata *image_metadata, double gain,\n-\t\t\t      double target_Y);\n+\tbool applyDigitalGain(double gain, double target_Y);\n \tvoid filterExposure(bool desaturate);\n \tvoid divideUpExposure();\n \tvoid writeAndFinish(Metadata *image_metadata, bool desaturate);\n@@ -95,6 +95,7 @@ private:\n \tAgcExposureMode *exposure_mode_;\n \tAgcConstraintMode *constraint_mode_;\n \tuint64_t frame_count_;\n+\tAwbStatus awb_;\n \tstruct ExposureValues {\n \t\tExposureValues() : shutter(0), analogue_gain(0),\n \t\t\t\t   total_exposure(0), total_exposure_no_dg(0) {}\n",
    "prefixes": [
        "libcamera-devel",
        "v2",
        "05/10"
    ]
}