[{"id":39003,"web_url":"https://patchwork.libcamera.org/comment/39003/","msgid":"<178059772137.1119811.14384220982117068962@ping.linuxembedded.co.uk>","date":"2026-06-04T18:28:41","subject":"Re: [RFC PATCH v3 03/17] libcamera: software_isp: Introduce\n\targuments for parameters buffers","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Milan Zamazal (2026-06-04 10:50:45)\n> Processing parameters in software ISP are currently passed by value.\n> This is unlike hardware pipelines, which use a ring of buffers for the\n> purpose and pass references to the buffers currently selected from the\n> ring rather than passing the whole parameters buffers.\n> \n> This is a preparatory patch to introduce a similar mechanism in software\n> ISP, in order to resolve TODO #5.  It adds a new argument paramsBufferId\n> for the future parameters buffer ids passed to the calls.  The buffer\n> ids must be passed to the following groups of methods:\n> \n> - IPASoftSimple::prepare, in order to create the parameters in the given\n>   buffer for the corresponding frame processing.\n> \n> - SoftwareIsp::saveIspParams, in order to signal that the parameters are\n>   set by the IPA.\n> \n> - Debayer::process, in order to get the buffer with the processing\n>   parameters.\n> \n> - SoftwareIsp::paramsBufferReady, in order to signal that the selected\n>   parameters buffer from the ring is no longer needed for the given\n>   frame and can be reused.  This is a newly introduced signal.\n> \n> The type of the buffer id parameter is set to uint32_t because:\n> \n> - It can be used in mojom.\n> - It is consistent with the similar types in the hardware pipelines.\n> - It covers file descriptor number range, which will be used as buffer\n>   ids (more on this in followup patches).\n> \n> This patch doesn't do more than adding the arguments, to keep the patch\n> simple.  The buffer handling will be implemented in the followup\n> patches.\n> \n\nI'm curious if the actual 'ISP' part should know about the buffer id ...\nbecause hardware ISPs don't know the buffer id - they just get given the\ndmabufs etc.\n\nBut I think for now it's fine?\n\nI would be curious to see how the actual 'ISP' part could be very\nclearly an independent component with a clear interface, almost\nmirroring the hardware devices, but I think this is already working\ntowards simplifying things for parallel/pipelined operations so:\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  .../libcamera/internal/software_isp/software_isp.h |  3 ++-\n>  include/libcamera/ipa/soft.mojom                   |  4 ++--\n>  src/ipa/simple/soft_simple.cpp                     |  8 +++++---\n>  src/libcamera/software_isp/debayer.cpp             |  8 +++++++-\n>  src/libcamera/software_isp/debayer.h               |  6 +++++-\n>  src/libcamera/software_isp/debayer_cpu.cpp         |  6 +++++-\n>  src/libcamera/software_isp/debayer_cpu.h           |  4 +++-\n>  src/libcamera/software_isp/debayer_egl.cpp         |  6 +++++-\n>  src/libcamera/software_isp/debayer_egl.h           |  4 +++-\n>  src/libcamera/software_isp/software_isp.cpp        | 14 +++++++++++---\n>  10 files changed, 48 insertions(+), 15 deletions(-)\n> \n> diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h\n> index 86cb8f8de..85c9059e2 100644\n> --- a/include/libcamera/internal/software_isp/software_isp.h\n> +++ b/include/libcamera/internal/software_isp/software_isp.h\n> @@ -88,7 +88,8 @@ public:\n>         Signal<const ControlList &> setSensorControls;\n>  \n>  private:\n> -       void saveIspParams();\n> +       void saveIspParams(const uint32_t paramsBufferId);\n> +       void paramsBufferReady(const uint32_t paramsBufferId);\n>         void setSensorCtrls(const ControlList &sensorControls);\n>         void statsReady(uint32_t frame, uint32_t bufferId);\n>         void inputReady(FrameBuffer *input);\n> diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom\n> index e75b03a3d..18789d5de 100644\n> --- a/include/libcamera/ipa/soft.mojom\n> +++ b/include/libcamera/ipa/soft.mojom\n> @@ -25,7 +25,7 @@ interface IPASoftInterface {\n>                 => (int32 ret);\n>  \n>         [async] queueRequest(uint32 frame, libcamera.ControlList sensorControls);\n> -       [async] computeParams(uint32 frame);\n> +       [async] computeParams(uint32 frame, uint32 paramsBufferId);\n>         [async] processStats(uint32 frame,\n>                              uint32 bufferId,\n>                              libcamera.ControlList sensorControls);\n> @@ -33,6 +33,6 @@ interface IPASoftInterface {\n>  \n>  interface IPASoftEventInterface {\n>         setSensorControls(libcamera.ControlList sensorControls);\n> -       paramsComputed();\n> +       paramsComputed(uint32 paramsBufferId);\n>         metadataReady(uint32 frame, libcamera.ControlList metadata);\n>  };\n> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> index cfc1389e4..69bfef302 100644\n> --- a/src/ipa/simple/soft_simple.cpp\n> +++ b/src/ipa/simple/soft_simple.cpp\n> @@ -64,7 +64,8 @@ public:\n>         void stop() override;\n>  \n>         void queueRequest(const uint32_t frame, const ControlList &controls) override;\n> -       void computeParams(const uint32_t frame) override;\n> +       void computeParams(const uint32_t frame,\n> +                          const uint32_t paramsBufferId) override;\n>         void processStats(const uint32_t frame, const uint32_t bufferId,\n>                           const ControlList &sensorControls) override;\n>  \n> @@ -283,7 +284,8 @@ void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro\n>                 algo->queueRequest(context_, frame, frameContext, controls);\n>  }\n>  \n> -void IPASoftSimple::computeParams(const uint32_t frame)\n> +void IPASoftSimple::computeParams(const uint32_t frame,\n> +                                 const uint32_t paramsBufferId)\n>  {\n>         context_.activeState.combinedMatrix = Matrix<float, 3, 3>::identity();\n>  \n> @@ -292,7 +294,7 @@ void IPASoftSimple::computeParams(const uint32_t frame)\n>                 algo->prepare(context_, frame, frameContext, params_);\n>         params_->combinedMatrix = context_.activeState.combinedMatrix;\n>  \n> -       paramsComputed.emit();\n> +       paramsComputed.emit(paramsBufferId);\n>  }\n>  \n>  void IPASoftSimple::processStats(const uint32_t frame,\n> diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\n> index 2d7abfb83..7b1be52b2 100644\n> --- a/src/libcamera/software_isp/debayer.cpp\n> +++ b/src/libcamera/software_isp/debayer.cpp\n> @@ -104,9 +104,10 @@ Debayer::~Debayer()\n>   */\n>  \n>  /**\n> - * \\fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)\n> + * \\fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params)\n>   * \\brief Process the bayer data into the requested format\n>   * \\param[in] frame The frame number\n> + * \\param[in] paramsBufferId The id of the params buffer in use\n>   * \\param[in] input The input buffer\n>   * \\param[in] output The output buffer\n>   * \\param[in] params The parameters to be used in debayering\n> @@ -142,6 +143,11 @@ Debayer::~Debayer()\n>   * current stream.\n>   */\n>  \n> +/**\n> + * \\var Debayer::paramsBufferReady\n> + * \\brief Signals when the processing params are no longer needed\n> + */\n> +\n>  /**\n>   * \\var Signal<FrameBuffer *> Debayer::inputBufferReady\n>   * \\brief Signals when the input buffer is ready\n> diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h\n> index a2a17ec18..9a97851b7 100644\n> --- a/src/libcamera/software_isp/debayer.h\n> +++ b/src/libcamera/software_isp/debayer.h\n> @@ -47,7 +47,10 @@ public:\n>         virtual std::tuple<unsigned int, unsigned int>\n>         strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0;\n>  \n> -       virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) = 0;\n> +       virtual void process(uint32_t frame,\n> +                            const uint32_t paramsBufferId,\n> +                            FrameBuffer *input, FrameBuffer *output,\n> +                            const DebayerParams &params) = 0;\n>         virtual int start() { return 0; }\n>         virtual void stop() {}\n>  \n> @@ -59,6 +62,7 @@ public:\n>  \n>         Signal<FrameBuffer *> inputBufferReady;\n>         Signal<FrameBuffer *> outputBufferReady;\n> +       Signal<uint32_t> paramsBufferReady;\n>  \n>         struct DebayerInputConfig {\n>                 Size patternSize;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index 1f9b24da0..51b58fce5 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -971,7 +971,9 @@ void DebayerCpu::updateLookupTables(const DebayerParams &params)\n>         params_ = params;\n>  }\n>  \n> -void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params)\n> +void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId,\n> +                        FrameBuffer *input, FrameBuffer *output,\n> +                        const DebayerParams &params)\n>  {\n>         bench_.startFrame();\n>  \n> @@ -981,6 +983,8 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>  \n>         updateLookupTables(params);\n>  \n> +       paramsBufferReady.emit(paramsBufferId);\n> +\n>         /* Copy metadata from the input buffer */\n>         FrameMetadata &metadata = output->_d()->metadata();\n>         metadata.status = input->metadata().status;\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index 68da95083..1b4e8548a 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -42,7 +42,9 @@ public:\n>         std::vector<PixelFormat> formats(PixelFormat input) override;\n>         std::tuple<unsigned int, unsigned int>\n>         strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override;\n> -       void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) override;\n> +       void process(uint32_t frame, const uint32_t paramsBufferId,\n> +                    FrameBuffer *input, FrameBuffer *output,\n> +                    const DebayerParams &params) override;\n>         int start() override;\n>         void stop() override;\n>         SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;\n> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n> index 99825d49e..60fd5463f 100644\n> --- a/src/libcamera/software_isp/debayer_egl.cpp\n> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n> @@ -546,7 +546,9 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye\n>         return 0;\n>  }\n>  \n> -void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params)\n> +void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId,\n> +                        FrameBuffer *input, FrameBuffer *output,\n> +                        const DebayerParams &params)\n>  {\n>         bench_.startFrame();\n>  \n> @@ -563,6 +565,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>                 LOG(Debayer, Error) << \"debayerGPU failed\";\n>                 goto error;\n>         }\n> +       paramsBufferReady.emit(paramsBufferId);\n>  \n>         metadata.planes()[0].bytesused = output->planes()[0].length;\n>  \n> @@ -593,6 +596,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>         return;\n>  \n>  error:\n> +       paramsBufferReady.emit(paramsBufferId);\n>         bench_.finishFrame();\n>         metadata.status = FrameMetadata::FrameError;\n>         return;\n> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n> index 875e7cfc5..a3a4448e7 100644\n> --- a/src/libcamera/software_isp/debayer_egl.h\n> +++ b/src/libcamera/software_isp/debayer_egl.h\n> @@ -51,7 +51,9 @@ public:\n>         std::vector<PixelFormat> formats(PixelFormat input) override;\n>         std::tuple<unsigned int, unsigned int> strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override;\n>  \n> -       void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) override;\n> +       void process(uint32_t frame, const uint32_t paramsBufferId,\n> +                    FrameBuffer *input, FrameBuffer *output,\n> +                    const DebayerParams &params) override;\n>         int start() override;\n>         void stop() override;\n>  \n> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n> index f5b44f4e5..3d1dec21d 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -128,6 +128,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>  \n>         debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);\n>         debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);\n> +       debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady);\n>  \n>         ipa_ = pipe->createIPA<ipa::soft::IPAProxySoft>(0, 0);\n>         if (!ipa_) {\n> @@ -409,16 +410,23 @@ void SoftwareIsp::stop()\n>   */\n>  void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output)\n>  {\n> -       ipa_->computeParams(frame);\n> +       /* \\todo Provide a real value */\n> +       constexpr uint32_t paramsBufferId = 0;\n> +       ipa_->computeParams(frame, paramsBufferId);\n>         debayer_->invokeMethod(&Debayer::process,\n> -                              ConnectionTypeQueued, frame, input, output, debayerParams_);\n> +                              ConnectionTypeQueued, frame, paramsBufferId,\n> +                              input, output, debayerParams_);\n>  }\n>  \n> -void SoftwareIsp::saveIspParams()\n> +void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId)\n>  {\n>         debayerParams_ = *sharedParams_;\n>  }\n>  \n> +void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId)\n> +{\n> +}\n> +\n>  void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)\n>  {\n>         setSensorControls.emit(sensorControls);\n> -- \n> 2.54.0\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 BE608C328C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu,  4 Jun 2026 18:28:47 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DD3C163411;\n\tThu,  4 Jun 2026 20:28:46 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B95AA62DC4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu,  4 Jun 2026 20:28:44 +0200 (CEST)","from monstersaurus.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 C361813D7;\n\tThu,  4 Jun 2026 20:28:19 +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=\"anYmZqKI\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1780597699;\n\tbh=w3ZNv5PaVbM5wJzkrq/3ij4/hS2e4GAgqhzqAnBg7GI=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=anYmZqKIRJb8nmWeip7vFlyGl7bBJNeOf0uqAXgoi4gDaIKwWyRbskxHSN/a/XtXO\n\tDxaxJjRyfZpz2WBJQPXMWB1BrfUlCOJ21iD1A+8i439AuUVISk4HVQ2Ug6EvRTBGrg\n\tBbbvlWR37W7/9gGOZZwXLzA3qd1aXqgdFFLZ6+u8=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260604095105.68798-4-mzamazal@redhat.com>","References":"<20260604095105.68798-1-mzamazal@redhat.com>\n\t<20260604095105.68798-4-mzamazal@redhat.com>","Subject":"Re: [RFC PATCH v3 03/17] libcamera: software_isp: Introduce\n\targuments for parameters buffers","From":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"Milan Zamazal <mzamazal@redhat.com>, =?utf-8?b?QmFybmFiw6FzIFDFkWN6?=\n\t=?utf-8?q?e?= <barnabas.pocze@ideasonboard.com>,\n\tjohannes.goede@oss.qualcomm.com","To":"Milan Zamazal <mzamazal@redhat.com>, libcamera-devel@lists.libcamera.org","Date":"Thu, 04 Jun 2026 19:28:41 +0100","Message-ID":"<178059772137.1119811.14384220982117068962@ping.linuxembedded.co.uk>","User-Agent":"alot/0.9.1","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":39010,"web_url":"https://patchwork.libcamera.org/comment/39010/","msgid":"<85y0gpxgfi.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2026-06-08T14:20:01","subject":"Re: [RFC PATCH v3 03/17] libcamera: software_isp: Introduce\n\targuments for parameters buffers","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"[I've apparently forgotten to clean up the patch directory before some\nfinal reordering and have posted duplicate patches.  I'll post v4 fixing\nthis.]\n\nHi Kieran,\n\nthank you for review.\n\nKieran Bingham <kieran.bingham@ideasonboard.com> writes:\n\n> Quoting Milan Zamazal (2026-06-04 10:50:45)\n>> Processing parameters in software ISP are currently passed by value.\n>> This is unlike hardware pipelines, which use a ring of buffers for the\n>\n>> purpose and pass references to the buffers currently selected from the\n>> ring rather than passing the whole parameters buffers.\n>> \n>> This is a preparatory patch to introduce a similar mechanism in software\n>> ISP, in order to resolve TODO #5.  It adds a new argument paramsBufferId\n>> for the future parameters buffer ids passed to the calls.  The buffer\n>> ids must be passed to the following groups of methods:\n>> \n>> - IPASoftSimple::prepare, in order to create the parameters in the given\n>>   buffer for the corresponding frame processing.\n>> \n>> - SoftwareIsp::saveIspParams, in order to signal that the parameters are\n>>   set by the IPA.\n>> \n>> - Debayer::process, in order to get the buffer with the processing\n>>   parameters.\n>> \n>> - SoftwareIsp::paramsBufferReady, in order to signal that the selected\n>>   parameters buffer from the ring is no longer needed for the given\n>>   frame and can be reused.  This is a newly introduced signal.\n>> \n>> The type of the buffer id parameter is set to uint32_t because:\n>> \n>> - It can be used in mojom.\n>> - It is consistent with the similar types in the hardware pipelines.\n>> - It covers file descriptor number range, which will be used as buffer\n>>   ids (more on this in followup patches).\n>> \n>> This patch doesn't do more than adding the arguments, to keep the patch\n>> simple.  The buffer handling will be implemented in the followup\n>> patches.\n>> \n>\n> I'm curious if the actual 'ISP' part should know about the buffer id ...\n> because hardware ISPs don't know the buffer id - they just get given the\n> dmabufs etc.\n>\n> But I think for now it's fine?\n>\n> I would be curious to see how the actual 'ISP' part could be very\n> clearly an independent component with a clear interface, almost\n> mirroring the hardware devices, \n\nMaybe, IIRC I thought the way implemented here was easier and avoided\none level of indirection somewhere.  I don't feel like reworking it now\nwould be wise, let's see how we can progress.\n\n> but I think this is already working towards simplifying things for\n> parallel/pipelined operations so:\n>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n>\n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  .../libcamera/internal/software_isp/software_isp.h |  3 ++-\n>>  include/libcamera/ipa/soft.mojom                   |  4 ++--\n>>  src/ipa/simple/soft_simple.cpp                     |  8 +++++---\n>>  src/libcamera/software_isp/debayer.cpp             |  8 +++++++-\n>>  src/libcamera/software_isp/debayer.h               |  6 +++++-\n>>  src/libcamera/software_isp/debayer_cpu.cpp         |  6 +++++-\n>>  src/libcamera/software_isp/debayer_cpu.h           |  4 +++-\n>>  src/libcamera/software_isp/debayer_egl.cpp         |  6 +++++-\n>>  src/libcamera/software_isp/debayer_egl.h           |  4 +++-\n>>  src/libcamera/software_isp/software_isp.cpp        | 14 +++++++++++---\n>>  10 files changed, 48 insertions(+), 15 deletions(-)\n>> \n>> diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h\n>> index 86cb8f8de..85c9059e2 100644\n>> --- a/include/libcamera/internal/software_isp/software_isp.h\n>> +++ b/include/libcamera/internal/software_isp/software_isp.h\n>> @@ -88,7 +88,8 @@ public:\n>>         Signal<const ControlList &> setSensorControls;\n>>  \n>>  private:\n>> -       void saveIspParams();\n>> +       void saveIspParams(const uint32_t paramsBufferId);\n>> +       void paramsBufferReady(const uint32_t paramsBufferId);\n>>         void setSensorCtrls(const ControlList &sensorControls);\n>>         void statsReady(uint32_t frame, uint32_t bufferId);\n>>         void inputReady(FrameBuffer *input);\n>> diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom\n>> index e75b03a3d..18789d5de 100644\n>> --- a/include/libcamera/ipa/soft.mojom\n>> +++ b/include/libcamera/ipa/soft.mojom\n>> @@ -25,7 +25,7 @@ interface IPASoftInterface {\n>>                 => (int32 ret);\n>>  \n>>         [async] queueRequest(uint32 frame, libcamera.ControlList sensorControls);\n>> -       [async] computeParams(uint32 frame);\n>> +       [async] computeParams(uint32 frame, uint32 paramsBufferId);\n>>         [async] processStats(uint32 frame,\n>>                              uint32 bufferId,\n>>                              libcamera.ControlList sensorControls);\n>> @@ -33,6 +33,6 @@ interface IPASoftInterface {\n>>  \n>>  interface IPASoftEventInterface {\n>>         setSensorControls(libcamera.ControlList sensorControls);\n>> -       paramsComputed();\n>> +       paramsComputed(uint32 paramsBufferId);\n>>         metadataReady(uint32 frame, libcamera.ControlList metadata);\n>>  };\n>> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n>> index cfc1389e4..69bfef302 100644\n>> --- a/src/ipa/simple/soft_simple.cpp\n>> +++ b/src/ipa/simple/soft_simple.cpp\n>> @@ -64,7 +64,8 @@ public:\n>>         void stop() override;\n>>  \n>>         void queueRequest(const uint32_t frame, const ControlList &controls) override;\n>> -       void computeParams(const uint32_t frame) override;\n>> +       void computeParams(const uint32_t frame,\n>> +                          const uint32_t paramsBufferId) override;\n>>         void processStats(const uint32_t frame, const uint32_t bufferId,\n>>                           const ControlList &sensorControls) override;\n>>  \n>> @@ -283,7 +284,8 @@ void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro\n>>                 algo->queueRequest(context_, frame, frameContext, controls);\n>>  }\n>>  \n>> -void IPASoftSimple::computeParams(const uint32_t frame)\n>> +void IPASoftSimple::computeParams(const uint32_t frame,\n>> +                                 const uint32_t paramsBufferId)\n>>  {\n>>         context_.activeState.combinedMatrix = Matrix<float, 3, 3>::identity();\n>>  \n>> @@ -292,7 +294,7 @@ void IPASoftSimple::computeParams(const uint32_t frame)\n>>                 algo->prepare(context_, frame, frameContext, params_);\n>>         params_->combinedMatrix = context_.activeState.combinedMatrix;\n>>  \n>> -       paramsComputed.emit();\n>> +       paramsComputed.emit(paramsBufferId);\n>>  }\n>>  \n>>  void IPASoftSimple::processStats(const uint32_t frame,\n>> diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\n>> index 2d7abfb83..7b1be52b2 100644\n>> --- a/src/libcamera/software_isp/debayer.cpp\n>> +++ b/src/libcamera/software_isp/debayer.cpp\n>> @@ -104,9 +104,10 @@ Debayer::~Debayer()\n>>   */\n>>  \n>>  /**\n>> - * \\fn void Debayer::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)\n>> + * \\fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params)\n>>   * \\brief Process the bayer data into the requested format\n>>   * \\param[in] frame The frame number\n>> + * \\param[in] paramsBufferId The id of the params buffer in use\n>>   * \\param[in] input The input buffer\n>>   * \\param[in] output The output buffer\n>>   * \\param[in] params The parameters to be used in debayering\n>> @@ -142,6 +143,11 @@ Debayer::~Debayer()\n>>   * current stream.\n>>   */\n>>  \n>> +/**\n>> + * \\var Debayer::paramsBufferReady\n>> + * \\brief Signals when the processing params are no longer needed\n>> + */\n>> +\n>>  /**\n>>   * \\var Signal<FrameBuffer *> Debayer::inputBufferReady\n>>   * \\brief Signals when the input buffer is ready\n>> diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h\n>> index a2a17ec18..9a97851b7 100644\n>> --- a/src/libcamera/software_isp/debayer.h\n>> +++ b/src/libcamera/software_isp/debayer.h\n>> @@ -47,7 +47,10 @@ public:\n>>         virtual std::tuple<unsigned int, unsigned int>\n>>         strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) = 0;\n>>  \n>> -       virtual void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) = 0;\n>> +       virtual void process(uint32_t frame,\n>> +                            const uint32_t paramsBufferId,\n>> +                            FrameBuffer *input, FrameBuffer *output,\n>> +                            const DebayerParams &params) = 0;\n>>         virtual int start() { return 0; }\n>>         virtual void stop() {}\n>>  \n>> @@ -59,6 +62,7 @@ public:\n>>  \n>>         Signal<FrameBuffer *> inputBufferReady;\n>>         Signal<FrameBuffer *> outputBufferReady;\n>> +       Signal<uint32_t> paramsBufferReady;\n>>  \n>>         struct DebayerInputConfig {\n>>                 Size patternSize;\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n>> index 1f9b24da0..51b58fce5 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n>> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n>> @@ -971,7 +971,9 @@ void DebayerCpu::updateLookupTables(const DebayerParams &params)\n>>         params_ = params;\n>>  }\n>>  \n>> -void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params)\n>> +void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId,\n>> +                        FrameBuffer *input, FrameBuffer *output,\n>> +                        const DebayerParams &params)\n>>  {\n>>         bench_.startFrame();\n>>  \n>> @@ -981,6 +983,8 @@ void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>>  \n>>         updateLookupTables(params);\n>>  \n>> +       paramsBufferReady.emit(paramsBufferId);\n>> +\n>>         /* Copy metadata from the input buffer */\n>>         FrameMetadata &metadata = output->_d()->metadata();\n>>         metadata.status = input->metadata().status;\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n>> index 68da95083..1b4e8548a 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.h\n>> +++ b/src/libcamera/software_isp/debayer_cpu.h\n>> @@ -42,7 +42,9 @@ public:\n>>         std::vector<PixelFormat> formats(PixelFormat input) override;\n>>         std::tuple<unsigned int, unsigned int>\n>>         strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override;\n>> -       void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) override;\n>> +       void process(uint32_t frame, const uint32_t paramsBufferId,\n>> +                    FrameBuffer *input, FrameBuffer *output,\n>> +                    const DebayerParams &params) override;\n>>         int start() override;\n>>         void stop() override;\n>>         SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) override;\n>> diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\n>> index 99825d49e..60fd5463f 100644\n>> --- a/src/libcamera/software_isp/debayer_egl.cpp\n>> +++ b/src/libcamera/software_isp/debayer_egl.cpp\n>> @@ -546,7 +546,9 @@ int DebayerEGL::debayerGPU(FrameBuffer *input, FrameBuffer *output, const Debaye\n>>         return 0;\n>>  }\n>>  \n>> -void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params)\n>> +void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId,\n>> +                        FrameBuffer *input, FrameBuffer *output,\n>> +                        const DebayerParams &params)\n>>  {\n>>         bench_.startFrame();\n>>  \n>> @@ -563,6 +565,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>>                 LOG(Debayer, Error) << \"debayerGPU failed\";\n>>                 goto error;\n>>         }\n>> +       paramsBufferReady.emit(paramsBufferId);\n>>  \n>>         metadata.planes()[0].bytesused = output->planes()[0].length;\n>>  \n>> @@ -593,6 +596,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n>>         return;\n>>  \n>>  error:\n>> +       paramsBufferReady.emit(paramsBufferId);\n>>         bench_.finishFrame();\n>>         metadata.status = FrameMetadata::FrameError;\n>>         return;\n>> diff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\n>> index 875e7cfc5..a3a4448e7 100644\n>> --- a/src/libcamera/software_isp/debayer_egl.h\n>> +++ b/src/libcamera/software_isp/debayer_egl.h\n>> @@ -51,7 +51,9 @@ public:\n>>         std::vector<PixelFormat> formats(PixelFormat input) override;\n>>         std::tuple<unsigned int, unsigned int> strideAndFrameSize(const PixelFormat &outputFormat, const Size &size) override;\n>>  \n>> -       void process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams &params) override;\n>> +       void process(uint32_t frame, const uint32_t paramsBufferId,\n>> +                    FrameBuffer *input, FrameBuffer *output,\n>> +                    const DebayerParams &params) override;\n>>         int start() override;\n>>         void stop() override;\n>>  \n>> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n>> index f5b44f4e5..3d1dec21d 100644\n>> --- a/src/libcamera/software_isp/software_isp.cpp\n>> +++ b/src/libcamera/software_isp/software_isp.cpp\n>> @@ -128,6 +128,7 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>>  \n>>         debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);\n>>         debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);\n>> +       debayer_->paramsBufferReady.connect(this, &SoftwareIsp::paramsBufferReady);\n>>  \n>>         ipa_ = pipe->createIPA<ipa::soft::IPAProxySoft>(0, 0);\n>>         if (!ipa_) {\n>> @@ -409,16 +410,23 @@ void SoftwareIsp::stop()\n>>   */\n>>  void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output)\n>>  {\n>> -       ipa_->computeParams(frame);\n>> +       /* \\todo Provide a real value */\n>> +       constexpr uint32_t paramsBufferId = 0;\n>> +       ipa_->computeParams(frame, paramsBufferId);\n>>         debayer_->invokeMethod(&Debayer::process,\n>> -                              ConnectionTypeQueued, frame, input, output, debayerParams_);\n>> +                              ConnectionTypeQueued, frame, paramsBufferId,\n>> +                              input, output, debayerParams_);\n>>  }\n>>  \n>> -void SoftwareIsp::saveIspParams()\n>> +void SoftwareIsp::saveIspParams([[maybe_unused]] const uint32_t paramsBufferId)\n>>  {\n>>         debayerParams_ = *sharedParams_;\n>>  }\n>>  \n>> +void SoftwareIsp::paramsBufferReady([[maybe_unused]] const uint32_t paramsBufferId)\n>> +{\n>> +}\n>> +\n>>  void SoftwareIsp::setSensorCtrls(const ControlList &sensorControls)\n>>  {\n>>         setSensorControls.emit(sensorControls);\n>> -- \n>> 2.54.0\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 EE974C324C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  8 Jun 2026 14:20:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DA45D61EE2;\n\tMon,  8 Jun 2026 16:20:10 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 743B261E74\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  8 Jun 2026 16:20:09 +0200 (CEST)","from mail-wm1-f71.google.com (mail-wm1-f71.google.com\n\t[209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-210-T5JDIe_yONaYKRPF4Hcb7Q-1; Mon, 08 Jun 2026 10:20:05 -0400","by mail-wm1-f71.google.com with SMTP id\n\t5b1f17b1804b1-4908af8d7f9so26752835e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 08 Jun 2026 07:20:05 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb\n\t(ip-77-48-47-4.net.vodafone.cz. [77.48.47.4])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-490bc3e4b5asm398884245e9.13.2026.06.08.07.20.02\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 08 Jun 2026 07:20:02 -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=\"hQYOmqEz\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1780928408;\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=tBWhNOvL3aLj8Gk8Rh1pRJ1jWwviTs12CVF6TN6CfE8=;\n\tb=hQYOmqEzRT2GumL8jgUTRDP+LcwvXfnE3AJJNlSidtSSpNCfTUjeflcOiaYr7HYC7nOb5y\n\t3oiGNcHWnb6erC+Sdwt+z15sQcuvNmBUM3PlQYUyR4oEy6FhndpSYCZbo1SqpldyyL0DDL\n\tANG9ByFxT6CYPby+MjSzxRulvHAoaVg=","X-MC-Unique":"T5JDIe_yONaYKRPF4Hcb7Q-1","X-Mimecast-MFC-AGG-ID":"T5JDIe_yONaYKRPF4Hcb7Q_1780928404","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1780928404; x=1781533204;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject\n\t:date:message-id:reply-to;\n\tbh=tBWhNOvL3aLj8Gk8Rh1pRJ1jWwviTs12CVF6TN6CfE8=;\n\tb=XZcRuga98djuh1+NCjV7bf4shNp39sAa74IUZXlyCH5WnXOpUFjYZaypNauJBTewpQ\n\tGCexNQV1FD4/Kizg8EoEUetBiEhQVwy3NhMu9wJgkWOnvmIxL+QUvWjb+d+5i9nRaa1K\n\tbdiGPoDiV6kH2GwopzGA6EyzZJfQNVq9UUi/9RAA25yBLRVBV0mda8UZfucJ9ce99ep5\n\tyFWLKFfVUXC7+EhAFpLbDU7wdaRb1Drh8BVORYKhoHoVj5OQlwvYtAQwUJo8NMhYrcaQ\n\tj8G2sbEQU6L0UutmVvc4+ZrW00z3XnkX81wfgxNMOko43F+b0eFpb6h/vH3yPMD9zcHm\n\tNr1w==","X-Gm-Message-State":"AOJu0YwP5MwwvO72XLBYDZIp0pcJZXnNQIloF7uXbBAh5IphuNlqTroy\n\tTVY9pfYtIF9QjFRLXCX+gQKm9JEVQDtcn8UJB3ughXNodqclb+icBshFUiR66+FmSdpDg9V/cZw\n\tpQBm0XncL5IcelULX2vCVItEpezUsPA0cJU/KFkMU/gI151nJiJZPX28RD2/38HljX7xGXfw+K4\n\t0=","X-Gm-Gg":"Acq92OH+jZasHDYwHS25x8eb5vXPiYsGHwCBUVqVQEWQ55eZFCr43zhvyC+xBwP1tz6\n\tx3SvKfZfNpnHDEDPjWmW1+kRr1JoIXY3/8tm+5e3Rzc9+ofQ7uNxpyRH6SRdFS/w990akNNSb8/\n\t9BA/M813SX/c+p6ptVV+KIIvqrq2qKZQ0uOA1r7nsdODx1/E4FDpIuk+Dsdtsu/cUQUy9B4DjDS\n\t5u/68mqXdfBSDBFVXs5Zmanj00YULkEw11l5EBd9jhn3bsWtJkMPk4s2rAdRW4mqA5k+Hapb5xg\n\tEjg/2jb6vmc21Z6drE53KEX1eNmqHXG6gW59w19DWtYHRty9GZ9/LTFr/7mRqauNRFKbHzddiPA\n\thUJvcd8r1mP2nlEPdzvNSbv/OK3DxcGZZKJWcry8Sm7Cu9KTmD02LxtfWBy0LlJ/WvNW464Pt0C\n\tNW79hpAmbIKg==","X-Received":["by 2002:a05:600c:8183:b0:490:958c:46dc with SMTP id\n\t5b1f17b1804b1-490c25b0a60mr238605455e9.17.1780928404290; \n\tMon, 08 Jun 2026 07:20:04 -0700 (PDT)","by 2002:a05:600c:8183:b0:490:958c:46dc with SMTP id\n\t5b1f17b1804b1-490c25b0a60mr238604835e9.17.1780928403690; \n\tMon, 08 Jun 2026 07:20:03 -0700 (PDT)"],"From":"Milan Zamazal <mzamazal@redhat.com>","To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, =?utf-8?b?QmFybmFiw6FzIFDFkWN6?=\n\t=?utf-8?q?e?= <barnabas.pocze@ideasonboard.com>,\n\tjohannes.goede@oss.qualcomm.com","Subject":"Re: [RFC PATCH v3 03/17] libcamera: software_isp: Introduce\n\targuments for parameters buffers","In-Reply-To":"<178059772137.1119811.14384220982117068962@ping.linuxembedded.co.uk>\n\t(Kieran Bingham's message of \"Thu, 04 Jun 2026 19:28:41 +0100\")","References":"<20260604095105.68798-1-mzamazal@redhat.com>\n\t<20260604095105.68798-4-mzamazal@redhat.com>\n\t<178059772137.1119811.14384220982117068962@ping.linuxembedded.co.uk>","Date":"Mon, 08 Jun 2026 16:20:01 +0200","Message-ID":"<85y0gpxgfi.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"PY8gOZHhiSJ5JVVJxhyklCEB_i4QcYb0yj5vDH04Aq0_1780928404","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>"}}]