@@ -34,6 +34,7 @@
#include "libcamera/internal/pipeline_handler.h"
#include "libcamera/internal/shared_mem_object.h"
#include "libcamera/internal/software_isp/debayer_params.h"
+#include "libcamera/internal/software_isp/swstats_cpu.h"
namespace libcamera {
@@ -103,6 +104,10 @@ private:
DebayerParams debayerParams_;
std::queue<uint32_t> availableParams_;
bool allocateParamsBuffers(const unsigned int bufferCount);
+ std::unique_ptr<SwStatsCpu> allocateStatsBuffers(
+ const GlobalConfiguration &configuration,
+ std::vector<SharedFD> &fdStats,
+ const unsigned int bufferCount);
DmaBufAllocator dmaHeap_;
bool ccmEnabled_;
@@ -11,6 +11,7 @@
#pragma once
+#include <map>
#include <stdint.h>
#include <libcamera/base/signal.h>
@@ -34,7 +35,7 @@ struct StreamConfiguration;
class SwStatsCpu
{
public:
- SwStatsCpu(const GlobalConfiguration &configuration);
+ SwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats);
~SwStatsCpu() = default;
/*
@@ -45,9 +46,9 @@ public:
*/
static constexpr uint32_t kStatPerNumFrames = 4;
- bool isValid() const { return sharedStats_.fd().isValid(); }
+ bool isValid() const { return sharedStats_->begin()->second.fd().isValid(); }
- const SharedFD &getStatsFD() { return sharedStats_.fd(); }
+ const SharedFD &getStatsFD() { return sharedStats_->begin()->second.fd(); }
const Size &patternSize() { return patternSize_; }
@@ -116,7 +117,7 @@ private:
unsigned int xShift_;
unsigned int stride_;
- SharedMemObject<SwIspStats> sharedStats_;
+ std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats_;
SwIspStats stats_;
Benchmark bench_;
};
@@ -12,6 +12,8 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
+#include <utility>
+#include <vector>
#include <libcamera/base/log.h>
#include <libcamera/base/shared_fd.h>
@@ -24,7 +26,9 @@
#include "libcamera/internal/framebuffer.h"
#include "libcamera/internal/ipa_manager.h"
+#include "libcamera/internal/shared_mem_object.h"
#include "libcamera/internal/software_isp/debayer_params.h"
+#include "libcamera/internal/software_isp/swisp_stats.h"
#include "debayer_cpu.h"
#if HAVE_DEBAYER_EGL
@@ -95,17 +99,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
const GlobalConfiguration &configuration = pipe->cameraManager()->_d()->configuration();
- auto stats = std::make_unique<SwStatsCpu>(configuration);
- if (!stats->isValid()) {
- LOG(SoftwareIsp, Error) << "Failed to create SwStatsCpu object";
- return;
- }
- stats->statsReady.connect(this, &SoftwareIsp::statsReady);
-
std::vector<SharedFD> fdParams;
for (auto &item : sharedParams_)
fdParams.emplace_back(item.second.fd());
+ std::vector<SharedFD> fdStats;
+ auto stats = allocateStatsBuffers(configuration, fdStats, bufferCount);
+ if (!stats)
+ return;
+
#if HAVE_DEBAYER_EGL
std::optional<std::string> softISPMode = configuration.envOption("LIBCAMERA_SOFTISP_MODE", { "software_isp", "mode" });
if (softISPMode) {
@@ -199,6 +201,35 @@ bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount)
return true;
}
+std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(
+ const GlobalConfiguration &configuration,
+ std::vector<SharedFD> &fdStats,
+ const unsigned int bufferCount)
+{
+ auto sharedStats = std::make_unique<std::map<uint32_t, SharedMemObject<SwIspStats>>>();
+ for (unsigned int i = 0; i < bufferCount; i++) {
+ auto shared = SharedMemObject<SwIspStats>("softIsp_stats");
+ if (!shared) {
+ LOG(SoftwareIsp, Error) << "Failed to create shared memory for statistics";
+ return std::unique_ptr<SwStatsCpu>();
+ }
+ if (!shared.fd().isValid()) {
+ LOG(SoftwareIsp, Error) << "Invalid fd of shared statistics";
+ return std::unique_ptr<SwStatsCpu>();
+ }
+
+ ASSERT(shared.fd().get() >= 0);
+ unsigned int bufferId = shared.fd().get();
+ fdStats.emplace_back(shared.fd());
+ sharedStats->emplace(bufferId, std::move(shared));
+ }
+
+ auto stats = std::make_unique<SwStatsCpu>(configuration, std::move(sharedStats));
+ stats->statsReady.connect(this, &SoftwareIsp::statsReady);
+
+ return stats;
+}
+
/**
* \fn int SoftwareIsp::loadConfiguration([[maybe_unused]] const std::string &filename)
* \brief Load a configuration from a file
@@ -11,6 +11,8 @@
#include "libcamera/internal/software_isp/swstats_cpu.h"
+#include <memory>
+
#include <libcamera/base/log.h>
#include <libcamera/stream.h>
@@ -36,9 +38,11 @@ namespace libcamera {
*/
/**
- * \fn SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)
+ * \fn SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)
* \brief Construct a SwStatsCpu object
* \param[in] configuration Global configuration reference
+ * \param [in] sharedStats Mapping of statistics buffer ids to statistics
+ * instances that are shared with the IPA
*
* Creates a SwStatsCpu object and initialises shared memory for statistics
* exchange.
@@ -154,12 +158,9 @@ namespace libcamera {
LOG_DEFINE_CATEGORY(SwStatsCpu)
-SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration)
- : sharedStats_("softIsp_stats"), bench_(configuration)
+SwStatsCpu::SwStatsCpu(const GlobalConfiguration &configuration, std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)
+ : sharedStats_(std::move(sharedStats)), bench_(configuration)
{
- if (!sharedStats_)
- LOG(SwStatsCpu, Error)
- << "Failed to create shared memory for statistics";
}
static constexpr unsigned int kRedYMul = 77; /* 0.299 * 256 */
@@ -348,7 +349,7 @@ void SwStatsCpu::finishFrame(uint32_t frame,
const uint32_t statsBufferId)
{
stats_.valid = frame % kStatPerNumFrames == 0;
- *sharedStats_ = stats_;
+ *(sharedStats_->at(statsBufferId)) = stats_;
statsReady.emit(frame, statsBufferId);
}
In order to be able to use multiple shared statistics buffers, we must allocate them. They are allocated in SoftwareIsp and passed to SwIspStats. This changes the previous behavior when the (single) shared statistics buffer was created in SwIspStats. Centralizing it to SoftwareIsp makes sharing multiple buffers with IPA easier. Currently only one of the allocated buffers is used. This will be changed once the buffers are shared with IPA in a followup patch. Signed-off-by: Milan Zamazal <mzamazal@redhat.com> --- .../internal/software_isp/software_isp.h | 5 +++ .../internal/software_isp/swstats_cpu.h | 9 ++-- src/libcamera/software_isp/software_isp.cpp | 45 ++++++++++++++++--- src/libcamera/software_isp/swstats_cpu.cpp | 15 ++++--- 4 files changed, 56 insertions(+), 18 deletions(-)