[{"id":31144,"web_url":"https://patchwork.libcamera.org/comment/31144/","msgid":"<172591668965.2319503.10804291449485969885@ping.linuxembedded.co.uk>","date":"2024-09-09T21:18:09","subject":"Re: [PATCH v6 16/18] libcamera: software_isp: Use DelayedControls","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Milan Zamazal (2024-09-06 13:09:25)\n> Use the standard libcamera mechanism to report the \"current\" controls\n> rather than delaying updates by counting from the last update.\n> \n> MY SPECULATION -- valid or not?:\n> A problem is that with software ISP we cannot be sure about the sensor\n> delay.  The original implementation simply skips exposure updates for 2\n> frames, which should be enough in most cases.  After this change, we\n> assume the delay being exactly 2 frames, which may or may not be\n> correct and may work with outdated values if the delay is shorter.\n> \n> This patch also prepares moving exposure+gain to an algorithm module\n> where the original delay mechanism would be a (possibly unnecessary)\n> complication.\n> \n> Resolves software ISP TODO #11 + #12.\n\nYeah, I think this is both 'right' and 'wrong'.\n\nBut the wrong parts are also wrong on the IPU3/RKISP1/Mali pipelines\ntoo. Currently - only RPi have this correct.\n\nAnd we need to fix this - but we should fix it by correctly specifying\nthe gains in the libipa camera sensor helpers...\n\nSo I think this patch is worthwhile, but I do believe could introduce a\nrisk of increasing oscillations  ... so we need to tackle this soon!\n\n\n> \n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  src/ipa/simple/soft_simple.cpp           | 16 +------------\n>  src/libcamera/pipeline/simple/simple.cpp | 18 ++++++++++++---\n>  src/libcamera/software_isp/TODO          | 29 ------------------------\n>  3 files changed, 16 insertions(+), 47 deletions(-)\n> \n> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> index f8d923c5..60310a8e 100644\n> --- a/src/ipa/simple/soft_simple.cpp\n> +++ b/src/ipa/simple/soft_simple.cpp\n> @@ -59,8 +59,7 @@ class IPASoftSimple : public ipa::soft::IPASoftInterface, public Module\n>  public:\n>         IPASoftSimple()\n>                 : params_(nullptr), stats_(nullptr),\n> -                 context_({ {}, {}, { kMaxFrameContexts } }),\n> -                 ignoreUpdates_(0)\n> +                 context_({ {}, {}, { kMaxFrameContexts } })\n>         {\n>         }\n>  \n> @@ -98,7 +97,6 @@ private:\n>         int32_t exposure_;\n>         double againMin_, againMax_, againMinStep_;\n>         double again_;\n> -       unsigned int ignoreUpdates_;\n>  };\n>  \n>  IPASoftSimple::~IPASoftSimple()\n> @@ -298,16 +296,6 @@ void IPASoftSimple::processStats(const uint32_t frame,\n>  \n>         /* \\todo Switch to the libipa/algorithm.h API someday. */\n>  \n> -       /*\n> -        * AE / AGC, use 2 frames delay to make sure that the exposure and\n> -        * the gain set have applied to the camera sensor.\n> -        * \\todo This could be handled better with DelayedControls.\n> -        */\n> -       if (ignoreUpdates_ > 0) {\n> -               --ignoreUpdates_;\n> -               return;\n> -       }\n> -\n\nWe 'could' keep the ignoreUpdates in the agc module as well until the\ncontrol delays are encoded in the sensor helpers.\n\nThat would keep the current behaviour, and move to the common framework\nfor handling the delays...\n\nBut it's probably not worth it ... unless someone sees uncomfortable\noscillations ... (before we get to a 'real' fix, and the 'real' fix is\nprobably better to spend time on)\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n\n\n>         /*\n>          * Calculate Mean Sample Value (MSV) according to formula from:\n>          * https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf\n> @@ -356,8 +344,6 @@ void IPASoftSimple::processStats(const uint32_t frame,\n>         ctrls.set(V4L2_CID_ANALOGUE_GAIN,\n>                   static_cast<int32_t>(camHelper_ ? camHelper_->gainCode(again_) : again_));\n>  \n> -       ignoreUpdates_ = 2;\n> -\n>         setSensorControls.emit(ctrls);\n>  \n>         LOG(IPASoft, Debug) << \"exposureMSV \" << exposureMSV\n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index 7e412e17..40a7b1da 100644\n> --- a/src/libcamera/pipeline/simple/simple.cpp\n> +++ b/src/libcamera/pipeline/simple/simple.cpp\n> @@ -32,6 +32,7 @@\n>  #include \"libcamera/internal/camera.h\"\n>  #include \"libcamera/internal/camera_sensor.h\"\n>  #include \"libcamera/internal/converter.h\"\n> +#include \"libcamera/internal/delayed_controls.h\"\n>  #include \"libcamera/internal/device_enumerator.h\"\n>  #include \"libcamera/internal/media_device.h\"\n>  #include \"libcamera/internal/pipeline_handler.h\"\n> @@ -278,6 +279,8 @@ public:\n>         std::vector<Configuration> configs_;\n>         std::map<PixelFormat, std::vector<const Configuration *>> formats_;\n>  \n> +       std::unique_ptr<DelayedControls> delayedCtrls_;\n> +\n>         std::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n>         std::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n>         bool useConversion_;\n> @@ -900,14 +903,13 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n>  \n>  void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)\n>  {\n> -       /* \\todo Use the DelayedControls class */\n>         swIsp_->processStats(frame, bufferId,\n> -                            sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,\n> -                                                   V4L2_CID_EXPOSURE }));\n> +                            delayedCtrls_->get(frame));\n>  }\n>  \n>  void SimpleCameraData::setSensorControls(const ControlList &sensorControls)\n>  {\n> +       delayedCtrls_->push(sensorControls);\n>         ControlList ctrls(sensorControls);\n>         sensor_->setControls(&ctrls);\n>  }\n> @@ -1288,6 +1290,16 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)\n>         if (outputCfgs.empty())\n>                 return 0;\n>  \n> +       std::unordered_map<uint32_t, DelayedControls::ControlParams> params = {\n> +               { V4L2_CID_ANALOGUE_GAIN, { 2, false } },\n> +               { V4L2_CID_EXPOSURE, { 2, false } },\n> +       };\n> +       data->delayedCtrls_ =\n> +               std::make_unique<DelayedControls>(data->sensor_->device(),\n> +                                                 params);\n> +       data->video_->frameStart.connect(data->delayedCtrls_.get(),\n> +                                        &DelayedControls::applyControls);\n> +\n>         StreamConfiguration inputCfg;\n>         inputCfg.pixelFormat = pipeConfig->captureFormat;\n>         inputCfg.size = pipeConfig->captureSize;\n> diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO\n> index 9978afc0..8eeede46 100644\n> --- a/src/libcamera/software_isp/TODO\n> +++ b/src/libcamera/software_isp/TODO\n> @@ -209,35 +209,6 @@ At some point, yes.\n>  \n>  ---\n>  \n> -11. Improve handling the sensor controls which take effect with a delay\n> -\n> -> void IPASoftSimple::processStats(const ControlList &sensorControls)\n> -> {\n> ->       ...\n> ->      /*\n> ->       * AE / AGC, use 2 frames delay to make sure that the exposure and\n> ->       * the gain set have applied to the camera sensor.\n> ->       */\n> ->      if (ignore_updates_ > 0) {\n> ->              --ignore_updates_;\n> ->              return;\n> ->      }\n> -\n> -This could be handled better with DelayedControls.\n> -\n> ----\n> -\n> -12. Use DelayedControls class in ispStatsReady()\n> -\n> -> void SimpleCameraData::ispStatsReady()\n> -> {\n> ->      swIsp_->processStats(sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,\n> ->                                                  V4L2_CID_EXPOSURE }));\n> -\n> -You should use the DelayedControls class.\n> -\n> ----\n> -\n>  13. Improve black level and colour gains application\n>  \n>  I think the black level should eventually be moved before debayering, and\n> -- \n> 2.44.1\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 80A60BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Sep 2024 21:18:15 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 20812634F7;\n\tMon,  9 Sep 2024 23:18:14 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C20AD634EB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Sep 2024 23:18:12 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 309EA827;\n\tMon,  9 Sep 2024 23:16:56 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"edIzaIQL\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1725916616;\n\tbh=XrxymoUivmrfFz5sq9O9bOnxdT3FnoKqO6WcfT6eCAA=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=edIzaIQL/fnmI0XV5lLMkN7vY6nGVQRuuMNbRSjTIkF2O5BMTdfcx95GQE+bMPhKs\n\ts1ywGB3WqIN9KjwnsOjQgswHnngAlTAPH4I/RFrTTDXsED5zkKr5igZmBuc/6JZKnt\n\tnkRVxw0v63pEaBtHplr+7TDFTa/iXigSInF/7u0U=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20240906120927.4071508-17-mzamazal@redhat.com>","References":"<20240906120927.4071508-1-mzamazal@redhat.com>\n\t<20240906120927.4071508-17-mzamazal@redhat.com>","Subject":"Re: [PATCH v6 16/18] libcamera: software_isp: Use DelayedControls","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Milan Zamazal <mzamazal@redhat.com>,\n\tUmang Jain <umang.jain@ideasonboard.com>,\n\tLaurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tDaniel Scally <dan.scally@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Date":"Mon, 09 Sep 2024 22:18:09 +0100","Message-ID":"<172591668965.2319503.10804291449485969885@ping.linuxembedded.co.uk>","User-Agent":"alot/0.10","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":31279,"web_url":"https://patchwork.libcamera.org/comment/31279/","msgid":"<87o74jlcyc.fsf@redhat.com>","date":"2024-09-19T18:23:39","subject":"Re: [PATCH v6 16/18] libcamera: software_isp: Use DelayedControls","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Kieran Bingham <kieran.bingham@ideasonboard.com> writes:\n\n> Quoting Milan Zamazal (2024-09-06 13:09:25)\n>> Use the standard libcamera mechanism to report the \"current\" controls\n>> rather than delaying updates by counting from the last update.\n>\n>> \n>> MY SPECULATION -- valid or not?:\n>> A problem is that with software ISP we cannot be sure about the sensor\n>> delay.  The original implementation simply skips exposure updates for 2\n>> frames, which should be enough in most cases.  After this change, we\n>> assume the delay being exactly 2 frames, which may or may not be\n>> correct and may work with outdated values if the delay is shorter.\n>> \n>> This patch also prepares moving exposure+gain to an algorithm module\n>> where the original delay mechanism would be a (possibly unnecessary)\n>> complication.\n>> \n>> Resolves software ISP TODO #11 + #12.\n>\n> Yeah, I think this is both 'right' and 'wrong'.\n>\n> But the wrong parts are also wrong on the IPU3/RKISP1/Mali pipelines\n> too. Currently - only RPi have this correct.\n>\n> And we need to fix this - but we should fix it by correctly specifying\n> the gains in the libipa camera sensor helpers...\n>\n> So I think this patch is worthwhile, but I do believe could introduce a\n> risk of increasing oscillations  ... so we need to tackle this soon!\n>\n>\n>> \n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  src/ipa/simple/soft_simple.cpp           | 16 +------------\n>>  src/libcamera/pipeline/simple/simple.cpp | 18 ++++++++++++---\n>>  src/libcamera/software_isp/TODO          | 29 ------------------------\n>>  3 files changed, 16 insertions(+), 47 deletions(-)\n>> \n>> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n>> index f8d923c5..60310a8e 100644\n>> --- a/src/ipa/simple/soft_simple.cpp\n>> +++ b/src/ipa/simple/soft_simple.cpp\n>> @@ -59,8 +59,7 @@ class IPASoftSimple : public ipa::soft::IPASoftInterface, public Module\n>>  public:\n>>         IPASoftSimple()\n>>                 : params_(nullptr), stats_(nullptr),\n>> -                 context_({ {}, {}, { kMaxFrameContexts } }),\n>> -                 ignoreUpdates_(0)\n>> +                 context_({ {}, {}, { kMaxFrameContexts } })\n>>         {\n>>         }\n>>  \n>> @@ -98,7 +97,6 @@ private:\n>>         int32_t exposure_;\n>>         double againMin_, againMax_, againMinStep_;\n>>         double again_;\n>> -       unsigned int ignoreUpdates_;\n>>  };\n>>  \n>>  IPASoftSimple::~IPASoftSimple()\n>> @@ -298,16 +296,6 @@ void IPASoftSimple::processStats(const uint32_t frame,\n>>  \n>>         /* \\todo Switch to the libipa/algorithm.h API someday. */\n>>  \n>> -       /*\n>> -        * AE / AGC, use 2 frames delay to make sure that the exposure and\n>> -        * the gain set have applied to the camera sensor.\n>> -        * \\todo This could be handled better with DelayedControls.\n>> -        */\n>> -       if (ignoreUpdates_ > 0) {\n>> -               --ignoreUpdates_;\n>> -               return;\n>> -       }\n>> -\n>\n> We 'could' keep the ignoreUpdates in the agc module as well until the\n> control delays are encoded in the sensor helpers.\n>\n> That would keep the current behaviour, and move to the common framework\n> for handling the delays...\n>\n> But it's probably not worth it ... unless someone sees uncomfortable\n> oscillations ... (before we get to a 'real' fix, and the 'real' fix is\n> probably better to spend time on)\n\nOK, thank you for clarification.  I agree with focusing on the real fix.\n\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>\n>\n>\n>>         /*\n>>          * Calculate Mean Sample Value (MSV) according to formula from:\n>>          * https://www.araa.asn.au/acra/acra2007/papers/paper84final.pdf\n>> @@ -356,8 +344,6 @@ void IPASoftSimple::processStats(const uint32_t frame,\n>>         ctrls.set(V4L2_CID_ANALOGUE_GAIN,\n>>                   static_cast<int32_t>(camHelper_ ? camHelper_->gainCode(again_) : again_));\n>>  \n>> -       ignoreUpdates_ = 2;\n>> -\n>>         setSensorControls.emit(ctrls);\n>>  \n>>         LOG(IPASoft, Debug) << \"exposureMSV \" << exposureMSV\n>> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n>> index 7e412e17..40a7b1da 100644\n>> --- a/src/libcamera/pipeline/simple/simple.cpp\n>> +++ b/src/libcamera/pipeline/simple/simple.cpp\n>> @@ -32,6 +32,7 @@\n>>  #include \"libcamera/internal/camera.h\"\n>>  #include \"libcamera/internal/camera_sensor.h\"\n>>  #include \"libcamera/internal/converter.h\"\n>> +#include \"libcamera/internal/delayed_controls.h\"\n>>  #include \"libcamera/internal/device_enumerator.h\"\n>>  #include \"libcamera/internal/media_device.h\"\n>>  #include \"libcamera/internal/pipeline_handler.h\"\n>> @@ -278,6 +279,8 @@ public:\n>>         std::vector<Configuration> configs_;\n>>         std::map<PixelFormat, std::vector<const Configuration *>> formats_;\n>>  \n>> +       std::unique_ptr<DelayedControls> delayedCtrls_;\n>> +\n>>         std::vector<std::unique_ptr<FrameBuffer>> conversionBuffers_;\n>>         std::queue<std::map<const Stream *, FrameBuffer *>> conversionQueue_;\n>>         bool useConversion_;\n>> @@ -900,14 +903,13 @@ void SimpleCameraData::conversionOutputDone(FrameBuffer *buffer)\n>>  \n>>  void SimpleCameraData::ispStatsReady(uint32_t frame, uint32_t bufferId)\n>>  {\n>> -       /* \\todo Use the DelayedControls class */\n>>         swIsp_->processStats(frame, bufferId,\n>> -                            sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,\n>> -                                                   V4L2_CID_EXPOSURE }));\n>> +                            delayedCtrls_->get(frame));\n>>  }\n>>  \n>>  void SimpleCameraData::setSensorControls(const ControlList &sensorControls)\n>>  {\n>> +       delayedCtrls_->push(sensorControls);\n>>         ControlList ctrls(sensorControls);\n>>         sensor_->setControls(&ctrls);\n>>  }\n>> @@ -1288,6 +1290,16 @@ int SimplePipelineHandler::configure(Camera *camera, CameraConfiguration *c)\n>>         if (outputCfgs.empty())\n>>                 return 0;\n>>  \n>> +       std::unordered_map<uint32_t, DelayedControls::ControlParams> params = {\n>> +               { V4L2_CID_ANALOGUE_GAIN, { 2, false } },\n>> +               { V4L2_CID_EXPOSURE, { 2, false } },\n>> +       };\n>> +       data->delayedCtrls_ =\n>> +               std::make_unique<DelayedControls>(data->sensor_->device(),\n>> +                                                 params);\n>> +       data->video_->frameStart.connect(data->delayedCtrls_.get(),\n>> +                                        &DelayedControls::applyControls);\n>> +\n>>         StreamConfiguration inputCfg;\n>>         inputCfg.pixelFormat = pipeConfig->captureFormat;\n>>         inputCfg.size = pipeConfig->captureSize;\n>> diff --git a/src/libcamera/software_isp/TODO b/src/libcamera/software_isp/TODO\n>> index 9978afc0..8eeede46 100644\n>> --- a/src/libcamera/software_isp/TODO\n>> +++ b/src/libcamera/software_isp/TODO\n>> @@ -209,35 +209,6 @@ At some point, yes.\n>>  \n>>  ---\n>>  \n>> -11. Improve handling the sensor controls which take effect with a delay\n>> -\n>> -> void IPASoftSimple::processStats(const ControlList &sensorControls)\n>> -> {\n>> ->       ...\n>> ->      /*\n>> ->       * AE / AGC, use 2 frames delay to make sure that the exposure and\n>> ->       * the gain set have applied to the camera sensor.\n>> ->       */\n>> ->      if (ignore_updates_ > 0) {\n>> ->              --ignore_updates_;\n>> ->              return;\n>> ->      }\n>> -\n>> -This could be handled better with DelayedControls.\n>> -\n>> ----\n>> -\n>> -12. Use DelayedControls class in ispStatsReady()\n>> -\n>> -> void SimpleCameraData::ispStatsReady()\n>> -> {\n>> ->      swIsp_->processStats(sensor_->getControls({ V4L2_CID_ANALOGUE_GAIN,\n>> ->                                                  V4L2_CID_EXPOSURE }));\n>> -\n>> -You should use the DelayedControls class.\n>> -\n>> ----\n>> -\n>>  13. Improve black level and colour gains application\n>>  \n>>  I think the black level should eventually be moved before debayering, and\n>> -- \n>> 2.44.1\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 375BEC324C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 19 Sep 2024 18:23:48 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 4EFC6634FC;\n\tThu, 19 Sep 2024 20:23:47 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C5039618E7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 19 Sep 2024 20:23:45 +0200 (CEST)","from mail-ej1-f71.google.com (mail-ej1-f71.google.com\n\t[209.85.218.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-633-WArycZ_nOPyTu69tAw_nng-1; Thu, 19 Sep 2024 14:23:43 -0400","by mail-ej1-f71.google.com with SMTP id\n\ta640c23a62f3a-a8a92ab4cdbso73789466b.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 19 Sep 2024 11:23:43 -0700 (PDT)","from nuthatch (ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-a90612e1b8asm748622966b.167.2024.09.19.11.23.40\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 19 Sep 2024 11:23:40 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"ACCJZcq2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1726770224;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=R+/SxKhLg4SMUqwcJ3WtURNi2Bo0xQ22kD4s5lMBsHw=;\n\tb=ACCJZcq2gDkeFsy1I/Ou1P/+O6qazJapM8bZO9xjBlcfTkTDFTUa6p0AQH3Dl84f3KLR+f\n\t/odh1BnhkyDiJWALBwRNixI8Y+ZBcweyx9D7PBXaYKMbnUkF+mrBXuQmSNQ1aFt6M3avTf\n\t9PqCG/uMTWEfvFWSbctfFTSZOPqFAus=","X-MC-Unique":"WArycZ_nOPyTu69tAw_nng-1","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1726770222; x=1727375022;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=R+/SxKhLg4SMUqwcJ3WtURNi2Bo0xQ22kD4s5lMBsHw=;\n\tb=MjiqAT0scSAlKskx7GuD3rki1aB357C2GnuHmFHvnVA+q6WSI91G3TWyTg/HlUvOpX\n\tFzzfJB1yN9+NB7D89x6c9P2cA6nMAxRRw2ZGAtmFyOI2eCl4x99niMD0bIjAk1kuTMyY\n\t+3WLlKR5xI9UfjzIKMkNHViPEdtYkMj8CkQzUHBDON3Biy/UsAgHqBPOP0Fo6cllSMaw\n\tKZQu+pU2NiMujQ1qawHmTygvYTGTiQHXUG48HDtyD0oFd2taMCCwhjkXz8r8h4lfcrQE\n\tJAWDop2BGwwhlbEQf7hS8/XhTgT8ZzpPa9GmtAXF33jX0P2GQJdMS9XVh77y9qLCyQm+\n\tOTfg==","X-Gm-Message-State":"AOJu0Yy8JDNrN7MehrupAr14NgE64tXpr57OO/eJ6CxHryDS5iFVtMHW\n\tl6MLPJfYtiG6zF4vHP8xLMHHzDZc0XMihQPLTwdpF4zt6OPcoK6sYN4WeBPMU8rtfR3tt12gsNP\n\tanttgDmmkHNazhem4CzxB7FLxZV8zGqMOZTf5hWgq2vGGYWM2LWhDb4we5b7GZr2VcwAhVXs=","X-Received":["by 2002:a17:906:6a10:b0:a90:3492:9ad8 with SMTP id\n\ta640c23a62f3a-a90d51a7139mr9949366b.65.1726770222099; \n\tThu, 19 Sep 2024 11:23:42 -0700 (PDT)","by 2002:a17:906:6a10:b0:a90:3492:9ad8 with SMTP id\n\ta640c23a62f3a-a90d51a7139mr9946766b.65.1726770221664; \n\tThu, 19 Sep 2024 11:23:41 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IF3BI1rdemuWCn1U12OeJYEQUaX6M3tqPJ41RwFJnptgqSb1+tePH5oqwQVMklLlm6jT7yiOw==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Umang Jain\n\t<umang.jain@ideasonboard.com>,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>,  Daniel Scally\n\t<dan.scally@ideasonboard.com>","Subject":"Re: [PATCH v6 16/18] libcamera: software_isp: Use DelayedControls","In-Reply-To":"<172591668965.2319503.10804291449485969885@ping.linuxembedded.co.uk>\n\t(Kieran Bingham's message of \"Mon, 09 Sep 2024 22:18:09 +0100\")","References":"<20240906120927.4071508-1-mzamazal@redhat.com>\n\t<20240906120927.4071508-17-mzamazal@redhat.com>\n\t<172591668965.2319503.10804291449485969885@ping.linuxembedded.co.uk>","Date":"Thu, 19 Sep 2024 20:23:39 +0200","Message-ID":"<87o74jlcyc.fsf@redhat.com>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]