@@ -11,6 +11,8 @@
#include "debayer.h"
+#include <sys/mman.h>
+
namespace libcamera {
/**
@@ -21,6 +23,7 @@ namespace libcamera {
/**
* \fn Debayer::Debayer(const GlobalConfiguration &configuration)
* \brief Construct a Debayer object
+ * \param[in] paramsBuffers SharedFDs of parameter buffers
* \param[in] configuration Global configuration reference
*/
@@ -58,8 +61,22 @@ namespace libcamera {
LOG_DEFINE_CATEGORY(Debayer)
-Debayer::Debayer(const GlobalConfiguration &configuration) : bench_(configuration)
+Debayer::Debayer(const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration) : bench_(configuration)
{
+ paramsBuffers_ = std::map<unsigned int, DebayerParams *>();
+
+ for (auto &sharedFd : paramsBuffers) {
+ 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);
+ }
}
Debayer::~Debayer()
@@ -105,13 +122,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().
@@ -239,6 +255,11 @@ Debayer::~Debayer()
* reversed.
*/
+/**
+ * \var Debayer::paramsBuffers_
+ * \brief Ring of debayering parameters buffers
+ */
+
/**
* \var Debayer::bench_
* \brief Benchmarking utility instance for performance measurements
@@ -35,7 +35,8 @@ LOG_DECLARE_CATEGORY(Debayer)
class Debayer : public Object
{
public:
- Debayer(const GlobalConfiguration &configuration);
+ Debayer(const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration);
virtual ~Debayer() = 0;
virtual int configure(const StreamConfiguration &inputCfg,
@@ -49,8 +50,7 @@ public:
virtual void process(uint32_t frame,
const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output,
- const DebayerParams ¶ms) = 0;
+ FrameBuffer *input, FrameBuffer *output) = 0;
virtual int start() { return 0; }
virtual void stop() {}
@@ -83,6 +83,7 @@ public:
PixelFormat inputPixelFormat_;
PixelFormat outputPixelFormat_;
bool swapRedBlueGains_;
+ std::map<unsigned int, DebayerParams *> paramsBuffers_;
Benchmark bench_;
private:
@@ -12,13 +12,14 @@
#include "debayer_cpu.h"
#include <algorithm>
-#include <stdlib.h>
#include <sys/ioctl.h>
#include <time.h>
#include <utility>
#include <linux/dma-buf.h>
+#include <libcamera/base/shared_fd.h>
+
#include <libcamera/formats.h>
#include "libcamera/internal/bayer_format.h"
@@ -38,10 +39,13 @@ namespace libcamera {
/**
* \brief Constructs a DebayerCpu object
* \param[in] stats Pointer to the stats object to use
+ * \param[in] paramsBuffers SharedFDs of parameter buffers
* \param[in] configuration The global configuration
*/
-DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)
- : Debayer(configuration), stats_(std::move(stats))
+DebayerCpu::DebayerCpu(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration)
+ : Debayer(paramsBuffers, configuration), stats_(std::move(stats))
{
/*
* Reading from uncached buffers may be very slow.
@@ -750,13 +754,13 @@ void DebayerCpu::process4(uint32_t frame, const uint8_t *src, uint8_t *dst)
}
}
-void DebayerCpu::updateGammaTable(const DebayerParams ¶ms)
+void DebayerCpu::updateGammaTable(const DebayerParams *params)
{
- const RGB<float> blackLevel = params.blackLevel;
+ const RGB<float> blackLevel = params->blackLevel;
/* Take let's say the green channel black level */
const unsigned int blackIndex = blackLevel[1] * gammaTable_.size();
- const float gamma = params.gamma;
- const float contrastExp = params.contrastExp;
+ const float gamma = params->gamma;
+ const float contrastExp = params->contrastExp;
const float divisor = gammaTable_.size() - blackIndex - 1.0;
for (unsigned int i = blackIndex; i < gammaTable_.size(); i++) {
@@ -780,12 +784,12 @@ void DebayerCpu::updateGammaTable(const DebayerParams ¶ms)
gammaTable_[blackIndex]);
}
-void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
+void DebayerCpu::updateLookupTables(const DebayerParams *params)
{
const bool gammaUpdateNeeded =
- params.gamma != params_.gamma ||
- params.blackLevel != params_.blackLevel ||
- params.contrastExp != params_.contrastExp;
+ params->gamma != params_.gamma ||
+ params->blackLevel != params_.blackLevel ||
+ params->contrastExp != params_.contrastExp;
if (gammaUpdateNeeded)
updateGammaTable(params);
@@ -796,7 +800,7 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
const double div = static_cast<double>(kRGBLookupSize) / gammaTableSize;
if (ccmEnabled_) {
if (gammaUpdateNeeded ||
- matrixChanged(params.combinedMatrix, params_.combinedMatrix)) {
+ matrixChanged(params->combinedMatrix, params_.combinedMatrix)) {
auto &red = swapRedBlueGains_ ? blueCcm_ : redCcm_;
auto &green = greenCcm_;
auto &blue = swapRedBlueGains_ ? redCcm_ : blueCcm_;
@@ -804,21 +808,21 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
const unsigned int greenIndex = 1;
const unsigned int blueIndex = swapRedBlueGains_ ? 0 : 2;
for (unsigned int i = 0; i < kRGBLookupSize; i++) {
- red[i].r = std::round(i * params.combinedMatrix[redIndex][0]);
- red[i].g = std::round(i * params.combinedMatrix[greenIndex][0]);
- red[i].b = std::round(i * params.combinedMatrix[blueIndex][0]);
- green[i].r = std::round(i * params.combinedMatrix[redIndex][1]);
- green[i].g = std::round(i * params.combinedMatrix[greenIndex][1]);
- green[i].b = std::round(i * params.combinedMatrix[blueIndex][1]);
- blue[i].r = std::round(i * params.combinedMatrix[redIndex][2]);
- blue[i].g = std::round(i * params.combinedMatrix[greenIndex][2]);
- blue[i].b = std::round(i * params.combinedMatrix[blueIndex][2]);
+ red[i].r = std::round(i * params->combinedMatrix[redIndex][0]);
+ red[i].g = std::round(i * params->combinedMatrix[greenIndex][0]);
+ red[i].b = std::round(i * params->combinedMatrix[blueIndex][0]);
+ green[i].r = std::round(i * params->combinedMatrix[redIndex][1]);
+ green[i].g = std::round(i * params->combinedMatrix[greenIndex][1]);
+ green[i].b = std::round(i * params->combinedMatrix[blueIndex][1]);
+ blue[i].r = std::round(i * params->combinedMatrix[redIndex][2]);
+ blue[i].g = std::round(i * params->combinedMatrix[greenIndex][2]);
+ blue[i].b = std::round(i * params->combinedMatrix[blueIndex][2]);
gammaLut_[i] = gammaTable_[i / div];
}
}
} else {
- if (gammaUpdateNeeded || params.gains != params_.gains) {
- auto &gains = params.gains;
+ if (gammaUpdateNeeded || params->gains != params_.gains) {
+ auto &gains = params->gains;
auto &red = swapRedBlueGains_ ? blue_ : red_;
auto &green = green_;
auto &blue = swapRedBlueGains_ ? red_ : blue_;
@@ -833,18 +837,17 @@ void DebayerCpu::updateLookupTables(const DebayerParams ¶ms)
}
LOG(Debayer, Debug)
- << "Debayer parameters: blackLevel=" << params.blackLevel
- << "; gamma=" << params.gamma
- << "; contrastExp=" << params.contrastExp
- << "; gains=" << params.gains
- << "; matrix=" << params.combinedMatrix;
+ << "Debayer parameters: blackLevel=" << params->blackLevel
+ << "; gamma=" << params->gamma
+ << "; contrastExp=" << params->contrastExp
+ << "; gains=" << params->gains
+ << "; matrix=" << params->combinedMatrix;
- params_ = params;
+ params_ = *params;
}
void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output,
- const DebayerParams ¶ms)
+ FrameBuffer *input, FrameBuffer *output)
{
bench_.startFrame();
@@ -852,8 +855,8 @@ void DebayerCpu::process(uint32_t frame, const uint32_t paramsBufferId,
dmaSyncBegin(dmaSyncers, input, output);
+ DebayerParams *params = paramsBuffers_.at(paramsBufferId);
updateLookupTables(params);
-
releaseIspParams.emit(paramsBufferId);
/* Copy metadata from the input buffer */
@@ -16,6 +16,7 @@
#include <vector>
#include <libcamera/base/object.h>
+#include <libcamera/base/shared_fd.h>
#include "libcamera/internal/bayer_format.h"
#include "libcamera/internal/global_configuration.h"
@@ -29,7 +30,9 @@ namespace libcamera {
class DebayerCpu : public Debayer
{
public:
- DebayerCpu(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration);
+ DebayerCpu(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration);
~DebayerCpu();
int configure(const StreamConfiguration &inputCfg,
@@ -41,7 +44,7 @@ public:
strideAndFrameSize(const PixelFormat &outputFormat, const Size &size);
void process(uint32_t frame,
const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms);
+ FrameBuffer *input, FrameBuffer *output);
SizeRange sizes(PixelFormat inputFormat, const Size &inputSize);
const SharedFD &getStatsFD() { return stats_->getStatsFD(); }
@@ -112,8 +115,8 @@ private:
void memcpyNextLine(const uint8_t *linePointers[]);
void process2(uint32_t frame, const uint8_t *src, uint8_t *dst);
void process4(uint32_t frame, const uint8_t *src, uint8_t *dst);
- void updateGammaTable(const DebayerParams ¶ms);
- void updateLookupTables(const DebayerParams ¶ms);
+ void updateGammaTable(const DebayerParams *params);
+ void updateLookupTables(const DebayerParams *params);
/* Max. supported Bayer pattern height is 4, debayering this requires 5 lines */
static constexpr unsigned int kMaxLineBuffers = 5;
@@ -32,10 +32,13 @@ namespace libcamera {
* \fn DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)
* \brief Construct a DebayerEGL object
* \param[in] stats Statistics processing object
+ * \param[in] paramsBuffers SharedFDs of parameter buffers
* \param[in] configuration Global configuration reference
*/
-DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration)
- : Debayer(configuration), stats_(std::move(stats))
+DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration)
+ : Debayer(paramsBuffers, configuration), stats_(std::move(stats))
{
}
@@ -534,8 +537,7 @@ int DebayerEGL::debayerGPU(MappedFrameBuffer &in, int out_fd, const DebayerParam
}
void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output,
- const DebayerParams ¶ms)
+ FrameBuffer *input, FrameBuffer *output)
{
bench_.startFrame();
@@ -549,6 +551,9 @@ void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId,
metadata.sequence = input->metadata().sequence;
metadata.timestamp = input->metadata().timestamp;
+ DebayerParams params = *paramsBuffers_.at(paramsBufferId);
+ releaseIspParams.emit(paramsBufferId);
+
MappedFrameBuffer in(input, MappedFrameBuffer::MapFlag::Read);
if (!in.isValid()) {
LOG(Debayer, Error) << "mmap-ing buffer(s) failed";
@@ -559,7 +564,6 @@ void DebayerEGL::process(uint32_t frame, const uint32_t paramsBufferId,
LOG(Debayer, Error) << "debayerGPU failed";
goto error;
}
- releaseIspParams.emit(paramsBufferId);
bench_.finishFrame();
@@ -38,7 +38,9 @@ namespace libcamera {
class DebayerEGL : public Debayer
{
public:
- DebayerEGL(std::unique_ptr<SwStatsCpu> stats, const GlobalConfiguration &configuration);
+ DebayerEGL(std::unique_ptr<SwStatsCpu> stats,
+ const std::vector<SharedFD> ¶msBuffers,
+ const GlobalConfiguration &configuration);
~DebayerEGL();
int configure(const StreamConfiguration &inputCfg,
@@ -51,8 +53,7 @@ public:
std::tuple<unsigned int, unsigned int> strideAndFrameSize(const PixelFormat &outputFormat, const Size &size);
void process(uint32_t frame, const uint32_t paramsBufferId,
- FrameBuffer *input, FrameBuffer *output,
- const DebayerParams ¶ms);
+ FrameBuffer *input, FrameBuffer *output);
int start();
void stop();
@@ -102,6 +102,10 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
}
stats->statsReady.connect(this, &SoftwareIsp::statsReady);
+ std::vector<SharedFD> fdParams;
+ for (auto &item : sharedParams_)
+ fdParams.emplace_back(item.second.fd());
+
#if HAVE_DEBAYER_EGL
std::optional<std::string> softISPMode = configuration.envOption("LIBCAMERA_SOFTISP_MODE", { "software_isp", "mode" });
if (softISPMode) {
@@ -113,15 +117,14 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
}
if (!softISPMode || softISPMode == "gpu")
- debayer_ = std::make_unique<DebayerEGL>(std::move(stats), configuration);
+ debayer_ = std::make_unique<DebayerEGL>(std::move(stats), fdParams,
+ configuration);
#endif
if (!debayer_)
- debayer_ = std::make_unique<DebayerCpu>(std::move(stats), configuration);
+ debayer_ = std::make_unique<DebayerCpu>(std::move(stats), fdParams,
+ configuration);
- std::vector<SharedFD> fdParams;
- for (auto &item : sharedParams_)
- fdParams.emplace_back(item.second.fd());
debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
debayer_->releaseIspParams.connect(this, &SoftwareIsp::releaseIspParams);
@@ -426,9 +429,8 @@ void SoftwareIsp::process(uint32_t frame, FrameBuffer *input, FrameBuffer *outpu
const uint32_t paramsBufferId = availableParams_.front();
availableParams_.pop();
ipa_->computeParams(frame, paramsBufferId);
- debayerParams_ = *sharedParams_.at(paramsBufferId);
debayer_->invokeMethod(&Debayer::process,
- ConnectionTypeQueued, frame, paramsBufferId, input, output, debayerParams_);
+ ConnectionTypeQueued, frame, paramsBufferId, input, output);
}
void SoftwareIsp::saveIspParams(uint32_t paramsBufferId)
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. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- src/libcamera/software_isp/debayer.cpp | 27 ++++++++- src/libcamera/software_isp/debayer.h | 7 ++- src/libcamera/software_isp/debayer_cpu.cpp | 67 +++++++++++---------- src/libcamera/software_isp/debayer_cpu.h | 11 ++-- src/libcamera/software_isp/debayer_egl.cpp | 14 +++-- src/libcamera/software_isp/debayer_egl.h | 7 ++- src/libcamera/software_isp/software_isp.cpp | 16 ++--- 7 files changed, 92 insertions(+), 57 deletions(-)