@@ -33,6 +33,8 @@
#include "libcamera/internal/shared_mem_object.h"
#include "libcamera/internal/software_isp/debayer_params.h"
+#include "software_isp/swstats_cpu.h"
+
namespace libcamera {
class DebayerCpu;
@@ -100,6 +102,9 @@ private:
DebayerParams debayerParams_;
std::queue<uint32_t> availableParams_;
bool allocateParamsBuffers(const unsigned int bufferCount);
+ std::unique_ptr<SwStatsCpu> allocateStatsBuffers(
+ std::vector<SharedFD> &fdStats,
+ const unsigned int bufferCount);
DmaBufAllocator dmaHeap_;
std::unique_ptr<ipa::soft::IPAProxySoft> ipa_;
@@ -12,6 +12,8 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
+#include <utility>
+#include <vector>
#include <libcamera/base/shared_fd.h>
@@ -20,7 +22,9 @@
#include <libcamera/stream.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"
@@ -79,17 +83,15 @@ SoftwareIsp::SoftwareIsp(PipelineHandler *pipe, const CameraSensor *sensor,
if (!allocateParamsBuffers(bufferCount))
return;
- auto stats = std::make_unique<SwStatsCpu>();
- 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(fdStats, bufferCount);
+ if (!stats)
+ return;
+
debayer_ = std::make_unique<DebayerCpu>(std::move(stats), fdParams);
debayer_->inputBufferReady.connect(this, &SoftwareIsp::inputReady);
debayer_->outputBufferReady.connect(this, &SoftwareIsp::outputReady);
@@ -169,6 +171,34 @@ bool SoftwareIsp::allocateParamsBuffers(const unsigned int bufferCount)
return true;
}
+std::unique_ptr<SwStatsCpu> SoftwareIsp::allocateStatsBuffers(
+ 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>(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 "swstats_cpu.h"
+#include <memory>
+
#include <libcamera/base/log.h>
#include <libcamera/stream.h>
@@ -129,12 +131,14 @@ namespace libcamera {
LOG_DEFINE_CATEGORY(SwStatsCpu)
-SwStatsCpu::SwStatsCpu()
- : sharedStats_("softIsp_stats")
+/**
+ * \brief The constructor of SwStatsCpu
+ * \param [in] sharedStats Mapping of statistics buffer ids to statistics
+ * instances that are shared with the IPA
+ */
+SwStatsCpu::SwStatsCpu(std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats)
+ : sharedStats_(std::move(sharedStats))
{
- if (!sharedStats_)
- LOG(SwStatsCpu, Error)
- << "Failed to create shared memory for statistics";
}
static constexpr unsigned int kRedYMul = 77; /* 0.299 * 256 */
@@ -316,7 +320,7 @@ void SwStatsCpu::startFrame([[maybe_unused]] const uint32_t statsBufferId)
*/
void SwStatsCpu::finishFrame(uint32_t frame, const uint32_t statsBufferId)
{
- *sharedStats_ = stats_;
+ *(sharedStats_->at(statsBufferId)) = stats_;
statsReady.emit(frame, statsBufferId);
}
@@ -11,6 +11,7 @@
#pragma once
+#include <map>
#include <stdint.h>
#include <libcamera/base/signal.h>
@@ -29,12 +30,12 @@ struct StreamConfiguration;
class SwStatsCpu
{
public:
- SwStatsCpu();
+ SwStatsCpu(std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats);
~SwStatsCpu() = default;
- 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_; }
@@ -90,7 +91,7 @@ private:
unsigned int xShift_;
- SharedMemObject<SwIspStats> sharedStats_;
+ std::unique_ptr<std::map<uint32_t, SharedMemObject<SwIspStats>>> sharedStats_;
SwIspStats stats_;
};
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 +++ src/libcamera/software_isp/software_isp.cpp | 44 ++++++++++++++++--- src/libcamera/software_isp/swstats_cpu.cpp | 16 ++++--- src/libcamera/software_isp/swstats_cpu.h | 9 ++-- 4 files changed, 57 insertions(+), 17 deletions(-)