[{"id":33250,"web_url":"https://patchwork.libcamera.org/comment/33250/","msgid":"<20250203015205.GN12673@pendragon.ideasonboard.com>","date":"2025-02-03T01:52:05","subject":"Re: [PATCH v5 09/10] libcamera: software_isp: Track whether CCM is\n\tenabled","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Milan,\n\nThank you for the patch.\n\nOn Thu, Jan 30, 2025 at 07:14:46PM +0100, Milan Zamazal wrote:\n> Applying color correction matrix (CCM) in software ISP is optional due\n> to performance reasons.  CCM is applied if and only if `Ccm' algorithm\n> is present in the tuning file.\n> \n> Software ISP debayering is a performance critical piece of code and we\n> do not want to use dynamic conditionals there.  Therefore we pass\n> information about CCM application to debayering configuration and let it\n> select the right versions of debayering functions using templates.  This\n> is a trick similar to the previously used one for adding or not adding\n> an alpha channel to the output.\n> \n> Debayering gets this information but it ignores it in this patch.\n> Actual processing with CCM is added in the followup patch.\n> \n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  .../internal/software_isp/software_isp.h      |  1 +\n>  include/libcamera/ipa/soft.mojom              |  2 +-\n>  src/ipa/simple/algorithms/ccm.cpp             |  2 +\n>  src/ipa/simple/ipa_context.h                  |  1 +\n>  src/ipa/simple/soft_simple.cpp                |  8 +++-\n>  src/libcamera/software_isp/debayer.cpp        |  3 +-\n>  src/libcamera/software_isp/debayer.h          |  3 +-\n>  src/libcamera/software_isp/debayer_cpu.cpp    | 44 ++++++++++++-------\n>  src/libcamera/software_isp/debayer_cpu.h      | 29 ++++++------\n>  src/libcamera/software_isp/software_isp.cpp   |  5 ++-\n>  10 files changed, 61 insertions(+), 37 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 d51b03fd..156fde96 100644\n> --- a/include/libcamera/internal/software_isp/software_isp.h\n> +++ b/include/libcamera/internal/software_isp/software_isp.h\n> @@ -97,6 +97,7 @@ private:\n>  \tSharedMemObject<DebayerParams> sharedParams_;\n>  \tDebayerParams debayerParams_;\n>  \tDmaBufAllocator dmaHeap_;\n> +\tbool ccmEnabled_;\n>  \n>  \tstd::unique_ptr<ipa::soft::IPAProxySoft> ipa_;\n>  };\n> diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom\n> index d52e6f1a..ede74413 100644\n> --- a/include/libcamera/ipa/soft.mojom\n> +++ b/include/libcamera/ipa/soft.mojom\n> @@ -17,7 +17,7 @@ interface IPASoftInterface {\n>  \t     libcamera.SharedFD fdStats,\n>  \t     libcamera.SharedFD fdParams,\n>  \t     libcamera.ControlInfoMap sensorCtrlInfoMap)\n> -\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls);\n> +\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled);\n>  \tstart() => (int32 ret);\n>  \tstop();\n>  \tconfigure(IPAConfigInfo configInfo)\n> diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp\n> index 069a12f8..c50eb17d 100644\n> --- a/src/ipa/simple/algorithms/ccm.cpp\n> +++ b/src/ipa/simple/algorithms/ccm.cpp\n> @@ -34,6 +34,8 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData\n>  \t\treturn ret;\n>  \t}\n>  \n> +\tcontext.ccmEnabled = true;\n> +\n>  \treturn 0;\n>  }\n>  \n> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n> index bd6c66d8..40c13731 100644\n> --- a/src/ipa/simple/ipa_context.h\n> +++ b/src/ipa/simple/ipa_context.h\n> @@ -82,6 +82,7 @@ struct IPAContext {\n>  \tIPAActiveState activeState;\n>  \tFCQueue<IPAFrameContext> frameContexts;\n>  \tControlInfoMap::Map ctrlMap;\n> +\tbool ccmEnabled;\n>  };\n>  \n>  } /* namespace ipa::soft */\n> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n> index b26e4e15..a87c6cdd 100644\n> --- a/src/ipa/simple/soft_simple.cpp\n> +++ b/src/ipa/simple/soft_simple.cpp\n> @@ -51,7 +51,8 @@ public:\n>  \t\t const SharedFD &fdStats,\n>  \t\t const SharedFD &fdParams,\n>  \t\t const ControlInfoMap &sensorInfoMap,\n> -\t\t ControlInfoMap *ipaControls) override;\n> +\t\t ControlInfoMap *ipaControls,\n> +\t\t bool *ccmEnabled) override;\n>  \tint configure(const IPAConfigInfo &configInfo) override;\n>  \n>  \tint start() override;\n> @@ -89,7 +90,8 @@ int IPASoftSimple::init(const IPASettings &settings,\n>  \t\t\tconst SharedFD &fdStats,\n>  \t\t\tconst SharedFD &fdParams,\n>  \t\t\tconst ControlInfoMap &sensorInfoMap,\n> -\t\t\tControlInfoMap *ipaControls)\n> +\t\t\tControlInfoMap *ipaControls,\n> +\t\t\tbool *ccmEnabled)\n>  {\n>  \tcamHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel);\n>  \tif (!camHelper_) {\n> @@ -125,6 +127,8 @@ int IPASoftSimple::init(const IPASettings &settings,\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> +\t*ccmEnabled = context_.ccmEnabled;\n> +\n>  \tparams_ = nullptr;\n>  \tstats_ = nullptr;\n>  \n> diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\n> index f0b83261..45fe6960 100644\n> --- a/src/libcamera/software_isp/debayer.cpp\n> +++ b/src/libcamera/software_isp/debayer.cpp\n> @@ -57,10 +57,11 @@ Debayer::~Debayer()\n>  }\n>  \n>  /**\n> - * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n> + * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, bool ccmEnabled)\n\nIf there are no overloads of the function, you can write\n\n * \\fn int Debayer::configure()\n\nand doxygen will figure it out.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n>   * \\brief Configure the debayer object according to the passed in parameters\n>   * \\param[in] inputCfg The input configuration\n>   * \\param[in] outputCfgs The output configurations\n> + * \\param[in] ccmEnabled Whether a color correction matrix is applied\n>   *\n>   * \\return 0 on success, a negative errno on failure\n>   */\n> diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h\n> index d7ca060d..ba033d44 100644\n> --- a/src/libcamera/software_isp/debayer.h\n> +++ b/src/libcamera/software_isp/debayer.h\n> @@ -33,7 +33,8 @@ public:\n>  \tvirtual ~Debayer() = 0;\n>  \n>  \tvirtual int configure(const StreamConfiguration &inputCfg,\n> -\t\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;\n> +\t\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n> +\t\t\t      bool ccmEnabled) = 0;\n>  \n>  \tvirtual std::vector<PixelFormat> formats(PixelFormat inputFormat) = 0;\n>  \n> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n> index 01cfb36b..0cd03a8f 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n> @@ -114,7 +114,7 @@ DebayerCpu::~DebayerCpu() = default;\n>  \t\t(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div)),         \\\n>  \t\tcurr[x] / (div))\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -125,7 +125,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint8_t)\n> @@ -136,7 +136,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -148,7 +148,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -160,7 +160,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -172,7 +172,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tDECLARE_SRC_POINTERS(uint16_t)\n> @@ -184,7 +184,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -210,7 +210,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -231,7 +231,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -252,7 +252,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>  \t}\n>  }\n>  \n> -template<bool addAlphaByte>\n> +template<bool addAlphaByte, bool ccmEnabled>\n>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>  {\n>  \tconst int widthInBytes = window_.width * 5 / 4;\n> @@ -368,11 +368,17 @@ int DebayerCpu::setupStandardBayerOrder(BayerFormat::Order order)\n>  \treturn 0;\n>  }\n>  \n> -#define SET_DEBAYER_METHODS(method0, method1)                                                \\\n> -\tdebayer0_ = addAlphaByte ? &DebayerCpu::method0<true> : &DebayerCpu::method0<false>; \\\n> -\tdebayer1_ = addAlphaByte ? &DebayerCpu::method1<true> : &DebayerCpu::method1<false>;\n> -\n> -int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat)\n> +#define SET_DEBAYER_METHODS(method0, method1)                                                                        \\\n> +\tdebayer0_ = addAlphaByte                                                                                     \\\n> +\t\t\t    ? (ccmEnabled ? &DebayerCpu::method0<true, true> : &DebayerCpu::method0<true, false>)    \\\n> +\t\t\t    : (ccmEnabled ? &DebayerCpu::method0<false, true> : &DebayerCpu::method0<false, false>); \\\n> +\tdebayer1_ = addAlphaByte                                                                                     \\\n> +\t\t\t    ? (ccmEnabled ? &DebayerCpu::method1<true, true> : &DebayerCpu::method1<true, false>)    \\\n> +\t\t\t    : (ccmEnabled ? &DebayerCpu::method1<false, true> : &DebayerCpu::method1<false, false>);\n> +\n> +int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat,\n> +\t\t\t\t    PixelFormat outputFormat,\n> +\t\t\t\t    bool ccmEnabled)\n>  {\n>  \tBayerFormat bayerFormat =\n>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n> @@ -464,7 +470,8 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>  }\n>  \n>  int DebayerCpu::configure(const StreamConfiguration &inputCfg,\n> -\t\t\t  const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n> +\t\t\t  const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n> +\t\t\t  bool ccmEnabled)\n>  {\n>  \tif (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0)\n>  \t\treturn -EINVAL;\n> @@ -503,7 +510,10 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg,\n>  \t\treturn -EINVAL;\n>  \t}\n>  \n> -\tif (setDebayerFunctions(inputCfg.pixelFormat, outputCfg.pixelFormat) != 0)\n> +\tint ret = setDebayerFunctions(inputCfg.pixelFormat,\n> +\t\t\t\t      outputCfg.pixelFormat,\n> +\t\t\t\t      ccmEnabled);\n> +\tif (ret != 0)\n>  \t\treturn -EINVAL;\n>  \n>  \twindow_.x = ((inputCfg.size.width - outputCfg.size.width) / 2) &\n> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n> index 2c47e7c6..21c08a2d 100644\n> --- a/src/libcamera/software_isp/debayer_cpu.h\n> +++ b/src/libcamera/software_isp/debayer_cpu.h\n> @@ -1,7 +1,7 @@\n>  /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>  /*\n>   * Copyright (C) 2023, Linaro Ltd\n> - * Copyright (C) 2023, Red Hat Inc.\n> + * Copyright (C) 2023-2025 Red Hat Inc.\n>   *\n>   * Authors:\n>   * Hans de Goede <hdegoede@redhat.com>\n> @@ -31,7 +31,8 @@ public:\n>  \t~DebayerCpu();\n>  \n>  \tint configure(const StreamConfiguration &inputCfg,\n> -\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs);\n> +\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n> +\t\t      bool ccmEnabled);\n>  \tSize patternSize(PixelFormat inputFormat);\n>  \tstd::vector<PixelFormat> formats(PixelFormat input);\n>  \tstd::tuple<unsigned int, unsigned int>\n> @@ -85,28 +86,28 @@ private:\n>  \tusing debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \t/* 8-bit raw bayer format */\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 10-bit raw bayer format */\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* unpacked 12-bit raw bayer format */\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \t/* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n> -\ttemplate<bool addAlphaByte>\n> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>  \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>  \n>  \tstruct DebayerInputConfig {\n> @@ -125,7 +126,9 @@ private:\n>  \tint getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config);\n>  \tint getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config);\n>  \tint setupStandardBayerOrder(BayerFormat::Order order);\n> -\tint setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat);\n> +\tint setDebayerFunctions(PixelFormat inputFormat,\n> +\t\t\t\tPixelFormat outputFormat,\n> +\t\t\t\tbool ccmEnabled);\n>  \tvoid setupInputMemcpy(const uint8_t *linePointers[]);\n>  \tvoid shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src);\n>  \tvoid memcpyNextLine(const uint8_t *linePointers[]);\n> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n> index 44baf200..b03c4baa 100644\n> --- a/src/libcamera/software_isp/software_isp.cpp\n> +++ b/src/libcamera/software_isp/software_isp.cpp\n> @@ -128,7 +128,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>  \t\t\t     debayer_->getStatsFD(),\n>  \t\t\t     sharedParams_.fd(),\n>  \t\t\t     sensor->controls(),\n> -\t\t\t     ipaControls);\n> +\t\t\t     ipaControls,\n> +\t\t\t     &ccmEnabled_);\n>  \tif (ret) {\n>  \t\tLOG(SoftwareIsp, Error) << \"IPA init failed\";\n>  \t\tdebayer_.reset();\n> @@ -240,7 +241,7 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\n>  \tif (ret < 0)\n>  \t\treturn ret;\n>  \n> -\treturn debayer_->configure(inputCfg, outputCfgs);\n> +\treturn debayer_->configure(inputCfg, outputCfgs, ccmEnabled_);\n>  }\n>  \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 6084FC32DF\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  3 Feb 2025 01:52:12 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7307A6857A;\n\tMon,  3 Feb 2025 02:52:11 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 9566861876\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  3 Feb 2025 02:52:09 +0100 (CET)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 36B4D497;\n\tMon,  3 Feb 2025 02:50:58 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"LkQPMuTD\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1738547458;\n\tbh=3NBFtaHUO0byVy0qyKCzlzNN276Cjvy+rkzTVWKAsN4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=LkQPMuTD+SZqWElDALKkSC7vQcQyJ9HW+9O+ciOf/VAW/H9sRwX6A/xTIVmScb2ND\n\t/JSgnxl5gBtwhdXUBtFggXitN7pcTI/AuttkZgVy8oXfbRx51/U6rXOxegugH2Fp5t\n\tGo/4KysueHenTwsd3WkO86jIOjhbbJAwgVS1eoXs=","Date":"Mon, 3 Feb 2025 03:52:05 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org,\n\tRobert Mader <robert.mader@collabora.com>,\n\tHans de Goede <hdegoede@redhat.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v5 09/10] libcamera: software_isp: Track whether CCM is\n\tenabled","Message-ID":"<20250203015205.GN12673@pendragon.ideasonboard.com>","References":"<20250130181449.130492-1-mzamazal@redhat.com>\n\t<20250130181449.130492-10-mzamazal@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20250130181449.130492-10-mzamazal@redhat.com>","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":33288,"web_url":"https://patchwork.libcamera.org/comment/33288/","msgid":"<85seot68mf.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","date":"2025-02-04T15:18:48","subject":"Re: [PATCH v5 09/10] libcamera: software_isp: Track whether CCM is\n\tenabled","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Laurent,\n\nthank you for review.\n\nLaurent Pinchart <laurent.pinchart@ideasonboard.com> writes:\n\n> Hi Milan,\n>\n> Thank you for the patch.\n>\n> On Thu, Jan 30, 2025 at 07:14:46PM +0100, Milan Zamazal wrote:\n>> Applying color correction matrix (CCM) in software ISP is optional due\n>> to performance reasons.  CCM is applied if and only if `Ccm' algorithm\n>> is present in the tuning file.\n>> \n>> Software ISP debayering is a performance critical piece of code and we\n>> do not want to use dynamic conditionals there.  Therefore we pass\n>> information about CCM application to debayering configuration and let it\n>> select the right versions of debayering functions using templates.  This\n>> is a trick similar to the previously used one for adding or not adding\n>> an alpha channel to the output.\n>> \n>> Debayering gets this information but it ignores it in this patch.\n>> Actual processing with CCM is added in the followup patch.\n>> \n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  .../internal/software_isp/software_isp.h      |  1 +\n>>  include/libcamera/ipa/soft.mojom              |  2 +-\n>>  src/ipa/simple/algorithms/ccm.cpp             |  2 +\n>>  src/ipa/simple/ipa_context.h                  |  1 +\n>>  src/ipa/simple/soft_simple.cpp                |  8 +++-\n>>  src/libcamera/software_isp/debayer.cpp        |  3 +-\n>>  src/libcamera/software_isp/debayer.h          |  3 +-\n>>  src/libcamera/software_isp/debayer_cpu.cpp    | 44 ++++++++++++-------\n>>  src/libcamera/software_isp/debayer_cpu.h      | 29 ++++++------\n>>  src/libcamera/software_isp/software_isp.cpp   |  5 ++-\n>>  10 files changed, 61 insertions(+), 37 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 d51b03fd..156fde96 100644\n>> --- a/include/libcamera/internal/software_isp/software_isp.h\n>> +++ b/include/libcamera/internal/software_isp/software_isp.h\n>> @@ -97,6 +97,7 @@ private:\n>>  \tSharedMemObject<DebayerParams> sharedParams_;\n>>  \tDebayerParams debayerParams_;\n>>  \tDmaBufAllocator dmaHeap_;\n>> +\tbool ccmEnabled_;\n>>  \n>>  \tstd::unique_ptr<ipa::soft::IPAProxySoft> ipa_;\n>>  };\n>> diff --git a/include/libcamera/ipa/soft.mojom b/include/libcamera/ipa/soft.mojom\n>> index d52e6f1a..ede74413 100644\n>> --- a/include/libcamera/ipa/soft.mojom\n>> +++ b/include/libcamera/ipa/soft.mojom\n>> @@ -17,7 +17,7 @@ interface IPASoftInterface {\n>>  \t     libcamera.SharedFD fdStats,\n>>  \t     libcamera.SharedFD fdParams,\n>>  \t     libcamera.ControlInfoMap sensorCtrlInfoMap)\n>> -\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls);\n>> +\t\t=> (int32 ret, libcamera.ControlInfoMap ipaControls, bool ccmEnabled);\n>>  \tstart() => (int32 ret);\n>>  \tstop();\n>>  \tconfigure(IPAConfigInfo configInfo)\n>> diff --git a/src/ipa/simple/algorithms/ccm.cpp b/src/ipa/simple/algorithms/ccm.cpp\n>> index 069a12f8..c50eb17d 100644\n>> --- a/src/ipa/simple/algorithms/ccm.cpp\n>> +++ b/src/ipa/simple/algorithms/ccm.cpp\n>> @@ -34,6 +34,8 @@ int Ccm::init([[maybe_unused]] IPAContext &context, const YamlObject &tuningData\n>>  \t\treturn ret;\n>>  \t}\n>>  \n>> +\tcontext.ccmEnabled = true;\n>> +\n>>  \treturn 0;\n>>  }\n>>  \n>> diff --git a/src/ipa/simple/ipa_context.h b/src/ipa/simple/ipa_context.h\n>> index bd6c66d8..40c13731 100644\n>> --- a/src/ipa/simple/ipa_context.h\n>> +++ b/src/ipa/simple/ipa_context.h\n>> @@ -82,6 +82,7 @@ struct IPAContext {\n>>  \tIPAActiveState activeState;\n>>  \tFCQueue<IPAFrameContext> frameContexts;\n>>  \tControlInfoMap::Map ctrlMap;\n>> +\tbool ccmEnabled;\n>>  };\n>>  \n>>  } /* namespace ipa::soft */\n>> diff --git a/src/ipa/simple/soft_simple.cpp b/src/ipa/simple/soft_simple.cpp\n>> index b26e4e15..a87c6cdd 100644\n>> --- a/src/ipa/simple/soft_simple.cpp\n>> +++ b/src/ipa/simple/soft_simple.cpp\n>> @@ -51,7 +51,8 @@ public:\n>>  \t\t const SharedFD &fdStats,\n>>  \t\t const SharedFD &fdParams,\n>>  \t\t const ControlInfoMap &sensorInfoMap,\n>> -\t\t ControlInfoMap *ipaControls) override;\n>> +\t\t ControlInfoMap *ipaControls,\n>> +\t\t bool *ccmEnabled) override;\n>>  \tint configure(const IPAConfigInfo &configInfo) override;\n>>  \n>>  \tint start() override;\n>> @@ -89,7 +90,8 @@ int IPASoftSimple::init(const IPASettings &settings,\n>>  \t\t\tconst SharedFD &fdStats,\n>>  \t\t\tconst SharedFD &fdParams,\n>>  \t\t\tconst ControlInfoMap &sensorInfoMap,\n>> -\t\t\tControlInfoMap *ipaControls)\n>> +\t\t\tControlInfoMap *ipaControls,\n>> +\t\t\tbool *ccmEnabled)\n>>  {\n>>  \tcamHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel);\n>>  \tif (!camHelper_) {\n>> @@ -125,6 +127,8 @@ int IPASoftSimple::init(const IPASettings &settings,\n>>  \tif (ret)\n>>  \t\treturn ret;\n>>  \n>> +\t*ccmEnabled = context_.ccmEnabled;\n>> +\n>>  \tparams_ = nullptr;\n>>  \tstats_ = nullptr;\n>>  \n>> diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp\n>> index f0b83261..45fe6960 100644\n>> --- a/src/libcamera/software_isp/debayer.cpp\n>> +++ b/src/libcamera/software_isp/debayer.cpp\n>> @@ -57,10 +57,11 @@ Debayer::~Debayer()\n>>  }\n>>  \n>>  /**\n>> - * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n>> + * \\fn int Debayer::configure(const StreamConfiguration &inputCfg, const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs, bool ccmEnabled)\n>\n> If there are no overloads of the function, you can write\n>\n>  * \\fn int Debayer::configure()\n>\n> and doxygen will figure it out.\n\nI see OK.\n\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n>>   * \\brief Configure the debayer object according to the passed in parameters\n>>   * \\param[in] inputCfg The input configuration\n>>   * \\param[in] outputCfgs The output configurations\n>> + * \\param[in] ccmEnabled Whether a color correction matrix is applied\n>>   *\n>>   * \\return 0 on success, a negative errno on failure\n>>   */\n>> diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h\n>> index d7ca060d..ba033d44 100644\n>> --- a/src/libcamera/software_isp/debayer.h\n>> +++ b/src/libcamera/software_isp/debayer.h\n>> @@ -33,7 +33,8 @@ public:\n>>  \tvirtual ~Debayer() = 0;\n>>  \n>>  \tvirtual int configure(const StreamConfiguration &inputCfg,\n>> -\t\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs) = 0;\n>> +\t\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n>> +\t\t\t      bool ccmEnabled) = 0;\n>>  \n>>  \tvirtual std::vector<PixelFormat> formats(PixelFormat inputFormat) = 0;\n>>  \n>> diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp\n>> index 01cfb36b..0cd03a8f 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.cpp\n>> +++ b/src/libcamera/software_isp/debayer_cpu.cpp\n>> @@ -114,7 +114,7 @@ DebayerCpu::~DebayerCpu() = default;\n>>  \t\t(prev[x] + curr[x - p] + curr[x + n] + next[x]) / (4 * (div)),         \\\n>>  \t\tcurr[x] / (div))\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint8_t)\n>> @@ -125,7 +125,7 @@ void DebayerCpu::debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint8_t)\n>> @@ -136,7 +136,7 @@ void DebayerCpu::debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint16_t)\n>> @@ -148,7 +148,7 @@ void DebayerCpu::debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint16_t)\n>> @@ -160,7 +160,7 @@ void DebayerCpu::debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint16_t)\n>> @@ -172,7 +172,7 @@ void DebayerCpu::debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tDECLARE_SRC_POINTERS(uint16_t)\n>> @@ -184,7 +184,7 @@ void DebayerCpu::debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tconst int widthInBytes = window_.width * 5 / 4;\n>> @@ -210,7 +210,7 @@ void DebayerCpu::debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tconst int widthInBytes = window_.width * 5 / 4;\n>> @@ -231,7 +231,7 @@ void DebayerCpu::debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tconst int widthInBytes = window_.width * 5 / 4;\n>> @@ -252,7 +252,7 @@ void DebayerCpu::debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  \t}\n>>  }\n>>  \n>> -template<bool addAlphaByte>\n>> +template<bool addAlphaByte, bool ccmEnabled>\n>>  void DebayerCpu::debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[])\n>>  {\n>>  \tconst int widthInBytes = window_.width * 5 / 4;\n>> @@ -368,11 +368,17 @@ int DebayerCpu::setupStandardBayerOrder(BayerFormat::Order order)\n>>  \treturn 0;\n>>  }\n>>  \n>> -#define SET_DEBAYER_METHODS(method0, method1)                                                \\\n>> -\tdebayer0_ = addAlphaByte ? &DebayerCpu::method0<true> : &DebayerCpu::method0<false>; \\\n>> -\tdebayer1_ = addAlphaByte ? &DebayerCpu::method1<true> : &DebayerCpu::method1<false>;\n>> -\n>> -int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat)\n>> +#define SET_DEBAYER_METHODS(method0, method1)                                                                        \\\n>> +\tdebayer0_ = addAlphaByte                                                                                     \\\n>> +\t\t\t    ? (ccmEnabled ? &DebayerCpu::method0<true, true> : &DebayerCpu::method0<true, false>)    \\\n>> +\t\t\t    : (ccmEnabled ? &DebayerCpu::method0<false, true> : &DebayerCpu::method0<false, false>); \\\n>> +\tdebayer1_ = addAlphaByte                                                                                     \\\n>> +\t\t\t    ? (ccmEnabled ? &DebayerCpu::method1<true, true> : &DebayerCpu::method1<true, false>)    \\\n>> +\t\t\t    : (ccmEnabled ? &DebayerCpu::method1<false, true> : &DebayerCpu::method1<false, false>);\n>> +\n>> +int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat,\n>> +\t\t\t\t    PixelFormat outputFormat,\n>> +\t\t\t\t    bool ccmEnabled)\n>>  {\n>>  \tBayerFormat bayerFormat =\n>>  \t\tBayerFormat::fromPixelFormat(inputFormat);\n>> @@ -464,7 +470,8 @@ int DebayerCpu::setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputF\n>>  }\n>>  \n>>  int DebayerCpu::configure(const StreamConfiguration &inputCfg,\n>> -\t\t\t  const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs)\n>> +\t\t\t  const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n>> +\t\t\t  bool ccmEnabled)\n>>  {\n>>  \tif (getInputConfig(inputCfg.pixelFormat, inputConfig_) != 0)\n>>  \t\treturn -EINVAL;\n>> @@ -503,7 +510,10 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg,\n>>  \t\treturn -EINVAL;\n>>  \t}\n>>  \n>> -\tif (setDebayerFunctions(inputCfg.pixelFormat, outputCfg.pixelFormat) != 0)\n>> +\tint ret = setDebayerFunctions(inputCfg.pixelFormat,\n>> +\t\t\t\t      outputCfg.pixelFormat,\n>> +\t\t\t\t      ccmEnabled);\n>> +\tif (ret != 0)\n>>  \t\treturn -EINVAL;\n>>  \n>>  \twindow_.x = ((inputCfg.size.width - outputCfg.size.width) / 2) &\n>> diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h\n>> index 2c47e7c6..21c08a2d 100644\n>> --- a/src/libcamera/software_isp/debayer_cpu.h\n>> +++ b/src/libcamera/software_isp/debayer_cpu.h\n>> @@ -1,7 +1,7 @@\n>>  /* SPDX-License-Identifier: LGPL-2.1-or-later */\n>>  /*\n>>   * Copyright (C) 2023, Linaro Ltd\n>> - * Copyright (C) 2023, Red Hat Inc.\n>> + * Copyright (C) 2023-2025 Red Hat Inc.\n>>   *\n>>   * Authors:\n>>   * Hans de Goede <hdegoede@redhat.com>\n>> @@ -31,7 +31,8 @@ public:\n>>  \t~DebayerCpu();\n>>  \n>>  \tint configure(const StreamConfiguration &inputCfg,\n>> -\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs);\n>> +\t\t      const std::vector<std::reference_wrapper<StreamConfiguration>> &outputCfgs,\n>> +\t\t      bool ccmEnabled);\n>>  \tSize patternSize(PixelFormat inputFormat);\n>>  \tstd::vector<PixelFormat> formats(PixelFormat input);\n>>  \tstd::tuple<unsigned int, unsigned int>\n>> @@ -85,28 +86,28 @@ private:\n>>  \tusing debayerFn = void (DebayerCpu::*)(uint8_t *dst, const uint8_t *src[]);\n>>  \n>>  \t/* 8-bit raw bayer format */\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer8_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer8_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>  \t/* unpacked 10-bit raw bayer format */\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>  \t/* unpacked 12-bit raw bayer format */\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer12_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer12_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>  \t/* CSI-2 packed 10-bit raw bayer format (all the 4 orders) */\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10P_BGBG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10P_GRGR_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10P_GBGB_BGR888(uint8_t *dst, const uint8_t *src[]);\n>> -\ttemplate<bool addAlphaByte>\n>> +\ttemplate<bool addAlphaByte, bool ccmEnabled>\n>>  \tvoid debayer10P_RGRG_BGR888(uint8_t *dst, const uint8_t *src[]);\n>>  \n>>  \tstruct DebayerInputConfig {\n>> @@ -125,7 +126,9 @@ private:\n>>  \tint getInputConfig(PixelFormat inputFormat, DebayerInputConfig &config);\n>>  \tint getOutputConfig(PixelFormat outputFormat, DebayerOutputConfig &config);\n>>  \tint setupStandardBayerOrder(BayerFormat::Order order);\n>> -\tint setDebayerFunctions(PixelFormat inputFormat, PixelFormat outputFormat);\n>> +\tint setDebayerFunctions(PixelFormat inputFormat,\n>> +\t\t\t\tPixelFormat outputFormat,\n>> +\t\t\t\tbool ccmEnabled);\n>>  \tvoid setupInputMemcpy(const uint8_t *linePointers[]);\n>>  \tvoid shiftLinePointers(const uint8_t *linePointers[], const uint8_t *src);\n>>  \tvoid memcpyNextLine(const uint8_t *linePointers[]);\n>> diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp\n>> index 44baf200..b03c4baa 100644\n>> --- a/src/libcamera/software_isp/software_isp.cpp\n>> +++ b/src/libcamera/software_isp/software_isp.cpp\n>> @@ -128,7 +128,8 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,\n>>  \t\t\t     debayer_->getStatsFD(),\n>>  \t\t\t     sharedParams_.fd(),\n>>  \t\t\t     sensor->controls(),\n>> -\t\t\t     ipaControls);\n>> +\t\t\t     ipaControls,\n>> +\t\t\t     &ccmEnabled_);\n>>  \tif (ret) {\n>>  \t\tLOG(SoftwareIsp, Error) << \"IPA init failed\";\n>>  \t\tdebayer_.reset();\n>> @@ -240,7 +241,7 @@ int SoftwareIsp::configure(const StreamConfiguration &inputCfg,\n>>  \tif (ret < 0)\n>>  \t\treturn ret;\n>>  \n>> -\treturn debayer_->configure(inputCfg, outputCfgs);\n>> +\treturn debayer_->configure(inputCfg, outputCfgs, ccmEnabled_);\n>>  }\n>>  \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 88467C32F1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue,  4 Feb 2025 15:18:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9E440685B7;\n\tTue,  4 Feb 2025 16:18:56 +0100 (CET)","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 81FB8685A7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  4 Feb 2025 16:18:54 +0100 (CET)","from mail-ej1-f70.google.com (mail-ej1-f70.google.com\n\t[209.85.218.70]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-511-qzbh3CFsOIag0APtaikGdA-1; Tue, 04 Feb 2025 10:18:52 -0500","by mail-ej1-f70.google.com with SMTP id\n\ta640c23a62f3a-ab69e4c2563so207246166b.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 04 Feb 2025 07:18:51 -0800 (PST)","from mzamazal-thinkpadp1gen3.tpbc.csb\n\t(ip-77-48-47-2.net.vodafone.cz. [77.48.47.2])\n\tby smtp.gmail.com with ESMTPSA id\n\ta640c23a62f3a-ab6e4a310f1sm945983066b.136.2025.02.04.07.18.49\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 04 Feb 2025 07:18:49 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"FzcDrH8V\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1738682333;\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=4V+Lc2IPNXnnAwq/tefwEwaj7HBHxPP3G8XWhJY0N4w=;\n\tb=FzcDrH8VHyLEnKb/2bK+QBXDK2/+2i03Gu31l5ZnbUiWPQNK2Ud/KbaiHaWGo/kWkOOKzY\n\tEyXNIYkozrTSZ5BHFBYf+8InwqqsioNc/m829zJ8dprgwe6vrxirzC621B/2CWpFDJs5nk\n\tEx5UaylREnzTRz6SrhzQAFB4Zh6nbPE=","X-MC-Unique":"qzbh3CFsOIag0APtaikGdA-1","X-Mimecast-MFC-AGG-ID":"qzbh3CFsOIag0APtaikGdA","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1738682331; x=1739287131;\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=4V+Lc2IPNXnnAwq/tefwEwaj7HBHxPP3G8XWhJY0N4w=;\n\tb=EM0QAPdlNPJ/R+mf0wZ86NfxZY7zQhul0cxwC79pK/TDf19BN46ARpaT/7exl4NMmE\n\tlF6piGKIH8frVjuWZlezC/gbh6bWbUtUcMAQBLP4H72yR49qiNLgS7o59I+kUCDBVE4A\n\tMHOIgZEi4KSZJThT3tfR/86Uda7YcsfBNFAbgSOzIoL6S8LwpIFP5hkjK0QyB9SMUidc\n\tT+bE+7vXIdQhPHOgq2VhWNiGsjjNE38/oeuHyL+rnPyAelfRihPYL6+shbvKDor8s5kc\n\tNktcE1JXB82lcxzx4GmKog9lyV05kh/WwmhqJN2mzTXNPRsqGA2HBTP731DOBuCtSlM+\n\tzOLg==","X-Gm-Message-State":"AOJu0Ywa+ZLHcjkwtHW+OnRfadIK2bPnBZ8u2FQcvBWTunJxjiX8BQI1\n\tuawdWV9vxxYz6zaE59bnfCTtJXCzSnSqFSWbN6bQAhsr1sBJF9chGUGjNf5dUMOFB4kp1tVgKde\n\tl4j+avIjL0gUmsp3ZBEcoM0h7JBfo2Y5qOd0V/rwFEVfTlFMGRI6Fo6lkPJRyGBE7yL63IG4=","X-Gm-Gg":"ASbGncsegWTFo8Ft8AKuFOszHVyuj14QvRGrIjE6DqyFbfn5JLluoBPJNg8+oIjHpBl\n\t2BzMoSNTX0IvNDpDONVM5DMxNx6ENP4hLxQoGTFqf6f5YYNd3LT5X8FOE1GefZGqDag1t/suOOl\n\t7r7A6dmd4FjnToJxr5/zcvhLW1+GoDamEQaVomcowH3+veXEW3z7DO/0JwF5r+MUhJhpASpiXsU\n\tsnT40ri4Zx+APJuVlkl65vZ0xaA1nD29F32aZ9b+5cl/nNnezEtcY/mbAh5YjG3UK9Ltuw9feyT\n\tT0sk13wgmcZcPO3M7lPRAdBEglqrE5xy7ClSGWE9gdP7G6+xmR3+c8kf+Q==","X-Received":["by 2002:a17:907:72d2:b0:ab6:8a4a:a6cd with SMTP id\n\ta640c23a62f3a-ab6cfda4112mr3099391166b.35.1738682330564; \n\tTue, 04 Feb 2025 07:18:50 -0800 (PST)","by 2002:a17:907:72d2:b0:ab6:8a4a:a6cd with SMTP id\n\ta640c23a62f3a-ab6cfda4112mr3099386766b.35.1738682330054; \n\tTue, 04 Feb 2025 07:18:50 -0800 (PST)"],"X-Google-Smtp-Source":"AGHT+IHlPXwshLltBWAr/bd9yfrQOpP1ijNkLso/P3RjOir59VzzbU48vYDbI8VpfSV4CwRf3THhMA==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org,  Robert Mader\n\t<robert.mader@collabora.com>,  Hans de Goede <hdegoede@redhat.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>","Subject":"Re: [PATCH v5 09/10] libcamera: software_isp: Track whether CCM is\n\tenabled","In-Reply-To":"<20250203015205.GN12673@pendragon.ideasonboard.com> (Laurent\n\tPinchart's message of \"Mon, 3 Feb 2025 03:52:05 +0200\")","References":"<20250130181449.130492-1-mzamazal@redhat.com>\n\t<20250130181449.130492-10-mzamazal@redhat.com>\n\t<20250203015205.GN12673@pendragon.ideasonboard.com>","Date":"Tue, 04 Feb 2025 16:18:48 +0100","Message-ID":"<85seot68mf.fsf@mzamazal-thinkpadp1gen3.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"jIONEQRrdacMyde68V02UXw4l3weocATC5jSyWYK6lk_1738682331","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>"}}]