[v7,6/8] ipa: softisp: Rename IPASoftSimple to IPASoftIsp
diff mbox series

Message ID 20260812185055.289021-7-johannes.goede@oss.qualcomm.com
State New
Headers show
Series
  • ipa: Allow IPA creation by name
Related show

Commit Message

Hans de Goede Aug. 12, 2026, 6:50 p.m. UTC
The simple_soft IPA is the IPA for the software ISP and the software ISP
may be plugged into any pipeline, drop the Simple part from the class
names and replace Soft with SoftIsp.

Also rename the IPA.so file from soft_simple to softisp.

Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 .../internal/software_isp/software_isp.h      |  2 +-
 include/libcamera/ipa/softisp.mojom           |  4 +-
 src/ipa/softisp/algorithms/adjust.cpp         |  8 +-
 src/ipa/softisp/algorithms/agc.cpp            |  8 +-
 src/ipa/softisp/algorithms/awb.cpp            | 16 ++--
 src/ipa/softisp/algorithms/awb.h              |  6 +-
 src/ipa/softisp/algorithms/blc.cpp            |  6 +-
 src/ipa/softisp/algorithms/ccm.cpp            |  2 +-
 src/ipa/softisp/algorithms/meson.build        |  2 +-
 src/ipa/softisp/ipa_context.h                 |  2 +-
 src/ipa/softisp/meson.build                   | 10 +--
 .../softisp/{soft_simple.cpp => softisp.cpp}  | 74 +++++++++----------
 src/libcamera/software_isp/software_isp.cpp   |  2 +-
 13 files changed, 71 insertions(+), 71 deletions(-)
 rename src/ipa/softisp/{soft_simple.cpp => softisp.cpp} (83%)

Patch
diff mbox series

diff --git a/include/libcamera/internal/software_isp/software_isp.h b/include/libcamera/internal/software_isp/software_isp.h
index 3205a2e14..2363a91c8 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -101,7 +101,7 @@  private:
 	DmaBufAllocator dmaHeap_;
 	bool ccmEnabled_;
 
-	std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
+	std::unique_ptr<ipa::soft::IPAProxySoftIsp> ipa_;
 	std::deque<FrameBuffer *> queuedInputBuffers_;
 	std::deque<FrameBuffer *> queuedOutputBuffers_;
 };
diff --git a/include/libcamera/ipa/softisp.mojom b/include/libcamera/ipa/softisp.mojom
index 77328c5fd..66cf311b3 100644
--- a/include/libcamera/ipa/softisp.mojom
+++ b/include/libcamera/ipa/softisp.mojom
@@ -12,7 +12,7 @@  struct IPAConfigInfo {
 	libcamera.ControlInfoMap sensorControls;
 };
 
-interface IPASoftInterface {
+interface IPASoftIspInterface {
 	init(libcamera.IPASettings settings,
 	     libcamera.SharedFD fdStats,
 	     libcamera.SharedFD fdParams,
@@ -31,7 +31,7 @@  interface IPASoftInterface {
 			     libcamera.ControlList sensorControls);
 };
 
-interface IPASoftEventInterface {
+interface IPASoftIspEventInterface {
 	setSensorControls(libcamera.ControlList sensorControls);
 	setIspParams();
 	metadataReady(uint32 frame, libcamera.ControlList metadata);
diff --git a/src/ipa/softisp/algorithms/adjust.cpp b/src/ipa/softisp/algorithms/adjust.cpp
index 8bf39c4c8..52eb81d76 100644
--- a/src/ipa/softisp/algorithms/adjust.cpp
+++ b/src/ipa/softisp/algorithms/adjust.cpp
@@ -22,7 +22,7 @@  namespace ipa::soft::algorithms {
 constexpr float kDefaultContrast = 1.0f;
 constexpr float kDefaultSaturation = 1.0f;
 
-LOG_DEFINE_CATEGORY(IPASoftAdjust)
+LOG_DEFINE_CATEGORY(IPASoftIspAdjust)
 
 int Adjust::init(IPAContext &context, [[maybe_unused]] const ValueNode &tuningData)
 {
@@ -54,19 +54,19 @@  void Adjust::queueRequest(typename Module::Context &context,
 	const auto &gamma = controls.get(controls::Gamma);
 	if (gamma.has_value()) {
 		context.activeState.knobs.gamma = gamma.value();
-		LOG(IPASoftAdjust, Debug) << "Setting gamma to " << gamma.value();
+		LOG(IPASoftIspAdjust, Debug) << "Setting gamma to " << gamma.value();
 	}
 
 	const auto &contrast = controls.get(controls::Contrast);
 	if (contrast.has_value()) {
 		context.activeState.knobs.contrast = contrast;
-		LOG(IPASoftAdjust, Debug) << "Setting contrast to " << contrast.value();
+		LOG(IPASoftIspAdjust, Debug) << "Setting contrast to " << contrast.value();
 	}
 
 	const auto &saturation = controls.get(controls::Saturation);
 	if (saturation.has_value()) {
 		context.activeState.knobs.saturation = saturation;
-		LOG(IPASoftAdjust, Debug) << "Setting saturation to " << saturation.value();
+		LOG(IPASoftIspAdjust, Debug) << "Setting saturation to " << saturation.value();
 	}
 }
 
diff --git a/src/ipa/softisp/algorithms/agc.cpp b/src/ipa/softisp/algorithms/agc.cpp
index a13a75528..72f000628 100644
--- a/src/ipa/softisp/algorithms/agc.cpp
+++ b/src/ipa/softisp/algorithms/agc.cpp
@@ -17,7 +17,7 @@ 
 
 namespace libcamera {
 
-LOG_DEFINE_CATEGORY(IPASoftExposure)
+LOG_DEFINE_CATEGORY(IPASoftIspExposure)
 
 namespace ipa::soft::algorithms {
 
@@ -118,7 +118,7 @@  void Agc::updateExposure(IPAContext &context, IPAFrameContext &frameContext, dou
 	context.activeState.agc.exposure = exposure;
 	context.activeState.agc.again = again;
 
-	LOG(IPASoftExposure, Debug)
+	LOG(IPASoftIspExposure, Debug)
 		<< "exposureMSV " << exposureMSV
 		<< " error " << error << " factor " << factor
 		<< " exp " << exposure << " again " << again;
@@ -172,7 +172,7 @@  void Agc::process(IPAContext &context,
 	unsigned int num = 0;
 
 	if (yHistValsPerBin == 0) {
-		LOG(IPASoftExposure, Debug)
+		LOG(IPASoftIspExposure, Debug)
 			<< "Not adjusting exposure due to insufficient histogram data";
 		return;
 	}
@@ -183,7 +183,7 @@  void Agc::process(IPAContext &context,
 	}
 
 	for (unsigned int i = 0; i < kExposureBinsCount; i++) {
-		LOG(IPASoftExposure, Debug) << i << ": " << exposureBins[i];
+		LOG(IPASoftIspExposure, Debug) << i << ": " << exposureBins[i];
 		denom += exposureBins[i];
 		num += exposureBins[i] * (i + 1);
 	}
diff --git a/src/ipa/softisp/algorithms/awb.cpp b/src/ipa/softisp/algorithms/awb.cpp
index 0bd6b66ce..84f01b832 100644
--- a/src/ipa/softisp/algorithms/awb.cpp
+++ b/src/ipa/softisp/algorithms/awb.cpp
@@ -16,7 +16,7 @@ 
 
 namespace libcamera {
 
-LOG_DEFINE_CATEGORY(IPASoftAwb)
+LOG_DEFINE_CATEGORY(IPASoftIspAwb)
 
 namespace ipa::soft::algorithms {
 
@@ -25,12 +25,12 @@  namespace ipa::soft::algorithms {
  */
 static constexpr unsigned int kDefaultLux = 500;
 
-class SimpleAwbStats final : public AwbStats
+class SoftIspAwbStats final : public AwbStats
 {
 public:
-	SimpleAwbStats() = default;
+	SoftIspAwbStats() = default;
 
-	SimpleAwbStats(const RGB<double> &rgbMeans)
+	SoftIspAwbStats(const RGB<double> &rgbMeans)
 	{
 		rgbMeans_ = rgbMeans;
 
@@ -112,8 +112,8 @@  void Awb::prepare(IPAContext &context,
 	params->gains = frameContext.awb.gains;
 }
 
-SimpleAwbStats Awb::calculateRgbMeans(IPAContext &context,
-				      const SwIspStats *stats) const
+SoftIspAwbStats Awb::calculateRgbMeans(IPAContext &context,
+				       const SwIspStats *stats) const
 {
 	if (!stats->valid)
 		return {};
@@ -141,7 +141,7 @@  SimpleAwbStats Awb::calculateRgbMeans(IPAContext &context,
 				   static_cast<double>(sum.g()) / nPixels,
 				   static_cast<double>(sum.b()) / nPixels } };
 
-	return SimpleAwbStats(rgbMeans);
+	return SoftIspAwbStats(rgbMeans);
 }
 
 /**
@@ -151,7 +151,7 @@  void Awb::process(IPAContext &context, [[maybe_unused]] const uint32_t frame,
 		  IPAFrameContext &frameContext, const SwIspStats *stats,
 		  ControlList &metadata)
 {
-	SimpleAwbStats awbStats = calculateRgbMeans(context, stats);
+	SoftIspAwbStats awbStats = calculateRgbMeans(context, stats);
 
 	awbAlgo_.process(context.activeState.awb, frameContext.awb, awbStats,
 			 kDefaultLux, metadata);
diff --git a/src/ipa/softisp/algorithms/awb.h b/src/ipa/softisp/algorithms/awb.h
index 59ab6fd79..37893932b 100644
--- a/src/ipa/softisp/algorithms/awb.h
+++ b/src/ipa/softisp/algorithms/awb.h
@@ -22,7 +22,7 @@  namespace libcamera {
 
 namespace ipa::soft::algorithms {
 
-class SimpleAwbStats;
+class SoftIspAwbStats;
 
 class Awb : public Algorithm
 {
@@ -48,8 +48,8 @@  public:
 		     ControlList &metadata) override;
 
 private:
-	SimpleAwbStats calculateRgbMeans(IPAContext &context,
-					 const SwIspStats *stats) const;
+	SoftIspAwbStats calculateRgbMeans(IPAContext &context,
+					  const SwIspStats *stats) const;
 
 	/*
 	 * There actually is no Q register format for SoftISP, but allow the
diff --git a/src/ipa/softisp/algorithms/blc.cpp b/src/ipa/softisp/algorithms/blc.cpp
index e45a913cd..fca76f442 100644
--- a/src/ipa/softisp/algorithms/blc.cpp
+++ b/src/ipa/softisp/algorithms/blc.cpp
@@ -17,7 +17,7 @@  namespace libcamera {
 
 namespace ipa::soft::algorithms {
 
-LOG_DEFINE_CATEGORY(IPASoftBL)
+LOG_DEFINE_CATEGORY(IPASoftIspBL)
 
 BlackLevel::BlackLevel()
 {
@@ -90,7 +90,7 @@  void BlackLevel::process(IPAContext &context,
 	const unsigned int total =
 		std::accumulate(begin(histogram), end(histogram), 0);
 	if (total == 0) {
-		LOG(IPASoftBL, Debug) << "Not guessing black level, histogram is empty";
+		LOG(IPASoftIspBL, Debug) << "Not guessing black level, histogram is empty";
 		return;
 	}
 
@@ -107,7 +107,7 @@  void BlackLevel::process(IPAContext &context,
 			context.activeState.blc.level = i * histogramRatio;
 			context.activeState.blc.lastExposure = frameContext.sensor.exposure;
 			context.activeState.blc.lastGain = frameContext.sensor.gain;
-			LOG(IPASoftBL, Debug)
+			LOG(IPASoftIspBL, Debug)
 				<< "Auto-set black level: "
 				<< i << "/" << SwIspStats::kYHistogramSize
 				<< " (" << 100 * (seen - histogram[i]) / total << "% below, "
diff --git a/src/ipa/softisp/algorithms/ccm.cpp b/src/ipa/softisp/algorithms/ccm.cpp
index 8b6da543a..58e17bbeb 100644
--- a/src/ipa/softisp/algorithms/ccm.cpp
+++ b/src/ipa/softisp/algorithms/ccm.cpp
@@ -14,7 +14,7 @@  namespace libcamera {
 
 namespace ipa::soft::algorithms {
 
-LOG_DEFINE_CATEGORY(IPASoftCcm)
+LOG_DEFINE_CATEGORY(IPASoftIspCcm)
 
 /**
  * \copydoc libcamera::ipa::Algorithm::init
diff --git a/src/ipa/softisp/algorithms/meson.build b/src/ipa/softisp/algorithms/meson.build
index 73c637220..d240409e5 100644
--- a/src/ipa/softisp/algorithms/meson.build
+++ b/src/ipa/softisp/algorithms/meson.build
@@ -1,6 +1,6 @@ 
 # SPDX-License-Identifier: CC0-1.0
 
-soft_simple_ipa_algorithms = files([
+softisp_ipa_algorithms = files([
     'adjust.cpp',
     'awb.cpp',
     'agc.cpp',
diff --git a/src/ipa/softisp/ipa_context.h b/src/ipa/softisp/ipa_context.h
index ff312ae8f..bccf95775 100644
--- a/src/ipa/softisp/ipa_context.h
+++ b/src/ipa/softisp/ipa_context.h
@@ -2,7 +2,7 @@ 
 /*
  * Copyright (C) 2024-2026 Red Hat, Inc.
  *
- * Simple pipeline IPA Context
+ * Software ISP IPA Context
  */
 
 #pragma once
diff --git a/src/ipa/softisp/meson.build b/src/ipa/softisp/meson.build
index 2f9f15f4a..755b7eaab 100644
--- a/src/ipa/softisp/meson.build
+++ b/src/ipa/softisp/meson.build
@@ -3,16 +3,16 @@ 
 subdir('algorithms')
 subdir('data')
 
-ipa_name = 'ipa_soft_simple'
+ipa_name = 'ipa_softisp'
 
-soft_simple_sources = files([
+softisp_sources = files([
     'ipa_context.cpp',
-    'soft_simple.cpp',
+    'softisp.cpp',
 ])
 
-soft_simple_sources += soft_simple_ipa_algorithms
+softisp_sources += softisp_ipa_algorithms
 
-mod = shared_module(ipa_name, soft_simple_sources,
+mod = shared_module(ipa_name, softisp_sources,
                     name_prefix : '',
                     include_directories : [ipa_includes],
                     dependencies : [libcamera_private, libipa_dep],
diff --git a/src/ipa/softisp/soft_simple.cpp b/src/ipa/softisp/softisp.cpp
similarity index 83%
rename from src/ipa/softisp/soft_simple.cpp
rename to src/ipa/softisp/softisp.cpp
index e84feeea7..111325d7d 100644
--- a/src/ipa/softisp/soft_simple.cpp
+++ b/src/ipa/softisp/softisp.cpp
@@ -2,7 +2,7 @@ 
 /*
  * Copyright (C) 2023, Linaro Ltd
  *
- * Simple Software Image Processing Algorithm module
+ * Software ISP Image Processing Algorithm module
  */
 
 #include <chrono>
@@ -32,7 +32,7 @@ 
 #include "module.h"
 
 namespace libcamera {
-LOG_DEFINE_CATEGORY(IPASoft)
+LOG_DEFINE_CATEGORY(IPASoftIsp)
 
 using namespace std::literals::chrono_literals;
 
@@ -41,15 +41,15 @@  namespace ipa::soft {
 /* Maximum number of frame contexts to be held */
 static constexpr uint32_t kMaxFrameContexts = 16;
 
-class IPASoftSimple : public ipa::soft::IPASoftInterface, public Module
+class IPASoftIsp : public ipa::soft::IPASoftIspInterface, public Module
 {
 public:
-	IPASoftSimple()
+	IPASoftIsp()
 		: context_(kMaxFrameContexts)
 	{
 	}
 
-	~IPASoftSimple();
+	~IPASoftIsp();
 
 	int init(const IPASettings &settings,
 		 const SharedFD &fdStats,
@@ -83,7 +83,7 @@  private:
 	struct IPAContext context_;
 };
 
-IPASoftSimple::~IPASoftSimple()
+IPASoftIsp::~IPASoftIsp()
 {
 	if (stats_)
 		munmap(stats_, sizeof(SwIspStats));
@@ -91,17 +91,17 @@  IPASoftSimple::~IPASoftSimple()
 		munmap(params_, sizeof(DebayerParams));
 }
 
-int IPASoftSimple::init(const IPASettings &settings,
-			const SharedFD &fdStats,
-			const SharedFD &fdParams,
-			const IPACameraSensorInfo &sensorInfo,
-			const ControlInfoMap &sensorControls,
-			ControlInfoMap *ipaControls,
-			bool *ccmEnabled)
+int IPASoftIsp::init(const IPASettings &settings,
+		     const SharedFD &fdStats,
+		     const SharedFD &fdParams,
+		     const IPACameraSensorInfo &sensorInfo,
+		     const ControlInfoMap &sensorControls,
+		     ControlInfoMap *ipaControls,
+		     bool *ccmEnabled)
 {
 	camHelper_ = CameraSensorHelperFactoryBase::create(settings.sensorModel);
 	if (!camHelper_) {
-		LOG(IPASoft, Warning)
+		LOG(IPASoftIsp, Warning)
 			<< "Failed to create camera sensor helper for "
 			<< settings.sensorModel;
 	}
@@ -112,7 +112,7 @@  int IPASoftSimple::init(const IPASettings &settings,
 	File file(settings.configurationFile);
 	if (!file.open(File::OpenModeFlag::ReadOnly)) {
 		int ret = file.error();
-		LOG(IPASoft, Error)
+		LOG(IPASoftIsp, Error)
 			<< "Failed to open configuration file "
 			<< settings.configurationFile << ": " << strerror(-ret);
 		return ret;
@@ -124,10 +124,10 @@  int IPASoftSimple::init(const IPASettings &settings,
 
 	/* \todo Use the IPA configuration file for real. */
 	unsigned int version = (*data)["version"].get<uint32_t>(0);
-	LOG(IPASoft, Debug) << "Tuning file version " << version;
+	LOG(IPASoftIsp, Debug) << "Tuning file version " << version;
 
 	if (!data->contains("algorithms")) {
-		LOG(IPASoft, Error) << "Tuning file doesn't contain algorithms";
+		LOG(IPASoftIsp, Error) << "Tuning file doesn't contain algorithms";
 		return -EINVAL;
 	}
 
@@ -141,12 +141,12 @@  int IPASoftSimple::init(const IPASettings &settings,
 	stats_ = nullptr;
 
 	if (!fdStats.isValid()) {
-		LOG(IPASoft, Error) << "Invalid Statistics handle";
+		LOG(IPASoftIsp, Error) << "Invalid Statistics handle";
 		return -ENODEV;
 	}
 
 	if (!fdParams.isValid()) {
-		LOG(IPASoft, Error) << "Invalid Parameters handle";
+		LOG(IPASoftIsp, Error) << "Invalid Parameters handle";
 		return -ENODEV;
 	}
 
@@ -154,7 +154,7 @@  int IPASoftSimple::init(const IPASettings &settings,
 		void *mem = mmap(nullptr, sizeof(DebayerParams), PROT_WRITE,
 				 MAP_SHARED, fdParams.get(), 0);
 		if (mem == MAP_FAILED) {
-			LOG(IPASoft, Error) << "Unable to map Parameters";
+			LOG(IPASoftIsp, Error) << "Unable to map Parameters";
 			return -errno;
 		}
 
@@ -170,7 +170,7 @@  int IPASoftSimple::init(const IPASettings &settings,
 		void *mem = mmap(nullptr, sizeof(SwIspStats), PROT_READ,
 				 MAP_SHARED, fdStats.get(), 0);
 		if (mem == MAP_FAILED) {
-			LOG(IPASoft, Error) << "Unable to map Statistics";
+			LOG(IPASoftIsp, Error) << "Unable to map Statistics";
 			return -errno;
 		}
 
@@ -187,19 +187,19 @@  int IPASoftSimple::init(const IPASettings &settings,
 	 * for V4L2_CID_EXPOSURE depend on the configured sensor resolution.
 	 */
 	if (sensorControls.find(V4L2_CID_EXPOSURE) == sensorControls.end()) {
-		LOG(IPASoft, Error) << "Don't have exposure control";
+		LOG(IPASoftIsp, Error) << "Don't have exposure control";
 		return -EINVAL;
 	}
 
 	if (sensorControls.find(V4L2_CID_ANALOGUE_GAIN) == sensorControls.end()) {
-		LOG(IPASoft, Error) << "Don't have gain control";
+		LOG(IPASoftIsp, Error) << "Don't have gain control";
 		return -EINVAL;
 	}
 
 	return 0;
 }
 
-int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
+int IPASoftIsp::configure(const IPAConfigInfo &configInfo)
 {
 	sensorInfoMap_ = configInfo.sensorControls;
 
@@ -216,7 +216,7 @@  int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
 	context_.configuration.agc.exposureMin = exposureInfo.min().get<int32_t>();
 	context_.configuration.agc.exposureMax = exposureInfo.max().get<int32_t>();
 	if (!context_.configuration.agc.exposureMin) {
-		LOG(IPASoft, Warning) << "Minimum exposure is zero, that can't be linear";
+		LOG(IPASoftIsp, Warning) << "Minimum exposure is zero, that can't be linear";
 		context_.configuration.agc.exposureMin = 1;
 	}
 
@@ -255,7 +255,7 @@  int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
 			return ret;
 	}
 
-	LOG(IPASoft, Info)
+	LOG(IPASoftIsp, Info)
 		<< "Exposure " << context_.configuration.agc.exposureMin << "-"
 		<< context_.configuration.agc.exposureMax
 		<< ", gain " << context_.configuration.agc.againMin << "-"
@@ -265,17 +265,17 @@  int IPASoftSimple::configure(const IPAConfigInfo &configInfo)
 	return 0;
 }
 
-int IPASoftSimple::start()
+int IPASoftIsp::start()
 {
 	return 0;
 }
 
-void IPASoftSimple::stop()
+void IPASoftIsp::stop()
 {
 	context_.frameContexts.clear();
 }
 
-void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &controls)
+void IPASoftIsp::queueRequest(const uint32_t frame, const ControlList &controls)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.alloc(frame);
 
@@ -283,7 +283,7 @@  void IPASoftSimple::queueRequest(const uint32_t frame, const ControlList &contro
 		algo->queueRequest(context_, frame, frameContext, controls);
 }
 
-void IPASoftSimple::computeParams(const uint32_t frame)
+void IPASoftIsp::computeParams(const uint32_t frame)
 {
 	context_.activeState.combinedMatrix = Matrix<float, 3, 3>::identity();
 
@@ -295,9 +295,9 @@  void IPASoftSimple::computeParams(const uint32_t frame)
 	setIspParams.emit();
 }
 
-void IPASoftSimple::processStats(const uint32_t frame,
-				 [[maybe_unused]] const uint32_t bufferId,
-				 const ControlList &sensorControls)
+void IPASoftIsp::processStats(const uint32_t frame,
+			      [[maybe_unused]] const uint32_t bufferId,
+			      const ControlList &sensorControls)
 {
 	IPAFrameContext &frameContext = context_.frameContexts.get(frame);
 
@@ -314,7 +314,7 @@  void IPASoftSimple::processStats(const uint32_t frame,
 	/* Sanity check */
 	if (!sensorControls.contains(V4L2_CID_EXPOSURE) ||
 	    !sensorControls.contains(V4L2_CID_ANALOGUE_GAIN)) {
-		LOG(IPASoft, Error) << "Control(s) missing";
+		LOG(IPASoftIsp, Error) << "Control(s) missing";
 		return;
 	}
 
@@ -328,9 +328,9 @@  void IPASoftSimple::processStats(const uint32_t frame,
 	setSensorControls.emit(ctrls);
 }
 
-std::string IPASoftSimple::logPrefix() const
+std::string IPASoftIsp::logPrefix() const
 {
-	return "IPASoft";
+	return "IPASoftIsp";
 }
 
 } /* namespace ipa::soft */
@@ -347,7 +347,7 @@  const struct IPAModuleInfo ipaModuleInfo = {
 
 IPAInterface *ipaCreate()
 {
-	return new ipa::soft::IPASoftSimple();
+	return new ipa::soft::IPASoftIsp();
 }
 
 } /* extern "C" */
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index c7165771c..d1fe02a2e 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -136,7 +136,7 @@  SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
 	debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
 	debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
 
-	ipa_ = pipe->createIPA<ipa::soft::IPAProxySoft>(0, 0);
+	ipa_ = pipe->createIPA<ipa::soft::IPAProxySoftIsp>(0, 0);
 	if (!ipa_) {
 		LOG(SoftwareIsp, Error)
 			<< "Creating IPA for software ISP failed";