[PATCH 08/16] libcamera: software_isp: Share parameters buffers with debayering
Milan Zamazal
mzamazal at redhat.com
Mon Aug 12 13:49:57 CEST 2024
Share the multiple parameters buffers with debayering rather than
copying the current parameters buffer there. This is done in a similar
way as sharing the buffers with IPA in the preceding patch.
The last missing step about parameters sharing is to avoid copying the
color lookup arrays in debayering, which will be addressed in the next
patch.
Signed-off-by: Milan Zamazal <mzamazal at redhat.com>
---
src/libcamera/software_isp/debayer.cpp | 3 +-
src/libcamera/software_isp/debayer.h | 3 +-
src/libcamera/software_isp/debayer_cpu.cpp | 36 +++++++++++++++------
src/libcamera/software_isp/debayer_cpu.h | 7 ++--
src/libcamera/software_isp/software_isp.cpp | 6 ++--
5 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/src/libcamera/software_isp/debayer.cpp b/src/libcamera/software_isp/debayer.cpp
index 8bd58c3d..52df8c23 100644
--- a/src/libcamera/software_isp/debayer.cpp
+++ b/src/libcamera/software_isp/debayer.cpp
@@ -94,13 +94,12 @@ Debayer::~Debayer()
*/
/**
- * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output, DebayerParams params)
+ * \fn void Debayer::process(uint32_t frame, const uint32_t paramsBufferId, FrameBuffer *input, FrameBuffer *output)
* \brief Process the bayer data into the requested format
* \param[in] frame The frame number
* \param[in] paramsBufferId The id of the params buffer in use
* \param[in] input The input buffer
* \param[in] output The output buffer
- * \param[in] params The parameters to be used in debayering
*
* \note DebayerParams is passed by value deliberately so that a copy is passed
* when this is run in another thread by invokeMethod().
diff --git a/src/libcamera/software_isp/debayer.h b/src/libcamera/software_isp/debayer.h
index 93020735..251b14fd 100644
--- a/src/libcamera/software_isp/debayer.h
+++ b/src/libcamera/software_isp/debayer.h
@@ -42,8 +42,7 @@ public:
virtual void process(uint32_t frame,
const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output,
- DebayerParams params) = 0;
+ FrameBuffer *input, FrameBuffer *output) = 0;
virtual SizeRange sizes(PixelFormat inputFormat, const Size &inputSize) = 0;
diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
index 20a15ae0..af08ab10 100644
--- a/src/libcamera/software_isp/debayer_cpu.cpp
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
@@ -11,9 +11,10 @@
#include "debayer_cpu.h"
-#include <stdlib.h>
#include <time.h>
+#include <libcamera/base/shared_fd.h>
+
#include <libcamera/formats.h>
#include "libcamera/internal/bayer_format.h"
@@ -32,8 +33,10 @@ namespace libcamera {
/**
* \brief Constructs a DebayerCpu object
* \param[in] stats Pointer to the stats object to use
+ * \param[in] paramBuffers SharedFDs of parameter buffers
*/
-DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats)
+DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶mBuffers)
: stats_(std::move(stats))
{
/*
@@ -49,6 +52,20 @@ DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats)
/* Initialize color lookup tables */
for (unsigned int i = 0; i < DebayerParams::kRGBLookupSize; i++)
red_[i] = green_[i] = blue_[i] = i;
+
+ paramsBuffers_ = std::map<unsigned int, DebayerParams *>();
+
+ for (auto &sharedFd : paramBuffers) {
+ void *mem = mmap(nullptr, sizeof(DebayerParams), PROT_WRITE,
+ MAP_SHARED, sharedFd.get(), 0);
+ if (mem == MAP_FAILED) {
+ LOG(Debayer, Error) << "Unable to map Parameters";
+ return;
+ }
+
+ ASSERT(sharedFd.get() >= 0);
+ paramsBuffers_[sharedFd.get()] = static_cast<DebayerParams *>(mem);
+ }
}
DebayerCpu::~DebayerCpu() = default;
@@ -608,8 +625,7 @@ void DebayerCpu::memcpyNextLine(const uint8_t *linePointers[])
memcpy(lineBuffers_[lineBufferIndex_].data(),
linePointers[patternHeight] - lineBufferPadding_,
lineBufferLength_);
- linePointers[patternHeight] = lineBuffers_[lineBufferIndex_].data()
- + lineBufferPadding_;
+ linePointers[patternHeight] = lineBuffers_[lineBufferIndex_].data() + lineBufferPadding_;
lineBufferIndex_ = (lineBufferIndex_ + 1) % (patternHeight + 1);
}
@@ -726,7 +742,7 @@ static inline int64_t timeDiff(timespec &after, timespec &before)
void DebayerCpu::process(uint32_t frame,
const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output, DebayerParams params)
+ FrameBuffer *input, FrameBuffer *output)
{
timespec frameStartTime;
@@ -735,12 +751,14 @@ void DebayerCpu::process(uint32_t frame,
clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime);
}
- green_ = params.green;
- red_ = swapRedBlueGains_ ? params.blue : params.red;
- blue_ = swapRedBlueGains_ ? params.red : params.blue;
-
+ DebayerParams *params = paramsBuffers_.at(paramsBufferId);
releaseIspParams.emit(paramsBufferId);
+ /* \todo Avoid copying here. */
+ green_ = params->green;
+ red_ = swapRedBlueGains_ ? params->blue : params->red;
+ blue_ = swapRedBlueGains_ ? params->red : params->blue;
+
/* Copy metadata from the input buffer */
FrameMetadata &metadata = output->_d()->metadata();
metadata.status = input->metadata().status;
diff --git a/src/libcamera/software_isp/debayer_cpu.h b/src/libcamera/software_isp/debayer_cpu.h
index 0b5a5258..324fc6c0 100644
--- a/src/libcamera/software_isp/debayer_cpu.h
+++ b/src/libcamera/software_isp/debayer_cpu.h
@@ -16,6 +16,7 @@
#include <vector>
#include <libcamera/base/object.h>
+#include <libcamera/base/shared_fd.h>
#include "libcamera/internal/bayer_format.h"
@@ -27,7 +28,8 @@ namespace libcamera {
class DebayerCpu : public Debayer, public Object
{
public:
- DebayerCpu(std::unique_ptr<SwStatsCpu> stats);
+ DebayerCpu(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶mBuffers);
~DebayerCpu();
int configure(const StreamConfiguration &inputCfg,
@@ -38,7 +40,7 @@ public:
strideAndFrameSize(const PixelFormat &outputFormat, const Size &size);
void process(uint32_t frame,
const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output, DebayerParams params);
+ FrameBuffer *input, FrameBuffer *output);
SizeRange sizes(PixelFormat inputFormat, const Size &inputSize);
/**
@@ -160,6 +162,7 @@ private:
/* Skip 30 frames for things to stabilize then measure 30 frames */
static constexpr unsigned int kFramesToSkip = 30;
static constexpr unsigned int kLastFrameToMeasure = 60;
+ std::map<unsigned int, DebayerParams *> paramsBuffers_;
};
} /* namespace libcamera */
diff --git a/src/libcamera/software_isp/software_isp.cpp b/src/libcamera/software_isp/software_isp.cpp
index 480ecf6e..db77f6f9 100644
--- a/src/libcamera/software_isp/software_isp.cpp
+++ b/src/libcamera/software_isp/software_isp.cpp
@@ -86,10 +86,11 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
}
stats->statsReady.connect(this, &SoftwareIsp::statsReady);
- debayer_ = std::make_unique<DebayerCpu>(std::move(stats));
std::vector<SharedFD> fdParams;
for (auto &item : sharedParams_)
fdParams.emplace_back(item.second.fd());
+
+ debayer_ = std::make_unique<DebayerCpu>(std::move(stats), fdParams);
debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
debayer_->releaseIspParams.connect(this, &SoftwareIsp::releaseIspParams);
@@ -385,9 +386,8 @@ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *outpu
const uint32_t paramsBufferId = availableParams_.front();
availableParams_.pop();
ipa_->prepare(frame, paramsBufferId);
- debayerParams_ = *sharedParams_.at(paramsBufferId);
debayer_->invokeMethod(&DebayerCpu::process,
- ConnectionTypeQueued, frame, paramsBufferId, input, output, debayerParams_);
+ ConnectionTypeQueued, frame, paramsBufferId, input, output);
}
void SoftwareIsp::saveIspParams(uint32_t paramsBufferId)
--
2.44.1
More information about the libcamera-devel
mailing list