py: Implement FrameBufferPlane
Implement FrameBufferPlane class and adjust the methods and uses accordingly. Note that we don't expose the fd as a SharedFD, but as an int. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
e8317de05c
commit
fbd6c4d1c8
4 changed files with 36 additions and 35 deletions
|
@ -131,10 +131,10 @@ class KMSRenderer:
|
|||
fds = []
|
||||
strides = []
|
||||
offsets = []
|
||||
for i in range(fb.num_planes):
|
||||
fds.append(fb.fd(i))
|
||||
for plane in fb.planes:
|
||||
fds.append(plane.fd)
|
||||
strides.append(cfg.stride)
|
||||
offsets.append(fb.offset(i))
|
||||
offsets.append(plane.offset)
|
||||
|
||||
drmfb = pykms.DmabufFramebuffer(self.card, w, h, fmt,
|
||||
fds, strides, offsets)
|
||||
|
|
|
@ -269,7 +269,7 @@ class MainWindow(QtWidgets.QWidget):
|
|||
EGL_WIDTH, w,
|
||||
EGL_HEIGHT, h,
|
||||
EGL_LINUX_DRM_FOURCC_EXT, fmt,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT, fb.fd(0),
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT, fb.planes[0].fd,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
|
||||
EGL_DMA_BUF_PLANE0_PITCH_EXT, cfg.stride,
|
||||
EGL_NONE,
|
||||
|
|
|
@ -155,6 +155,7 @@ PYBIND11_MODULE(_libcamera, m)
|
|||
auto pyStreamFormats = py::class_<StreamFormats>(m, "StreamFormats");
|
||||
auto pyFrameBufferAllocator = py::class_<FrameBufferAllocator>(m, "FrameBufferAllocator");
|
||||
auto pyFrameBuffer = py::class_<FrameBuffer>(m, "FrameBuffer");
|
||||
auto pyFrameBufferPlane = py::class_<FrameBuffer::Plane>(pyFrameBuffer, "Plane");
|
||||
auto pyStream = py::class_<Stream>(m, "Stream");
|
||||
auto pyControlId = py::class_<ControlId>(m, "ControlId");
|
||||
auto pyControlInfo = py::class_<ControlInfo>(m, "ControlInfo");
|
||||
|
@ -408,31 +409,31 @@ PYBIND11_MODULE(_libcamera, m)
|
|||
});
|
||||
|
||||
pyFrameBuffer
|
||||
/* \todo implement FrameBuffer::Plane properly */
|
||||
.def(py::init([](std::vector<std::tuple<int, unsigned int>> planes, unsigned int cookie) {
|
||||
std::vector<FrameBuffer::Plane> v;
|
||||
for (const auto &t : planes)
|
||||
v.push_back({ SharedFD(std::get<0>(t)), FrameBuffer::Plane::kInvalidOffset, std::get<1>(t) });
|
||||
return new FrameBuffer(v, cookie);
|
||||
}))
|
||||
.def(py::init<std::vector<FrameBuffer::Plane>, unsigned int>(),
|
||||
py::arg("planes"), py::arg("cookie") = 0)
|
||||
.def_property_readonly("metadata", &FrameBuffer::metadata, py::return_value_policy::reference_internal)
|
||||
.def_property_readonly("num_planes", [](const FrameBuffer &self) {
|
||||
return self.planes().size();
|
||||
})
|
||||
.def("length", [](FrameBuffer &self, uint32_t idx) {
|
||||
const FrameBuffer::Plane &plane = self.planes()[idx];
|
||||
return plane.length;
|
||||
})
|
||||
.def("fd", [](FrameBuffer &self, uint32_t idx) {
|
||||
const FrameBuffer::Plane &plane = self.planes()[idx];
|
||||
return plane.fd.get();
|
||||
})
|
||||
.def("offset", [](FrameBuffer &self, uint32_t idx) {
|
||||
const FrameBuffer::Plane &plane = self.planes()[idx];
|
||||
return plane.offset;
|
||||
})
|
||||
.def_property_readonly("planes", &FrameBuffer::planes)
|
||||
.def_property("cookie", &FrameBuffer::cookie, &FrameBuffer::setCookie);
|
||||
|
||||
pyFrameBufferPlane
|
||||
.def(py::init())
|
||||
.def(py::init([](int fd, unsigned int offset, unsigned int length) {
|
||||
auto p = FrameBuffer::Plane();
|
||||
p.fd = SharedFD(fd);
|
||||
p.offset = offset;
|
||||
p.length = length;
|
||||
return p;
|
||||
}), py::arg("fd"), py::arg("offset"), py::arg("length"))
|
||||
.def_property("fd",
|
||||
[](const FrameBuffer::Plane &self) {
|
||||
return self.fd.get();
|
||||
},
|
||||
[](FrameBuffer::Plane &self, int fd) {
|
||||
self.fd = SharedFD(fd);
|
||||
})
|
||||
.def_readwrite("offset", &FrameBuffer::Plane::offset)
|
||||
.def_readwrite("length", &FrameBuffer::Plane::length);
|
||||
|
||||
pyStream
|
||||
.def_property_readonly("configuration", &Stream::configuration);
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ class MappedFrameBuffer:
|
|||
|
||||
bufinfos = {}
|
||||
|
||||
for i in range(fb.num_planes):
|
||||
fd = fb.fd(i)
|
||||
for plane in fb.planes:
|
||||
fd = plane.fd
|
||||
|
||||
if fd not in bufinfos:
|
||||
buflen = os.lseek(fd, 0, os.SEEK_END)
|
||||
|
@ -30,11 +30,11 @@ class MappedFrameBuffer:
|
|||
else:
|
||||
buflen = bufinfos[fd]['buflen']
|
||||
|
||||
if fb.offset(i) > buflen or fb.offset(i) + fb.length(i) > buflen:
|
||||
if plane.offset > buflen or plane.offset + plane.length > buflen:
|
||||
raise RuntimeError(f'plane is out of buffer: buffer length={buflen}, ' +
|
||||
f'plane offset={fb.offset(i)}, plane length={fb.length(i)}')
|
||||
f'plane offset={plane.offset}, plane length={plane.length}')
|
||||
|
||||
bufinfos[fd]['maplen'] = max(bufinfos[fd]['maplen'], fb.offset(i) + fb.length(i))
|
||||
bufinfos[fd]['maplen'] = max(bufinfos[fd]['maplen'], plane.offset + plane.length)
|
||||
|
||||
# mmap the buffers
|
||||
|
||||
|
@ -51,14 +51,14 @@ class MappedFrameBuffer:
|
|||
|
||||
planes = []
|
||||
|
||||
for i in range(fb.num_planes):
|
||||
fd = fb.fd(i)
|
||||
for plane in fb.planes:
|
||||
fd = plane.fd
|
||||
info = bufinfos[fd]
|
||||
|
||||
mv = memoryview(info['map'])
|
||||
|
||||
start = fb.offset(i)
|
||||
end = fb.offset(i) + fb.length(i)
|
||||
start = plane.offset
|
||||
end = plane.offset + plane.length
|
||||
|
||||
mv = mv[start:end]
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue