[06/16] libcamera: software_isp: Allocate multiple parameters buffers
diff mbox series

Message ID 20240812115009.946036-7-mzamazal@redhat.com
State New
Headers show
Series
  • Software ISP: Share params and stats buffers
Related show

Commit Message

Milan Zamazal Aug. 12, 2024, 11:49 a.m. UTC
We want to use more than one parameters buffer.  Processing statistics
(and setting the corresponding parameters) is asynchronous and may work
with a parameters buffer while the last parameters buffer may be in or
wait for use in debayering.

The question is how many buffer we need.  A starting idea might be to
use the same number as for input and output buffers.  This may not be
necessarily the best or even correct idea, but if the number of those
buffers is sufficient now then perhaps the same number of the parameters
buffers (and later statistics buffers) would work.  Unless multiple
streams are used...

Nevertheless, the number of the input and output buffers is currently
fixed, which makes it possible to use in init, before configure, where
the current single buffer is allocated.  It just requires to make the
given constant public in SimplePipelineHandler so that it can be passed
to the SoftwareIsp constructor.

Another alternative would be to determine the right number of buffers in
SoftwareIsp::configure.  This would be more complicated as it would
require some more refactoring, allocating the buffers in configure and
passing their file descriptors to the IPA and debayering on demand.

Only the first allocated buffer is actually used at the moment.  This
will be changed in the followup patches once support for multiple
buffers is added to the IPA and debayering.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
---
 .../internal/software_isp/software_isp.h          |  6 +++---
 src/libcamera/pipeline/simple/simple.cpp          |  6 +++---
 src/libcamera/software_isp/software_isp.cpp       | 15 ++++++---------
 3 files changed, 12 insertions(+), 15 deletions(-)

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 c2fcc307..8956978c 100644
--- a/include/libcamera/internal/software_isp/software_isp.h
+++ b/include/libcamera/internal/software_isp/software_isp.h
@@ -46,7 +46,8 @@  LOG_DECLARE_CATEGORY(SoftwareIsp)
 class SoftwareIsp
 {
 public:
-	SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor);
+	SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
+		    const unsigned int bufferCount);
 	~SoftwareIsp();
 
 	int loadConfiguration([[maybe_unused]] const std::string &filename) { return 0; }
@@ -94,11 +95,10 @@  private:
 
 	std::unique_ptr<DebayerCpu> debayer_;
 	Thread ispWorkerThread_;
-	static constexpr unsigned int kParamStatBufferCount = 1;
 	std::map<uint32_t, SharedMemObject<DebayerParams>> sharedParams_;
 	DebayerParams debayerParams_;
 	std::queue<uint32_t> availableParams_;
-	bool allocateParamsBuffers();
+	bool allocateParamsBuffers(const unsigned int bufferCount);
 	DmaBufAllocator dmaHeap_;
 
 	std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index f0bcafba..459f617b 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -349,13 +349,12 @@  public:
 	V4L2Subdevice *subdev(const MediaEntity *entity);
 	MediaDevice *converter() { return converter_; }
 	bool swIspEnabled() const { return swIspEnabled_; }
+	static constexpr unsigned int kNumInternalBuffers = 3;
 
 protected:
 	int queueRequestDevice(Camera *camera, Request *request) override;
 
 private:
-	static constexpr unsigned int kNumInternalBuffers = 3;
-
 	struct EntityData {
 		std::unique_ptr<V4L2VideoDevice> video;
 		std::unique_ptr<V4L2Subdevice> subdev;
@@ -531,7 +530,8 @@  int SimpleCameraData::init()
 	 * Instantiate Soft ISP if this is enabled for the given driver and no converter is used.
 	 */
 	if (!converter_ && pipe->swIspEnabled()) {
-		swIsp_ = std::make_unique<SoftwareIsp>(pipe, sensor_.get());
+		swIsp_ = std::make_unique<SoftwareIsp>(pipe, sensor_.get(),
+						       pipe->kNumInternalBuffers);
 		if (!swIsp_->isValid()) {
 			LOG(SimplePipeline, Warning)
 				<< "Failed to create software ISP, disabling software debayering";
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index d78537fc..d48be2d2 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -57,18 +57,15 @@  LOG_DEFINE_CATEGORY(SoftwareIsp)
  * ready
  */
 
-/**
- * \var SoftwareIsp::kParamStatBufferCount
- * \brief The number of stats and params buffers (each of them)
- */
-
 /**
  * \brief Constructs SoftwareIsp object
  * \param[in] pipe The pipeline handler in use
  * \param[in] sensor Pointer to the CameraSensor instance owned by the pipeline
+ * \param[in] bufferCount Number of parameters buffers and stats buffers to allocate
  * handler
  */
-SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor)
+SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
+			 const unsigned bufferCount)
 	: dmaHeap_(DmaBufAllocator::DmaBufAllocatorFlag::CmaHeap |
 		   DmaBufAllocator::DmaBufAllocatorFlag::SystemHeap |
 		   DmaBufAllocator::DmaBufAllocatorFlag::UDmaBuf)
@@ -77,7 +74,7 @@  SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor)
 		LOG(SoftwareIsp, Error) << "Failed to create DmaBufAllocator object";
 		return;
 	}
-	if (!allocateParamsBuffers())
+	if (!allocateParamsBuffers(bufferCount))
 		return;
 
 	auto stats = std::make_unique<SwStatsCpu>();
@@ -129,13 +126,13 @@  SoftwareIsp::~SoftwareIsp()
 	debayer_.reset();
 }
 
-bool SoftwareIsp::allocateParamsBuffers()
+bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount)
 {
 	std::array<uint8_t, 256> gammaTable;
 	for (unsigned int i = 0; i < 256; i++)
 		gammaTable[i] = UINT8_MAX * std::pow(i / 256.0, 0.5);
 
-	for (unsigned int i = 0; i < kParamStatBufferCount; i++) {
+	for (unsigned int i = 0; i < bufferCount; i++) {
 		auto params = SharedMemObject<DebayerParams>("softIsp_params");
 		if (!params) {
 			LOG(SoftwareIsp, Error) << "Failed to create shared memory for parameters";