summaryrefslogtreecommitdiff
path: root/src/cam
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2019-11-22 16:22:56 +0100
committerNiklas Söderlund <niklas.soderlund@ragnatech.se>2020-01-12 16:10:38 +0100
commit9217f274f64f690b768d332663e1731a3ee5ef15 (patch)
treeee152928be1eaea656c929e56e27e97b175de435 /src/cam
parenteb4030f6c07174a520be1ebd73628e9ae4789569 (diff)
libcamera: Switch to FrameBuffer interface
Switch to the FrameBuffer interface where all buffers are treated as external buffers and are allocated outside the camera. Applications allocating buffers using libcamera are switched to use the FrameBufferAllocator helper. Follow-up changes to this one will finalize the transition to the new FrameBuffer interface by removing code that is left unused after this change. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/cam')
-rw-r--r--src/cam/buffer_writer.cpp5
-rw-r--r--src/cam/buffer_writer.h3
-rw-r--r--src/cam/capture.cpp42
-rw-r--r--src/cam/capture.h5
4 files changed, 33 insertions, 22 deletions
diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp
index 41ef4b0a..1d7366c8 100644
--- a/src/cam/buffer_writer.cpp
+++ b/src/cam/buffer_writer.cpp
@@ -22,7 +22,7 @@ BufferWriter::BufferWriter(const std::string &pattern)
{
}
-int BufferWriter::write(Buffer *buffer, const std::string &streamName)
+int BufferWriter::write(FrameBuffer *buffer, const std::string &streamName)
{
std::string filename;
size_t pos;
@@ -43,8 +43,7 @@ int BufferWriter::write(Buffer *buffer, const std::string &streamName)
if (fd == -1)
return -errno;
- BufferMemory *mem = buffer->mem();
- for (const FrameBuffer::Plane &plane : mem->planes()) {
+ for (const FrameBuffer::Plane &plane : buffer->planes()) {
/* \todo Once the FrameBuffer is done cache mapped memory. */
void *data = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
plane.fd.fd(), 0);
diff --git a/src/cam/buffer_writer.h b/src/cam/buffer_writer.h
index 7bf785d1..5917a7df 100644
--- a/src/cam/buffer_writer.h
+++ b/src/cam/buffer_writer.h
@@ -16,7 +16,8 @@ class BufferWriter
public:
BufferWriter(const std::string &pattern = "frame-#.bin");
- int write(libcamera::Buffer *buffer, const std::string &streamName);
+ int write(libcamera::FrameBuffer *buffer,
+ const std::string &streamName);
private:
std::string pattern_;
diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp
index da942f56..dd078eb0 100644
--- a/src/cam/capture.cpp
+++ b/src/cam/capture.cpp
@@ -57,7 +57,10 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)
writer_ = new BufferWriter();
}
- ret = capture(loop);
+
+ FrameBufferAllocator *allocator = FrameBufferAllocator::create(camera_);
+
+ ret = capture(loop, allocator);
if (options.isSet(OptFile)) {
delete writer_;
@@ -66,17 +69,27 @@ int Capture::run(EventLoop *loop, const OptionsParser::Options &options)
camera_->freeBuffers();
+ delete allocator;
+
return ret;
}
-int Capture::capture(EventLoop *loop)
+int Capture::capture(EventLoop *loop, FrameBufferAllocator *allocator)
{
int ret;
/* Identify the stream with the least number of buffers. */
unsigned int nbuffers = UINT_MAX;
- for (StreamConfiguration &cfg : *config_)
- nbuffers = std::min(nbuffers, cfg.bufferCount);
+ for (StreamConfiguration &cfg : *config_) {
+ ret = allocator->allocate(cfg.stream());
+ if (ret < 0) {
+ std::cerr << "Can't allocate buffers" << std::endl;
+ return -ENOMEM;
+ }
+
+ unsigned int allocated = allocator->buffers(cfg.stream()).size();
+ nbuffers = std::min(nbuffers, allocated);
+ }
/*
* TODO: make cam tool smarter to support still capture by for
@@ -93,9 +106,11 @@ int Capture::capture(EventLoop *loop)
for (StreamConfiguration &cfg : *config_) {
Stream *stream = cfg.stream();
- std::unique_ptr<Buffer> buffer = stream->createBuffer(i);
+ const std::vector<std::unique_ptr<FrameBuffer>> &buffers =
+ allocator->buffers(stream);
+ const std::unique_ptr<FrameBuffer> &buffer = buffers[i];
- ret = request->addBuffer(stream, std::move(buffer));
+ ret = request->addBuffer(stream, buffer.get());
if (ret < 0) {
std::cerr << "Can't set buffer for request"
<< std::endl;
@@ -138,7 +153,7 @@ void Capture::requestComplete(Request *request)
if (request->status() == Request::RequestCancelled)
return;
- const std::map<Stream *, Buffer *> &buffers = request->buffers();
+ const std::map<Stream *, FrameBuffer *> &buffers = request->buffers();
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
double fps = std::chrono::duration_cast<std::chrono::milliseconds>(now - last_).count();
@@ -151,7 +166,7 @@ void Capture::requestComplete(Request *request)
for (auto it = buffers.begin(); it != buffers.end(); ++it) {
Stream *stream = it->first;
- Buffer *buffer = it->second;
+ FrameBuffer *buffer = it->second;
const std::string &name = streamName_[stream];
const FrameMetadata &metadata = buffer->metadata();
@@ -185,16 +200,9 @@ void Capture::requestComplete(Request *request)
for (auto it = buffers.begin(); it != buffers.end(); ++it) {
Stream *stream = it->first;
- Buffer *buffer = it->second;
- unsigned int index = buffer->index();
-
- std::unique_ptr<Buffer> newBuffer = stream->createBuffer(index);
- if (!newBuffer) {
- std::cerr << "Can't create buffer" << std::endl;
- return;
- }
+ FrameBuffer *buffer = it->second;
- request->addBuffer(stream, std::move(newBuffer));
+ request->addBuffer(stream, buffer);
}
camera_->queueRequest(request);
diff --git a/src/cam/capture.h b/src/cam/capture.h
index c692d489..9bca5661 100644
--- a/src/cam/capture.h
+++ b/src/cam/capture.h
@@ -10,7 +10,9 @@
#include <chrono>
#include <memory>
+#include <libcamera/buffer.h>
#include <libcamera/camera.h>
+#include <libcamera/framebuffer_allocator.h>
#include <libcamera/request.h>
#include <libcamera/stream.h>
@@ -26,7 +28,8 @@ public:
int run(EventLoop *loop, const OptionsParser::Options &options);
private:
- int capture(EventLoop *loop);
+ int capture(EventLoop *loop,
+ libcamera::FrameBufferAllocator *allocator);
void requestComplete(libcamera::Request *request);