Show a patch.

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

{
    "id": 10434,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/10434/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10434/",
    "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": "<20201116164918.2055-6-david.plowman@raspberrypi.com>",
    "date": "2020-11-16T16:49:13",
    "name": "[libcamera-devel,05/10] libcamera: ipa: raspberrypi: agc: Fetch AWB status only once",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "f5ec372d270f7333281573413792bce41a9d523b",
    "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/10434/mbox/",
    "series": [
        {
            "id": 1464,
            "url": "https://patchwork.libcamera.org/api/1.1/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/10434/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10434/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 D0303BE082\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Nov 2020 16:49:32 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9EF39632DE;\n\tMon, 16 Nov 2020 17:49:32 +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 A6668632D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Nov 2020 17:49:29 +0100 (CET)",
            "by mail-wr1-x436.google.com with SMTP id j7so19410086wrp.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Nov 2020 08:49:29 -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.28\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 16 Nov 2020 08:49:28 -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=\"NidqvYhV\"; 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=3jOTqsdM+5vSReHOduxhhHeWX+jcNQzjs9vGsaKAjj8=;\n\tb=NidqvYhVeTQ16nbibmCfTfc8gH3CR+macAriZ0dsfCosr1dbDfzlnANSHKhtRb9x5q\n\tQqrSpX6WtBeVHbujcaasWrU9EF9a7v2CZM1HzTdAixVGHo9gRdyIUvAaW1bcjxqf2+Mw\n\t8sJfec3CWnfcABuD3SAWA/NLbBmzLPjB4NevLeD5DUyD89olhpmdRLkYmtfaDtVdwqpu\n\tw1mx6LeLpzsgXP3mScAnLLH6kb5KAjAArTUA4axdXehE5EEg7g3kD6FCbJxI6PGsWF5P\n\tFb344FX/E9sKwe9LFkeod99pnB94y12q/RsB26O1QrOb3gCKpHAWRZWVg4/KP8/byIM2\n\tKIcw==",
        "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=3jOTqsdM+5vSReHOduxhhHeWX+jcNQzjs9vGsaKAjj8=;\n\tb=PRIOU44nijD2JKVoG/3WvKwDc2k1FLXbpFEufoSArf6LnsQU0xfZPibdfFz1XYUnF0\n\tUUa92j6N/dVI/Js7NancrqfjMhNlqb5UXixu+XPDg5Rzk2vjBCndAyCGBonSH+GRo0QF\n\thDqewKXf33gL9Atodft3mTdHhDpGkKEuPNQjE+caacSBaZcKg/56afbcquRqyeESIute\n\tgwU53xOHbTNvOJz0GFN6U052WiyVgfuvvJ28l45bDzIEnJQTRf8g1Tw0xqMibBYxM1qE\n\thqWdrFHXKs956hoA0od9pAZc1ynwUwGo/+LNQn0YOt7FQFCKqz4ME5wr2cLcxc/ujkAq\n\tGVMw==",
        "X-Gm-Message-State": "AOAM533ybtmjC6XXZRn3/xtgdjPt0OTNiWQ1Opk1mBoUw7dUrGYtbSDE\n\tvGFAJAWDnTxS+OpFCVPT+FVvTP4rpeYD3w==",
        "X-Google-Smtp-Source": "ABdhPJwA/o677mH523dHvj34Pah/tT3vRGIqXOvqVLXQj6UMJghFfsr7uWFGGCC+dYOBaD2uZkIpCQ==",
        "X-Received": "by 2002:adf:e88b:: with SMTP id d11mr19378694wrm.4.1605545369068;\n\tMon, 16 Nov 2020 08:49:29 -0800 (PST)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon, 16 Nov 2020 16:49:13 +0000",
        "Message-Id": "<20201116164918.2055-6-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 05/10] libcamera: ipa: raspberrypi: agc:\n\tFetch 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>\n---\n src/ipa/raspberrypi/controller/rpi/agc.cpp | 37 ++++++++++++----------\n src/ipa/raspberrypi/controller/rpi/agc.hpp |  5 +--\n 2 files changed, 23 insertions(+), 19 deletions(-)",
    "diff": "diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp\nindex ead28398..6de56def 100644\n--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n@@ -5,6 +5,8 @@\n  * agc.cpp - AGC/AEC control algorithm\n  */\n \n+#include <assert.h>\n+\n #include <map>\n \n #include \"linux/bcm2835-isp.h\"\n@@ -235,6 +237,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@@ -301,7 +305,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@@ -378,14 +382,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@@ -437,7 +446,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@@ -483,19 +492,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",
        "05/10"
    ]
}