diff options
-rw-r--r-- | include/libcamera/buffer.h | 55 | ||||
-rw-r--r-- | include/libcamera/request.h | 4 | ||||
-rw-r--r-- | include/libcamera/stream.h | 4 | ||||
-rw-r--r-- | src/cam/buffer_writer.cpp | 4 | ||||
-rw-r--r-- | src/cam/buffer_writer.h | 3 | ||||
-rw-r--r-- | src/cam/capture.cpp | 37 | ||||
-rw-r--r-- | src/libcamera/buffer.cpp | 164 | ||||
-rw-r--r-- | src/libcamera/include/v4l2_videodevice.h | 8 | ||||
-rw-r--r-- | src/libcamera/request.cpp | 35 | ||||
-rw-r--r-- | src/libcamera/stream.cpp | 24 | ||||
-rw-r--r-- | src/libcamera/v4l2_videodevice.cpp | 40 | ||||
-rw-r--r-- | src/qcam/main_window.cpp | 40 | ||||
-rw-r--r-- | src/qcam/main_window.h | 2 | ||||
-rw-r--r-- | test/camera/capture.cpp | 19 | ||||
-rw-r--r-- | test/camera/statemachine.cpp | 6 |
15 files changed, 299 insertions, 146 deletions
diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h index 260a62e9..f5ba6207 100644 --- a/include/libcamera/buffer.h +++ b/include/libcamera/buffer.h @@ -14,6 +14,7 @@ namespace libcamera { class BufferPool; class Request; +class Stream; class Plane final { @@ -36,6 +37,30 @@ private: void *mem_; }; +class BufferMemory final +{ +public: + std::vector<Plane> &planes() { return planes_; } + +private: + std::vector<Plane> planes_; +}; + +class BufferPool final +{ +public: + ~BufferPool(); + + void createBuffers(unsigned int count); + void destroyBuffers(); + + unsigned int count() const { return buffers_.size(); } + std::vector<BufferMemory> &buffers() { return buffers_; } + +private: + std::vector<BufferMemory> buffers_; +}; + class Buffer final { public: @@ -45,20 +70,24 @@ public: BufferCancelled, }; - Buffer(); + Buffer(unsigned int index = -1, const Buffer *metadata = nullptr); + Buffer(const Buffer &) = delete; + Buffer &operator=(const Buffer &) = delete; unsigned int index() const { return index_; } + unsigned int bytesused() const { return bytesused_; } uint64_t timestamp() const { return timestamp_; } unsigned int sequence() const { return sequence_; } + Status status() const { return status_; } - std::vector<Plane> &planes() { return planes_; } Request *request() const { return request_; } + Stream *stream() const { return stream_; } private: - friend class BufferPool; friend class PipelineHandler; friend class Request; + friend class Stream; friend class V4L2VideoDevice; void cancel(); @@ -66,28 +95,14 @@ private: void setRequest(Request *request) { request_ = request; } unsigned int index_; + unsigned int bytesused_; uint64_t timestamp_; unsigned int sequence_; - Status status_; - std::vector<Plane> planes_; + Status status_; Request *request_; -}; - -class BufferPool final -{ -public: - ~BufferPool(); - - void createBuffers(unsigned int count); - void destroyBuffers(); - - unsigned int count() const { return buffers_.size(); } - std::vector<Buffer> &buffers() { return buffers_; } - -private: - std::vector<Buffer> buffers_; + Stream *stream_; }; } /* namespace libcamera */ diff --git a/include/libcamera/request.h b/include/libcamera/request.h index 4fdb3b51..f69b4e7a 100644 --- a/include/libcamera/request.h +++ b/include/libcamera/request.h @@ -8,6 +8,7 @@ #define __LIBCAMERA_REQUEST_H__ #include <map> +#include <memory> #include <stdint.h> #include <unordered_set> @@ -33,10 +34,11 @@ public: Request(Camera *camera, uint64_t cookie = 0); Request(const Request &) = delete; Request &operator=(const Request &) = delete; + ~Request(); ControlList &controls() { return controls_; } const std::map<Stream *, Buffer *> &buffers() const { return bufferMap_; } - int setBuffers(const std::map<Stream *, Buffer *> &streamMap); + int addBuffer(std::unique_ptr<Buffer> buffer); Buffer *findBuffer(Stream *stream) const; uint64_t cookie() const { return cookie_; } diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h index 5b4fea32..f595a630 100644 --- a/include/libcamera/stream.h +++ b/include/libcamera/stream.h @@ -8,6 +8,7 @@ #define __LIBCAMERA_STREAM_H__ #include <map> +#include <memory> #include <string> #include <vector> @@ -66,6 +67,9 @@ class Stream { public: Stream(); + + std::unique_ptr<Buffer> createBuffer(unsigned int index); + BufferPool &bufferPool() { return bufferPool_; } const StreamConfiguration &configuration() const { return configuration_; } 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<Stream *, Buffer *> 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> 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::map<Stream *, Buffer for (auto it = buffers.begin(); it != buffers.end(); ++it) { Stream *stream = it->first; 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::map<Stream *, Buffer << " bytesused: " << buffer->bytesused(); 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<Buffer> newBuffer = stream->createBuffer(index); + if (!newBuffer) { + std::cerr << "Can't create buffer " << index << std::endl; + return; + } + + request->addBuffer(std::move(newBuffer)); + } + camera_->queueRequest(request); } diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp index c0a02094..ecbf2524 100644 --- a/src/libcamera/buffer.cpp +++ b/src/libcamera/buffer.cpp @@ -173,12 +173,78 @@ void *Plane::mem() */ /** - * \class Buffer + * \class BufferMemory * \brief A memory buffer to store an image * - * The Buffer class represents the memory buffers used to store a - * full frame image, which may contain multiple separate memory Plane - * objects if the image format is multi-planar. + * The BufferMemory class represents the memory buffers used to store full frame + * images, which may contain multiple separate memory Plane objects if the + * image format is multi-planar. + */ + +/** + * \fn BufferMemory::planes() + * \brief Retrieve the planes within the buffer + * \return A reference to a vector holding all Planes within the buffer + */ + +/** + * \class BufferPool + * \brief A pool of buffers + * + * The BufferPool class groups together a collection of Buffers to store frames. + * The buffers must be exported by a device before they can be imported into + * another device for further use. + */ + +BufferPool::~BufferPool() +{ + destroyBuffers(); +} + +/** + * \brief Create buffers in the Pool + * \param[in] count The number of buffers to create + */ +void BufferPool::createBuffers(unsigned int count) +{ + buffers_.resize(count); +} + +/** + * \brief Release all buffers from pool + * + * If no buffers have been created or if buffers have already been released no + * operation is performed. + */ +void BufferPool::destroyBuffers() +{ + buffers_.resize(0); +} + +/** + * \fn BufferPool::count() + * \brief Retrieve the number of buffers contained within the pool + * \return The number of buffers contained in the pool + */ + +/** + * \fn BufferPool::buffers() + * \brief Retrieve all the buffers in the pool + * \return A vector containing all the buffers in the pool. + */ + +/** + * \class Buffer + * \brief A buffer handle and dynamic metadata + * + * The Buffer class references a buffer memory and associates dynamic metadata + * related to the frame contained in the buffer. It allows referencing buffer + * memory through a single interface regardless of whether the memory is + * allocated internally in libcamera or provided externally through dmabuf. + * + * Buffer instances are allocated dynamically for a stream through + * Stream::createBuffer(), added to a request with Request::addBuffer() and + * deleted automatically after the request complete handler returns. */ /** @@ -195,9 +261,26 @@ void *Plane::mem() * invalid and shall not be used. */ -Buffer::Buffer() - : index_(-1), request_(nullptr) +/** + * \brief Construct a buffer not associated with any stream + * + * This method constructs an orphaned buffer not associated with any stream. It + * is not meant to be called by applications, they should instead create buffers + * for a stream with Stream::createBuffer(). + */ +Buffer::Buffer(unsigned int index, const Buffer *metadata) + : index_(index), status_(Buffer::BufferSuccess), request_(nullptr), + stream_(nullptr) { + if (metadata) { + bytesused_ = metadata->bytesused_; + sequence_ = metadata->sequence_; + timestamp_ = metadata->timestamp_; + } else { + bytesused_ = 0; + sequence_ = 0; + timestamp_ = 0; + } } /** @@ -207,12 +290,6 @@ Buffer::Buffer() */ /** - * \fn Buffer::planes() - * \brief Retrieve the planes within the buffer - * \return A reference to a vector holding all Planes within the buffer - */ - -/** * \fn Buffer::bytesused() * \brief Retrieve the number of bytes occupied by the data in the buffer * \return Number of bytes occupied in the buffer @@ -265,6 +342,19 @@ Buffer::Buffer() */ /** + * \fn Buffer::stream() + * \brief Retrieve the stream this buffer is associated with + * + * A Buffer is associated to the stream that created it with + * Stream::createBuffer() and the association is valid until the buffer is + * destroyed. Buffer instances that are created directly are not associated + * with any stream. + * + * \return The Stream the Buffer is associated with, or nullptr if the buffer + * is not associated with a stream + */ + +/** * \brief Mark a buffer as cancel by setting its status to BufferCancelled */ void Buffer::cancel() @@ -282,54 +372,4 @@ void Buffer::cancel() * The intended callers are Request::prepare() and Request::completeBuffer(). */ -/** - * \class BufferPool - * \brief A pool of buffers - * - * The BufferPool class groups together a collection of Buffers to store frames. - * The buffers must be exported by a device before they can be imported into - * another device for further use. - */ - -BufferPool::~BufferPool() -{ - destroyBuffers(); -} - -/** - * \brief Create buffers in the Pool - * \param[in] count The number of buffers to create - */ -void BufferPool::createBuffers(unsigned int count) -{ - unsigned int index = 0; - - buffers_.resize(count); - for (Buffer &buffer : buffers_) - buffer.index_ = index++; -} - -/** - * \brief Release all buffers from pool - * - * If no buffers have been created or if buffers have already been released no - * operation is performed. - */ -void BufferPool::destroyBuffers() -{ - buffers_.resize(0); -} - -/** - * \fn BufferPool::count() - * \brief Retrieve the number of buffers contained within the pool - * \return The number of buffers contained in the pool - */ - -/** - * \fn BufferPool::buffers() - * \brief Retrieve all the buffers in the pool - * \return A vector containing all the buffers in the pool. - */ - } /* namespace libcamera */ diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h index 2996a609..f5c8da93 100644 --- a/src/libcamera/include/v4l2_videodevice.h +++ b/src/libcamera/include/v4l2_videodevice.h @@ -7,7 +7,6 @@ #ifndef __LIBCAMERA_V4L2_VIDEODEVICE_H__ #define __LIBCAMERA_V4L2_VIDEODEVICE_H__ -#include <atomic> #include <string> #include <vector> @@ -23,6 +22,7 @@ namespace libcamera { class Buffer; +class BufferMemory; class BufferPool; class EventNotifier; class MediaDevice; @@ -165,8 +165,8 @@ private: std::vector<SizeRange> enumSizes(unsigned int pixelFormat); int requestBuffers(unsigned int count); - int createPlane(Buffer *buffer, unsigned int plane, - unsigned int length); + int createPlane(BufferMemory *buffer, unsigned int index, + unsigned int plane, unsigned int length); Buffer *dequeueBuffer(); void bufferAvailable(EventNotifier *notifier); @@ -177,7 +177,7 @@ private: enum v4l2_memory memoryType_; BufferPool *bufferPool_; - std::atomic<unsigned int> queuedBuffersCount_; + std::map<unsigned int, Buffer *> queuedBuffers_; EventNotifier *fdEvent_; }; diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp index 8cf41a43..45e7133f 100644 --- a/src/libcamera/request.cpp +++ b/src/libcamera/request.cpp @@ -60,6 +60,14 @@ Request::Request(Camera *camera, uint64_t cookie) { } +Request::~Request() +{ + for (auto it : bufferMap_) { + Buffer *buffer = it.second; + delete buffer; + } +} + /** * \fn Request::controls() * \brief Retrieve the request's ControlList @@ -87,19 +95,30 @@ Request::Request(Camera *camera, uint64_t cookie) */ /** - * \brief Set the streams to capture with associated buffers - * \param[in] streamMap The map of streams to buffers + * \brief Store a Buffer with its associated Stream in the Request + * \param[in] buffer The Buffer to store in the request + * + * Ownership of the buffer is passed to the request. It will be deleted when + * the request is destroyed after completing. + * + * A request can only contain one buffer per stream. If a buffer has already + * been added to the request for the same stream, this method returns -EEXIST. + * * \return 0 on success or a negative error code otherwise - * \retval -EBUSY Buffers have already been set + * \retval -EEXIST The request already contains a buffer for the stream */ -int Request::setBuffers(const std::map<Stream *, Buffer *> &streamMap) +int Request::addBuffer(std::unique_ptr<Buffer> buffer) { - if (!bufferMap_.empty()) { - LOG(Request, Error) << "Buffers already set"; - return -EBUSY; + Stream *stream = buffer->stream(); + + auto it = bufferMap_.find(stream); + if (it != bufferMap_.end()) { + LOG(Request, Error) << "Buffer already set for stream"; + return -EEXIST; } - bufferMap_ = streamMap; + bufferMap_[stream] = buffer.release(); + return 0; } diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp index d8e87c62..6d80646b 100644 --- a/src/libcamera/stream.cpp +++ b/src/libcamera/stream.cpp @@ -408,6 +408,30 @@ Stream::Stream() } /** + * \brief Create a Buffer instance + * \param[in] index The desired buffer index + * + * This method creates a Buffer instance that references a BufferMemory from + * the stream's buffers pool by its \a index. The index shall be lower than the + * number of buffers in the pool. + * + * \return A newly created Buffer on success or nullptr otherwise + */ +std::unique_ptr<Buffer> Stream::createBuffer(unsigned int index) +{ + if (index >= bufferPool_.count()) { + LOG(Stream, Error) << "Invalid buffer index " << index; + return nullptr; + } + + Buffer *buffer = new Buffer(); + buffer->index_ = index; + buffer->stream_ = this; + + return std::unique_ptr<Buffer>(buffer); +} + +/** * \fn Stream::bufferPool() * \brief Retrieve the buffer pool for the stream * diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index 0ab92b3a..86e299c0 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -268,8 +268,7 @@ const std::string V4L2DeviceFormat::toString() const * \param[in] deviceNode The file-system path to the video device node */ V4L2VideoDevice::V4L2VideoDevice(const std::string &deviceNode) - : V4L2Device(deviceNode), bufferPool_(nullptr), - queuedBuffersCount_(0), fdEvent_(nullptr) + : V4L2Device(deviceNode), bufferPool_(nullptr), fdEvent_(nullptr) { /* * We default to an MMAP based CAPTURE video device, however this will @@ -764,7 +763,7 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool) for (i = 0; i < pool->count(); ++i) { struct v4l2_plane planes[VIDEO_MAX_PLANES] = {}; struct v4l2_buffer buf = {}; - Buffer &buffer = pool->buffers()[i]; + BufferMemory &buffer = pool->buffers()[i]; buf.index = i; buf.type = bufferType_; @@ -782,13 +781,13 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool) if (V4L2_TYPE_IS_MULTIPLANAR(buf.type)) { for (unsigned int p = 0; p < buf.length; ++p) { - ret = createPlane(&buffer, p, + ret = createPlane(&buffer, i, p, buf.m.planes[p].length); if (ret) break; } } else { - ret = createPlane(&buffer, 0, buf.length); + ret = createPlane(&buffer, i, 0, buf.length); } if (ret) { @@ -808,19 +807,19 @@ int V4L2VideoDevice::exportBuffers(BufferPool *pool) return 0; } -int V4L2VideoDevice::createPlane(Buffer *buffer, unsigned int planeIndex, - unsigned int length) +int V4L2VideoDevice::createPlane(BufferMemory *buffer, unsigned int index, + unsigned int planeIndex, unsigned int length) { struct v4l2_exportbuffer expbuf = {}; int ret; LOG(V4L2, Debug) - << "Buffer " << buffer->index() + << "Buffer " << index << " plane " << planeIndex << ": length=" << length; expbuf.type = bufferType_; - expbuf.index = buffer->index(); + expbuf.index = index; expbuf.plane = planeIndex; expbuf.flags = O_RDWR; @@ -904,7 +903,8 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer) buf.field = V4L2_FIELD_NONE; bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type); - const std::vector<Plane> &planes = buffer->planes(); + BufferMemory *mem = &bufferPool_->buffers()[buf.index]; + const std::vector<Plane> &planes = mem->planes(); if (buf.memory == V4L2_MEMORY_DMABUF) { if (multiPlanar) { @@ -937,9 +937,11 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer) return ret; } - if (queuedBuffersCount_++ == 0) + if (queuedBuffers_.empty()) fdEvent_->setEnabled(true); + queuedBuffers_[buf.index] = buffer; + return 0; } @@ -970,7 +972,7 @@ std::vector<std::unique_ptr<Buffer>> V4L2VideoDevice::queueAllBuffers() { int ret; - if (queuedBuffersCount_) + if (!queuedBuffers_.empty()) return {}; if (V4L2_TYPE_IS_OUTPUT(bufferType_)) @@ -979,8 +981,7 @@ std::vector<std::unique_ptr<Buffer>> V4L2VideoDevice::queueAllBuffers() std::vector<std::unique_ptr<Buffer>> buffers; for (unsigned int i = 0; i < bufferPool_->count(); ++i) { - Buffer *buffer = new Buffer(); - buffer->index_ = i; + Buffer *buffer = new Buffer(i); buffers.emplace_back(buffer); ret = queueBuffer(buffer); if (ret) @@ -1021,11 +1022,14 @@ Buffer *V4L2VideoDevice::dequeueBuffer() ASSERT(buf.index < bufferPool_->count()); - if (--queuedBuffersCount_ == 0) - fdEvent_->setEnabled(false); + auto it = queuedBuffers_.find(buf.index); + Buffer *buffer = it->second; + queuedBuffers_.erase(it); - Buffer *buffer = &bufferPool_->buffers()[buf.index]; + if (queuedBuffers_.empty()) + fdEvent_->setEnabled(false); + buffer->index_ = buf.index; buffer->bytesused_ = buf.bytesused; buffer->timestamp_ = buf.timestamp.tv_sec * 1000000000ULL + buf.timestamp.tv_usec * 1000ULL; @@ -1100,7 +1104,7 @@ int V4L2VideoDevice::streamOff() return ret; } - queuedBuffersCount_ = 0; + queuedBuffers_.clear(); fdEvent_->setEnabled(false); return 0; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 907d2423..6ecf30e3 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -142,8 +142,7 @@ int MainWindow::startCapture() BufferPool &pool = stream->bufferPool(); std::vector<Request *> requests; - - for (Buffer &buffer : pool.buffers()) { + for (unsigned int i = 0; i < pool.count(); ++i) { Request *request = camera_->createRequest(); if (!request) { std::cerr << "Can't create request" << std::endl; @@ -151,11 +150,15 @@ int MainWindow::startCapture() goto error; } - std::map<Stream *, Buffer *> map; - map[stream] = &buffer; - ret = request->setBuffers(map); + std::unique_ptr<Buffer> buffer = stream->createBuffer(i); + if (!buffer) { + std::cerr << "Can't create buffer " << i << std::endl; + goto error; + } + + ret = request->addBuffer(std::move(buffer)); if (ret < 0) { - std::cerr << "Can't set buffers for request" << std::endl; + std::cerr << "Can't set buffer for request" << std::endl; goto error; } @@ -219,6 +222,7 @@ void MainWindow::requestComplete(Request *request, framesCaptured_++; + Stream *stream = buffers.begin()->first; Buffer *buffer = buffers.begin()->second; double fps = buffer->timestamp() - lastBufferTime_; @@ -232,7 +236,8 @@ void MainWindow::requestComplete(Request *request, << " fps: " << std::fixed << std::setprecision(2) << fps << std::endl; - display(buffer); + BufferMemory *mem = &stream->bufferPool().buffers()[buffer->index()]; + display(buffer, mem); request = camera_->createRequest(); if (!request) { @@ -240,16 +245,29 @@ void MainWindow::requestComplete(Request *request, 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<Buffer> newBuffer = stream->createBuffer(index); + if (!newBuffer) { + std::cerr << "Can't create buffer " << index << std::endl; + return; + } + + request->addBuffer(std::move(newBuffer)); + } + camera_->queueRequest(request); } -int MainWindow::display(Buffer *buffer) +int MainWindow::display(Buffer *buffer, BufferMemory *mem) { - if (buffer->planes().size() != 1) + if (mem->planes().size() != 1) return -EINVAL; - Plane &plane = buffer->planes().front(); + Plane &plane = mem->planes().front(); unsigned char *raw = static_cast<unsigned char *>(plane.mem()); viewfinder_->display(raw, buffer->bytesused()); diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index f58cb6a6..b4f6f747 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -48,7 +48,7 @@ private: void requestComplete(Request *request, const std::map<Stream *, Buffer *> &buffers); - int display(Buffer *buffer); + int display(Buffer *buffer, BufferMemory *mem); QString title_; QTimer titleTimer_; diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp index 7ce247cc..ff1cbd6c 100644 --- a/test/camera/capture.cpp +++ b/test/camera/capture.cpp @@ -34,9 +34,13 @@ protected: completeRequestsCount_++; - /* Reuse the buffers for a new request. */ + /* Create a new request. */ + Stream *stream = buffers.begin()->first; + Buffer *buffer = buffers.begin()->second; + std::unique_ptr<Buffer> newBuffer = stream->createBuffer(buffer->index()); + request = camera_->createRequest(); - request->setBuffers(buffers); + request->addBuffer(std::move(newBuffer)); camera_->queueRequest(request); } @@ -78,15 +82,20 @@ protected: Stream *stream = cfg.stream(); BufferPool &pool = stream->bufferPool(); std::vector<Request *> requests; - for (Buffer &buffer : pool.buffers()) { + for (unsigned int i = 0; i < pool.count(); ++i) { Request *request = camera_->createRequest(); if (!request) { cout << "Failed to create request" << endl; return TestFail; } - std::map<Stream *, Buffer *> map = { { stream, &buffer } }; - if (request->setBuffers(map)) { + std::unique_ptr<Buffer> buffer = stream->createBuffer(i); + if (!buffer) { + cout << "Failed to create buffer " << i << endl; + return TestFail; + } + + if (request->addBuffer(std::move(buffer))) { cout << "Failed to associating buffer with request" << endl; return TestFail; } diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp index 84d2a6fa..12d5e0e1 100644 --- a/test/camera/statemachine.cpp +++ b/test/camera/statemachine.cpp @@ -211,10 +211,8 @@ protected: return TestFail; Stream *stream = *camera_->streams().begin(); - BufferPool &pool = stream->bufferPool(); - Buffer &buffer = pool.buffers().front(); - std::map<Stream *, Buffer *> map = { { stream, &buffer } }; - if (request->setBuffers(map)) + std::unique_ptr<Buffer> buffer = stream->createBuffer(0); + if (request->addBuffer(std::move(buffer))) return TestFail; if (camera_->queueRequest(request)) |