[{"id":13738,"web_url":"https://patchwork.libcamera.org/comment/13738/","msgid":"<CAEmqJPq4QY6Vh6yp4aBtj8LERZwSPCXXXTxN0z5f=3OoCmEJUQ@mail.gmail.com>","date":"2020-11-17T10:56:25","subject":"Re: [libcamera-devel] [PATCH 07/10] libcamera: ipa: raspberrypi:\n\tagc: Report fixed exposure/gain values during SwitchMode","submitter":{"id":34,"url":"https://patchwork.libcamera.org/api/people/34/","name":"Naushir Patuck","email":"naush@raspberrypi.com"},"content":"Hi David,\n\nOn Mon, 16 Nov 2020 at 16:49, David Plowman <david.plowman@raspberrypi.com>\nwrote:\n\n> When an application has specified fixed exposure time and/or gain they\n> must be programmed into the sensor immediately, even before the sensor\n> has been started. For this to happen they must be written into the\n> image metadata when the SwitchMode method is invoked.\n>\n> We also make the default exposure/gain, when nothing has been set,\n> customisable in the tuning file.\n>\n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n>\n\nReviewed-by: Naushir Patuck <naush@raspberrypi.com>\n\n\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(-)\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> b/src/ipa/raspberrypi/controller/rpi/agc.cpp\n> index 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\n> &params)\n>         fast_reduce_threshold =\n>                 params.get<double>(\"fast_reduce_threshold\", 0.4);\n>         base_ev = params.get<double>(\"base_ev\", 1.0);\n> +       // Start with quite a low value as ramping up is easier than\n> ramping down.\n> +       default_exposure_time =\n> params.get<double>(\"default_exposure_time\", 1000);\n> +       default_analogue_gain =\n> 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\n> &constraint_mode_name)\n>  void Agc::SwitchMode([[maybe_unused]] CameraMode const &camera_mode,\n>                      Metadata *metadata)\n>  {\n> -       // On a mode switch, it's possible the exposure profile could\n> change,\n> -       // so we run through the dividing up of exposure/gain again and\n> -       // write the results into the metadata we've been given.\n> -       if (status_.total_exposure_value) {\n> -               housekeepConfig();\n> +       housekeepConfig();\n> +\n> +       if (fixed_shutter_ != 0.0 && fixed_analogue_gain_ != 0.0) {\n> +               // We're going to reset the algorithm here with these\n> fixed values.\n> +\n> +               fetchAwbStatus(metadata);\n> +               double min_colour_gain = std::min({ awb_.gain_r,\n> awb_.gain_g, awb_.gain_b, 1.0 });\n> +               assert(min_colour_gain != 0.0);\n> +\n> +               // This is the equivalent of computeTargetExposure and\n> applyDigitalGain.\n> +               target_.total_exposure_no_dg = fixed_shutter_ *\n> fixed_analogue_gain_;\n> +               target_.total_exposure = target_.total_exposure_no_dg /\n> min_colour_gain;\n> +\n> +               // Equivalent of filterExposure. This resets any \"history\".\n> +               filtered_ = target_;\n> +\n> +               // Equivalent of divideUpExposure.\n> +               filtered_.shutter = fixed_shutter_;\n> +               filtered_.analogue_gain = fixed_analogue_gain_;\n> +       } else if (status_.total_exposure_value) {\n> +               // On a mode switch, it's possible the exposure profile\n> could change,\n> +               // or a fixed exposure/gain might be set so we divide up\n> the exposure/\n> +               // gain again, but we don't change any target values.\n>                 divideUpExposure();\n> -               writeAndFinish(metadata, false);\n> +       } else {\n> +               // We come through here on startup, when at least one of\n> the shutter\n> +               // or gain has not been fixed. We must still write those\n> values out so\n> +               // that they will be applied immediately. We supply some\n> arbitrary defaults\n> +               // for any that weren't set.\n> +\n> +               // Equivalent of divideUpExposure.\n> +               filtered_.shutter = fixed_shutter_ ? fixed_shutter_ :\n> config_.default_exposure_time;\n> +               filtered_.analogue_gain = fixed_analogue_gain_ ?\n> fixed_analogue_gain_ : config_.default_analogue_gain;\n>         }\n> +\n> +       writeAndFinish(metadata, false);\n>  }\n>\n>  void Agc::Prepare(Metadata *image_metadata)\n> @@ -475,20 +506,31 @@ void Agc::computeGain(bcm2835_isp_stats *statistics,\n> Metadata *image_metadata,\n>\n>  void Agc::computeTargetExposure(double gain)\n>  {\n> -       // The statistics reflect the image without digital gain, so the\n> final\n> -       // total exposure we're aiming for is:\n> -       target_.total_exposure = current_.total_exposure_no_dg * gain;\n> -       // The final target exposure is also limited to what the exposure\n> -       // mode allows.\n> -       double max_total_exposure =\n> -               (status_.fixed_shutter != 0.0\n> +       if (status_.fixed_shutter != 0.0 && status_.fixed_analogue_gain !=\n> 0.0) {\n> +               // When ag and shutter are both fixed, we need to drive the\n> +               // total exposure so that we end up with a digital gain of\n> at least\n> +               // 1/min_colour_gain. Otherwise we'd desaturate channels\n> causing\n> +               // white to go cyan or magenta.\n> +               double min_colour_gain = std::min({ awb_.gain_r,\n> awb_.gain_g, awb_.gain_b, 1.0 });\n> +               assert(min_colour_gain != 0.0);\n> +               target_.total_exposure =\n> +                       status_.fixed_shutter *\n> status_.fixed_analogue_gain / min_colour_gain;\n> +       } else {\n> +               // The statistics reflect the image without digital gain,\n> so the final\n> +               // total exposure we're aiming for is:\n> +               target_.total_exposure = current_.total_exposure_no_dg *\n> gain;\n> +               // The final target exposure is also limited to what the\n> exposure\n> +               // mode allows.\n> +               double max_total_exposure =\n> +                       (status_.fixed_shutter != 0.0\n>                          ? status_.fixed_shutter\n>                          : exposure_mode_->shutter.back()) *\n> -               (status_.fixed_analogue_gain != 0.0\n> +                       (status_.fixed_analogue_gain != 0.0\n>                          ? status_.fixed_analogue_gain\n>                          : exposure_mode_->gain.back());\n> -       target_.total_exposure = std::min(target_.total_exposure,\n> -                                         max_total_exposure);\n> +               target_.total_exposure = std::min(target_.total_exposure,\n> +                                                 max_total_exposure);\n> +       }\n>         LOG(RPiAgc, Debug) << \"Target total_exposure \" <<\n> target_.total_exposure;\n>  }\n>\n> diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp\n> b/src/ipa/raspberrypi/controller/rpi/agc.hpp\n> index 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>         std::string default_exposure_mode;\n>         std::string default_constraint_mode;\n>         double base_ev;\n> +       double default_exposure_time;\n> +       double default_analogue_gain;\n>  };\n>\n>  class Agc : public AgcAlgorithm\n> --\n> 2.20.1\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel\n>","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 41C02BE081\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 17 Nov 2020 10:56:44 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A93996332A;\n\tTue, 17 Nov 2020 11:56:43 +0100 (CET)","from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com\n\t[IPv6:2a00:1450:4864:20::12a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6DDB763320\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 17 Nov 2020 11:56:42 +0100 (CET)","by mail-lf1-x12a.google.com with SMTP id u18so29442873lfd.9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 17 Nov 2020 02:56:42 -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=\"tm4DmBxn\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=lF52hU/deN7Ve5HiL1ayQbxQ55fKsrePcSLKpNrfXIE=;\n\tb=tm4DmBxn3/0QP57J+WJPwywec9pOYSKtgH7IQjPSzIDpjYYmO4U0q7S6CCNJ0z7Wo1\n\tA7ttwNFU/gw61AJSaHmWIt4fqnNeVM+YA2t8ebqftol7AQkqNe5ihzgGYhRnAW4Uw5tb\n\t5WoX/5OoKe8FSbN0MT/PZ9u1l2c9Opy2JVoR396IrHczvQbqiqgY8aW+ptaN1oNcTOnp\n\tBFtlQA1j1fIWKistqWVTs7cZQ+z/JLseaPEYP47YOz+hhP32L8HdvnCLVXPPjY4Vmm54\n\tVYghfBi5OqwfD7qbUYQqgmLzZ3y6pp88HsSDSE8iOIU1vUC4nQFp0s6mMBpQCLe2LDUl\n\trlTQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=lF52hU/deN7Ve5HiL1ayQbxQ55fKsrePcSLKpNrfXIE=;\n\tb=YD/tS2pyjXVAuwcCGpuOSo7mThVOafKirs4AcCyAXJH9EZ4kjkT8N4QwbgeeFMhSHe\n\taC+VDDMpX/3N0yeGtt7+AFT/5kBNuYLITNqnjqhDVZm3clXUVmNpQQrrSyua4Xv5vlP7\n\t4Kq1Re6xrSC5AaUYPilsILg2WowGUseJGGJcs1lXDyCExZPuz/B3PU7J6ElZH9gYemqL\n\tawXYJ4pKxbdMospdN8xuENFvh9H9xmfJXHgaiLiaL8tQaEC5/4goxMH4PvFDvMGBNZCs\n\t9byX+tNc8naitr+2ynjIARjTkJVrfas2gaimwExoMmjmxLOYUdTpfGddylQMuED6gvej\n\tbkSA==","X-Gm-Message-State":"AOAM530Aih41jE3lcws7A+BaNP0m6oe6fNm+K3dirDWmtf+iw6A+sHuj\n\tWd+G01V9q3ZBc2VAvr5dnaJAyZ/q16L/hRK6XTn1+Q==","X-Google-Smtp-Source":"ABdhPJw4h1CkTnV6qBqqZ5qt9A2AYdaet4aed+sgtclKPVDxX7gm/rgxKvTjnLLtAtUzmrshSJ2nbRIndF7vXtWkTBk=","X-Received":"by 2002:a19:a415:: with SMTP id\n\tq21mr1436439lfc.508.1605610601845; \n\tTue, 17 Nov 2020 02:56:41 -0800 (PST)","MIME-Version":"1.0","References":"<20201116164918.2055-1-david.plowman@raspberrypi.com>\n\t<20201116164918.2055-8-david.plowman@raspberrypi.com>","In-Reply-To":"<20201116164918.2055-8-david.plowman@raspberrypi.com>","From":"Naushir Patuck <naush@raspberrypi.com>","Date":"Tue, 17 Nov 2020 10:56:25 +0000","Message-ID":"<CAEmqJPq4QY6Vh6yp4aBtj8LERZwSPCXXXTxN0z5f=3OoCmEJUQ@mail.gmail.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH 07/10] libcamera: ipa: raspberrypi:\n\tagc: Report 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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"multipart/mixed;\n\tboundary=\"===============7830387212149499035==\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]