libcamera: buffer: Switch from Plane to FrameBuffer::Plane
It is not libcamera's responsibility to handle memory mappings. Switch from the soon to be removed Plane class which deals with memory mappings to FrameBuffer::Plane which just describes it. This makes the transition to the full FrameBuffer easier. As the full FrameBuffer interface has not yet spread to all parts of libcamera core it is hard to create efficient caching of memory mappings in the qcam application. This will be fixed in a later patch, for now the dmabuf is mapped and unmapped each time it is seen by the application. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
007517618c
commit
ae9a05847c
9 changed files with 38 additions and 32 deletions
|
@ -95,11 +95,11 @@ private:
|
|||
class BufferMemory final
|
||||
{
|
||||
public:
|
||||
const std::vector<Plane> &planes() const { return planes_; }
|
||||
std::vector<Plane> &planes() { return planes_; }
|
||||
const std::vector<FrameBuffer::Plane> &planes() const { return planes_; }
|
||||
std::vector<FrameBuffer::Plane> &planes() { return planes_; }
|
||||
|
||||
private:
|
||||
std::vector<Plane> planes_;
|
||||
std::vector<FrameBuffer::Plane> planes_;
|
||||
};
|
||||
|
||||
class BufferPool final
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "buffer_writer.h"
|
||||
|
@ -43,9 +44,11 @@ int BufferWriter::write(Buffer *buffer, const std::string &streamName)
|
|||
return -errno;
|
||||
|
||||
BufferMemory *mem = buffer->mem();
|
||||
for (Plane &plane : mem->planes()) {
|
||||
void *data = plane.mem();
|
||||
unsigned int length = plane.length();
|
||||
for (const FrameBuffer::Plane &plane : mem->planes()) {
|
||||
/* \todo Once the FrameBuffer is done cache mapped memory. */
|
||||
void *data = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
|
||||
plane.fd.fd(), 0);
|
||||
unsigned int length = plane.length;
|
||||
|
||||
ret = ::write(fd, data, length);
|
||||
if (ret < 0) {
|
||||
|
@ -59,6 +62,8 @@ int BufferWriter::write(Buffer *buffer, const std::string &streamName)
|
|||
<< length << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
munmap(data, length);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
|
|
@ -257,13 +257,13 @@ void *Plane::mem()
|
|||
/**
|
||||
* \fn BufferMemory::planes() const
|
||||
* \brief Retrieve the planes within the buffer
|
||||
* \return A const reference to a vector holding all Planes within the buffer
|
||||
* \return A const reference to a vector holding all planes within the buffer
|
||||
*/
|
||||
|
||||
/**
|
||||
* \fn BufferMemory::planes()
|
||||
* \brief Retrieve the planes within the buffer
|
||||
* \return A reference to a vector holding all Planes within the buffer
|
||||
* \return A reference to a vector holding all planes within the buffer
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -687,22 +687,14 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera,
|
|||
}
|
||||
|
||||
for (unsigned int i = 0; i < stream->configuration().bufferCount + 1; i++) {
|
||||
FrameBuffer::Plane plane;
|
||||
plane.fd = FileDescriptor(paramPool_.buffers()[i].planes()[0].dmabuf());
|
||||
plane.length = paramPool_.buffers()[i].planes()[0].length();
|
||||
|
||||
data->ipaBuffers_.push_back({ .id = RKISP1_PARAM_BASE | i,
|
||||
.planes = { plane } });
|
||||
.planes = paramPool_.buffers()[i].planes() });
|
||||
paramBuffers_.push(new Buffer(i));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < stream->configuration().bufferCount + 1; i++) {
|
||||
FrameBuffer::Plane plane;
|
||||
plane.fd = FileDescriptor(statPool_.buffers()[i].planes()[0].dmabuf());
|
||||
plane.length = statPool_.buffers()[i].planes()[0].length();
|
||||
|
||||
data->ipaBuffers_.push_back({ .id = RKISP1_STAT_BASE | i,
|
||||
.planes = { plane } });
|
||||
.planes = statPool_.buffers()[i].planes() });
|
||||
statBuffers_.push(new Buffer(i));
|
||||
}
|
||||
|
||||
|
|
|
@ -577,8 +577,10 @@ int Stream::mapBuffer(const Buffer *buffer)
|
|||
if (dmabufs[i] == -1)
|
||||
break;
|
||||
|
||||
mem->planes().emplace_back();
|
||||
mem->planes().back().setDmabuf(dmabufs[i], 0);
|
||||
FrameBuffer::Plane plane;
|
||||
plane.fd = FileDescriptor(dmabufs[i]);
|
||||
plane.length = 0;
|
||||
mem->planes().push_back(plane);
|
||||
}
|
||||
|
||||
/* Remove the buffer from the cache and return its index. */
|
||||
|
|
|
@ -922,9 +922,10 @@ int V4L2VideoDevice::createPlane(BufferMemory *buffer, unsigned int index,
|
|||
return ret;
|
||||
}
|
||||
|
||||
buffer->planes().emplace_back();
|
||||
Plane &plane = buffer->planes().back();
|
||||
plane.setDmabuf(expbuf.fd, length);
|
||||
FrameBuffer::Plane plane;
|
||||
plane.fd = FileDescriptor(expbuf.fd);
|
||||
plane.length = length;
|
||||
buffer->planes().push_back(plane);
|
||||
::close(expbuf.fd);
|
||||
|
||||
return 0;
|
||||
|
@ -987,14 +988,14 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer)
|
|||
|
||||
bool multiPlanar = V4L2_TYPE_IS_MULTIPLANAR(buf.type);
|
||||
BufferMemory *mem = &bufferPool_->buffers()[buf.index];
|
||||
const std::vector<Plane> &planes = mem->planes();
|
||||
const std::vector<FrameBuffer::Plane> &planes = mem->planes();
|
||||
|
||||
if (buf.memory == V4L2_MEMORY_DMABUF) {
|
||||
if (multiPlanar) {
|
||||
for (unsigned int p = 0; p < planes.size(); ++p)
|
||||
v4l2Planes[p].m.fd = planes[p].dmabuf();
|
||||
v4l2Planes[p].m.fd = planes[p].fd.fd();
|
||||
} else {
|
||||
buf.m.fd = planes[0].dmabuf();
|
||||
buf.m.fd = planes[0].fd.fd();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QInputDialog>
|
||||
|
@ -296,13 +297,18 @@ void MainWindow::requestComplete(Request *request)
|
|||
|
||||
int MainWindow::display(Buffer *buffer)
|
||||
{
|
||||
BufferMemory *mem = buffer->mem();
|
||||
if (mem->planes().size() != 1)
|
||||
if (buffer->mem()->planes().size() != 1)
|
||||
return -EINVAL;
|
||||
|
||||
Plane &plane = mem->planes().front();
|
||||
unsigned char *raw = static_cast<unsigned char *>(plane.mem());
|
||||
/* \todo Once the FrameBuffer is done cache mapped memory. */
|
||||
const FrameBuffer::Plane &plane = buffer->mem()->planes().front();
|
||||
void *memory = mmap(NULL, plane.length, PROT_READ, MAP_SHARED,
|
||||
plane.fd.fd(), 0);
|
||||
|
||||
unsigned char *raw = static_cast<unsigned char *>(memory);
|
||||
viewfinder_->display(raw, buffer->bytesused());
|
||||
|
||||
munmap(memory, plane.length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ void V4L2Camera::freeBuffers()
|
|||
FileDescriptor V4L2Camera::getBufferFd(unsigned int index)
|
||||
{
|
||||
Stream *stream = *camera_->streams().begin();
|
||||
return FileDescriptor(stream->buffers()[index].planes()[0].dmabuf());
|
||||
return stream->buffers()[index].planes()[0].fd;
|
||||
}
|
||||
|
||||
int V4L2Camera::streamOn()
|
||||
|
|
|
@ -178,7 +178,7 @@ private:
|
|||
|
||||
uint64_t cookie = index;
|
||||
BufferMemory &mem = pool_.buffers()[index];
|
||||
int dmabuf = mem.planes()[0].dmabuf();
|
||||
int dmabuf = mem.planes()[0].fd.fd();
|
||||
|
||||
requestReady.emit(cookie, dmabuf);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue