Patch Detail
Show a patch.
GET /api/patches/10464/?format=api
{ "id": 10464, "url": "https://patchwork.libcamera.org/api/patches/10464/?format=api", "web_url": "https://patchwork.libcamera.org/patch/10464/", "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": "<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/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/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" ] }