summaryrefslogtreecommitdiff
path: root/src/libcamera/software_isp/debayer_cpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcamera/software_isp/debayer_cpu.cpp')
-rw-r--r--src/libcamera/software_isp/debayer_cpu.cpp71
1 files changed, 49 insertions, 22 deletions
diff --git a/src/libcamera/software_isp/debayer_cpu.cpp b/src/libcamera/software_isp/debayer_cpu.cpp
index f8d2677d..cf5ecdf7 100644
--- a/src/libcamera/software_isp/debayer_cpu.cpp
+++ b/src/libcamera/software_isp/debayer_cpu.cpp
@@ -12,8 +12,11 @@
#include "debayer_cpu.h"
#include <stdlib.h>
+#include <sys/ioctl.h>
#include <time.h>
+#include <linux/dma-buf.h>
+
#include <libcamera/formats.h>
#include "libcamera/internal/bayer_format.h"
@@ -49,16 +52,9 @@ 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;
-
- for (unsigned int i = 0; i < kMaxLineBuffers; i++)
- lineBuffers_[i] = nullptr;
}
-DebayerCpu::~DebayerCpu()
-{
- for (unsigned int i = 0; i < kMaxLineBuffers; i++)
- free(lineBuffers_[i]);
-}
+DebayerCpu::~DebayerCpu() = default;
#define DECLARE_SRC_POINTERS(pixel_t) \
const pixel_t *prev = (const pixel_t *)src[0] + xShift_; \
@@ -526,13 +522,10 @@ int DebayerCpu::configure(const StreamConfiguration &inputCfg,
lineBufferPadding_ = inputConfig_.patternSize.width * inputConfig_.bpp / 8;
lineBufferLength_ = window_.width * inputConfig_.bpp / 8 +
2 * lineBufferPadding_;
- for (unsigned int i = 0;
- i < (inputConfig_.patternSize.height + 1) && enableInputMemcpy_;
- i++) {
- free(lineBuffers_[i]);
- lineBuffers_[i] = (uint8_t *)malloc(lineBufferLength_);
- if (!lineBuffers_[i])
- return -ENOMEM;
+
+ if (enableInputMemcpy_) {
+ for (unsigned int i = 0; i <= inputConfig_.patternSize.height; i++)
+ lineBuffers_[i].resize(lineBufferLength_);
}
measuredFrames_ = 0;
@@ -587,9 +580,10 @@ void DebayerCpu::setupInputMemcpy(const uint8_t *linePointers[])
return;
for (unsigned int i = 0; i < patternHeight; i++) {
- memcpy(lineBuffers_[i], linePointers[i + 1] - lineBufferPadding_,
+ memcpy(lineBuffers_[i].data(),
+ linePointers[i + 1] - lineBufferPadding_,
lineBufferLength_);
- linePointers[i + 1] = lineBuffers_[i] + lineBufferPadding_;
+ linePointers[i + 1] = lineBuffers_[i].data() + lineBufferPadding_;
}
/* Point lineBufferIndex_ to first unused lineBuffer */
@@ -614,9 +608,10 @@ void DebayerCpu::memcpyNextLine(const uint8_t *linePointers[])
if (!enableInputMemcpy_)
return;
- memcpy(lineBuffers_[lineBufferIndex_], linePointers[patternHeight] - lineBufferPadding_,
+ memcpy(lineBuffers_[lineBufferIndex_].data(),
+ linePointers[patternHeight] - lineBufferPadding_,
lineBufferLength_);
- linePointers[patternHeight] = lineBuffers_[lineBufferIndex_] + lineBufferPadding_;
+ linePointers[patternHeight] = lineBuffers_[lineBufferIndex_].data() + lineBufferPadding_;
lineBufferIndex_ = (lineBufferIndex_ + 1) % (patternHeight + 1);
}
@@ -725,13 +720,34 @@ void DebayerCpu::process4(const uint8_t *src, uint8_t *dst)
}
}
-static inline int64_t timeDiff(timespec &after, timespec &before)
+namespace {
+
+void syncBufferForCPU(FrameBuffer *buffer, uint64_t syncFlags)
+{
+ for (const FrameBuffer::Plane &plane : buffer->planes()) {
+ const int fd = plane.fd.get();
+ struct dma_buf_sync sync = { syncFlags };
+ int ret;
+
+ ret = ioctl(fd, DMA_BUF_IOCTL_SYNC, &sync);
+ if (ret < 0) {
+ ret = errno;
+ LOG(Debayer, Error)
+ << "Syncing buffer FD " << fd << " with flags "
+ << syncFlags << " failed: " << strerror(ret);
+ }
+ }
+}
+
+inline int64_t timeDiff(timespec &after, timespec &before)
{
return (after.tv_sec - before.tv_sec) * 1000000000LL +
(int64_t)after.tv_nsec - (int64_t)before.tv_nsec;
}
-void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams params)
+} /* namespace */
+
+void DebayerCpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, DebayerParams params)
{
timespec frameStartTime;
@@ -740,6 +756,9 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
clock_gettime(CLOCK_MONOTONIC_RAW, &frameStartTime);
}
+ syncBufferForCPU(input, DMA_BUF_SYNC_START | DMA_BUF_SYNC_READ);
+ syncBufferForCPU(output, DMA_BUF_SYNC_START | DMA_BUF_SYNC_WRITE);
+
green_ = params.green;
red_ = swapRedBlueGains_ ? params.blue : params.red;
blue_ = swapRedBlueGains_ ? params.red : params.blue;
@@ -767,6 +786,9 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
metadata.planes()[0].bytesused = out.planes()[0].size();
+ syncBufferForCPU(output, DMA_BUF_SYNC_END | DMA_BUF_SYNC_WRITE);
+ syncBufferForCPU(input, DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ);
+
/* Measure before emitting signals */
if (measuredFrames_ < DebayerCpu::kLastFrameToMeasure &&
++measuredFrames_ > DebayerCpu::kFramesToSkip) {
@@ -784,7 +806,12 @@ void DebayerCpu::process(FrameBuffer *input, FrameBuffer *output, DebayerParams
}
}
- stats_->finishFrame();
+ /*
+ * Buffer ids are currently not used, so pass zeros as its parameter.
+ *
+ * \todo Pass real bufferId once stats buffer passing is changed.
+ */
+ stats_->finishFrame(frame, 0);
outputBufferReady.emit(output);
inputBufferReady.emit(input);
}