Patch Detail
Show a patch.
GET /api/1.1/patches/10434/?format=api
{ "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" ] }