From a2bcf6feee5ae6077225cc787c3d1a25d9ef95e7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 9 Jul 2019 18:08:07 +0300 Subject: libcamera: buffer: Split memory information to BufferMemory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Buffer class is a large beast the stores information about the buffer memory, dynamic metadata related to the frame stored in the buffer, and buffer reference data (in the index). In order to implement buffer import we will need to extend this with dmabuf file descriptors, making usage of the class even more complex. Refactor the Buffer class by splitting the buffer memory information to a BufferMemory class, and repurposing the Buffer class to reference a buffer and to store dynamic metadata. The BufferMemory class becomes a long term storage, valid and stable from the time buffer memory is allocated to the time it is freed. The Buffer class, on the other hand, becomes transient, is created on demand when an application requires a buffer, is given to a request, and is deleted when the request completes. Buffer and BufferMemory don't need to be copied, so their copy constructor and assignment operators are deleted. Signed-off-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/cam/buffer_writer.cpp | 4 ++-- src/cam/buffer_writer.h | 3 ++- src/cam/capture.cpp | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 32 insertions(+), 12 deletions(-) (limited to 'src/cam') diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp index e0374ffc..b7f2ed4f 100644 --- a/src/cam/buffer_writer.cpp +++ b/src/cam/buffer_writer.cpp @@ -19,7 +19,7 @@ BufferWriter::BufferWriter(const std::string &pattern) { } -int BufferWriter::write(libcamera::Buffer *buffer, +int BufferWriter::write(libcamera::Buffer *buffer, libcamera::BufferMemory *mem, const std::string &streamName) { std::string filename; @@ -41,7 +41,7 @@ int BufferWriter::write(libcamera::Buffer *buffer, if (fd == -1) return -errno; - for (libcamera::Plane &plane : buffer->planes()) { + for (libcamera::Plane &plane : mem->planes()) { void *data = plane.mem(); unsigned int length = plane.length(); diff --git a/src/cam/buffer_writer.h b/src/cam/buffer_writer.h index 7bf785d1..9bea205f 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::Buffer *buffer, libcamera::BufferMemory *mem, + const std::string &streamName); private: std::string pattern_; diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp index 6b842d73..1cf59063 100644 --- a/src/cam/capture.cpp +++ b/src/cam/capture.cpp @@ -95,13 +95,14 @@ int Capture::capture(EventLoop *loop) std::map map; for (StreamConfiguration &cfg : *config_) { Stream *stream = cfg.stream(); - map[stream] = &stream->bufferPool().buffers()[i]; - } - - ret = request->setBuffers(map); - if (ret < 0) { - std::cerr << "Can't set buffers for request" << std::endl; - return ret; + std::unique_ptr buffer = stream->createBuffer(i); + + ret = request->addBuffer(std::move(buffer)); + if (ret < 0) { + std::cerr << "Can't set buffer for request" + << std::endl; + return ret; + } } requests.push_back(request); @@ -155,6 +156,7 @@ void Capture::requestComplete(Request *request, const std::mapfirst; Buffer *buffer = it->second; + BufferMemory *mem = &stream->bufferPool().buffers()[buffer->index()]; const std::string &name = streamName_[stream]; info << " " << name @@ -163,17 +165,34 @@ void Capture::requestComplete(Request *request, const std::mapbytesused(); if (writer_) - writer_->write(buffer, name); + writer_->write(buffer, mem, name); } std::cout << info.str() << std::endl; + /* + * Create a new request and populate it with one buffer for each + * stream. + */ request = camera_->createRequest(); if (!request) { std::cerr << "Can't create request" << std::endl; return; } - request->setBuffers(buffers); + 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 newBuffer = stream->createBuffer(index); + if (!newBuffer) { + std::cerr << "Can't create buffer " << index << std::endl; + return; + } + + request->addBuffer(std::move(newBuffer)); + } + camera_->queueRequest(request); } -- cgit v1.2.1