py: Implement PixelFormat class
Implement PixelFormat bindings properly with a PixelFormat class. Change the bindings to use the new class instead of a string. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
11a271b292
commit
fa7bda46f8
6 changed files with 27 additions and 56 deletions
|
@ -164,7 +164,7 @@ def configure(ctx):
|
||||||
stream_config.size = (stream_opts['width'], stream_opts['height'])
|
stream_config.size = (stream_opts['width'], stream_opts['height'])
|
||||||
|
|
||||||
if 'pixelformat' in stream_opts:
|
if 'pixelformat' in stream_opts:
|
||||||
stream_config.pixel_format = stream_opts['pixelformat']
|
stream_config.pixel_format = libcam.PixelFormat(stream_opts['pixelformat'])
|
||||||
|
|
||||||
stat = camconfig.validate()
|
stat = camconfig.validate()
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,6 @@ import pykms
|
||||||
import selectors
|
import selectors
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
FMT_MAP = {
|
|
||||||
'RGB888': pykms.PixelFormat.RGB888,
|
|
||||||
'YUYV': pykms.PixelFormat.YUYV,
|
|
||||||
'ARGB8888': pykms.PixelFormat.ARGB8888,
|
|
||||||
'XRGB8888': pykms.PixelFormat.XRGB8888,
|
|
||||||
'NV12': pykms.PixelFormat.NV12,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class KMSRenderer:
|
class KMSRenderer:
|
||||||
def __init__(self, state):
|
def __init__(self, state):
|
||||||
|
@ -120,7 +112,7 @@ class KMSRenderer:
|
||||||
|
|
||||||
cfg = stream.configuration
|
cfg = stream.configuration
|
||||||
fmt = cfg.pixel_format
|
fmt = cfg.pixel_format
|
||||||
fmt = FMT_MAP[fmt]
|
fmt = pykms.PixelFormat(fmt.fourcc)
|
||||||
|
|
||||||
plane = self.resman.reserve_generic_plane(self.crtc, fmt)
|
plane = self.resman.reserve_generic_plane(self.crtc, fmt)
|
||||||
assert(plane is not None)
|
assert(plane is not None)
|
||||||
|
|
|
@ -87,6 +87,8 @@ def to_rgb(fmt, size, data):
|
||||||
w = size[0]
|
w = size[0]
|
||||||
h = size[1]
|
h = size[1]
|
||||||
|
|
||||||
|
fmt = str(fmt)
|
||||||
|
|
||||||
if fmt == 'YUYV':
|
if fmt == 'YUYV':
|
||||||
# YUV422
|
# YUV422
|
||||||
yuyv = data.reshape((h, w // 2 * 4))
|
yuyv = data.reshape((h, w // 2 * 4))
|
||||||
|
@ -293,7 +295,7 @@ class MainWindow(QtWidgets.QWidget):
|
||||||
w, h = cfg.size
|
w, h = cfg.size
|
||||||
pitch = cfg.stride
|
pitch = cfg.stride
|
||||||
|
|
||||||
if cfg.pixel_format == 'MJPEG':
|
if str(cfg.pixel_format) == 'MJPEG':
|
||||||
img = Image.open(BytesIO(mfb.planes[0]))
|
img = Image.open(BytesIO(mfb.planes[0]))
|
||||||
qim = ImageQt(img).copy()
|
qim = ImageQt(img).copy()
|
||||||
pix = QtGui.QPixmap.fromImage(qim)
|
pix = QtGui.QPixmap.fromImage(qim)
|
||||||
|
|
|
@ -30,14 +30,6 @@ from OpenGL.GL import shaders
|
||||||
|
|
||||||
from gl_helpers import *
|
from gl_helpers import *
|
||||||
|
|
||||||
# libcamera format string -> DRM fourcc
|
|
||||||
FMT_MAP = {
|
|
||||||
'RGB888': 'RG24',
|
|
||||||
'XRGB8888': 'XR24',
|
|
||||||
'ARGB8888': 'AR24',
|
|
||||||
'YUYV': 'YUYV',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class EglState:
|
class EglState:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -204,12 +196,6 @@ class MainWindow(QtWidgets.QWidget):
|
||||||
self.current[ctx['idx']] = []
|
self.current[ctx['idx']] = []
|
||||||
|
|
||||||
for stream in ctx['streams']:
|
for stream in ctx['streams']:
|
||||||
fmt = stream.configuration.pixel_format
|
|
||||||
size = stream.configuration.size
|
|
||||||
|
|
||||||
if fmt not in FMT_MAP:
|
|
||||||
raise Exception('Unsupported pixel format: ' + str(fmt))
|
|
||||||
|
|
||||||
self.textures[stream] = None
|
self.textures[stream] = None
|
||||||
|
|
||||||
num_tiles = len(self.textures)
|
num_tiles = len(self.textures)
|
||||||
|
@ -281,8 +267,7 @@ class MainWindow(QtWidgets.QWidget):
|
||||||
|
|
||||||
def create_texture(self, stream, fb):
|
def create_texture(self, stream, fb):
|
||||||
cfg = stream.configuration
|
cfg = stream.configuration
|
||||||
fmt = cfg.pixel_format
|
fmt = cfg.pixel_format.fourcc
|
||||||
fmt = str_to_fourcc(FMT_MAP[fmt])
|
|
||||||
w, h = cfg.size
|
w, h = cfg.size
|
||||||
|
|
||||||
attribs = [
|
attribs = [
|
||||||
|
|
|
@ -30,14 +30,6 @@ def getglEGLImageTargetTexture2DOES():
|
||||||
|
|
||||||
glEGLImageTargetTexture2DOES = getglEGLImageTargetTexture2DOES()
|
glEGLImageTargetTexture2DOES = getglEGLImageTargetTexture2DOES()
|
||||||
|
|
||||||
# \todo This can be dropped when we have proper PixelFormat bindings
|
|
||||||
def str_to_fourcc(str):
|
|
||||||
assert(len(str) == 4)
|
|
||||||
fourcc = 0
|
|
||||||
for i, v in enumerate([ord(c) for c in str]):
|
|
||||||
fourcc |= v << (i * 8)
|
|
||||||
return fourcc
|
|
||||||
|
|
||||||
|
|
||||||
def get_gl_extensions():
|
def get_gl_extensions():
|
||||||
n = GLint()
|
n = GLint()
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
/*
|
/*
|
||||||
* \todo Add geometry classes (Point, Rectangle...)
|
* \todo Add geometry classes (Point, Rectangle...)
|
||||||
* \todo Add bindings for the ControlInfo class
|
* \todo Add bindings for the ControlInfo class
|
||||||
* \todo Add bindings for the PixelFormat class
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -173,6 +172,7 @@ PYBIND11_MODULE(_libcamera, m)
|
||||||
auto pyColorSpaceTransferFunction = py::enum_<ColorSpace::TransferFunction>(pyColorSpace, "TransferFunction");
|
auto pyColorSpaceTransferFunction = py::enum_<ColorSpace::TransferFunction>(pyColorSpace, "TransferFunction");
|
||||||
auto pyColorSpaceYcbcrEncoding = py::enum_<ColorSpace::YcbcrEncoding>(pyColorSpace, "YcbcrEncoding");
|
auto pyColorSpaceYcbcrEncoding = py::enum_<ColorSpace::YcbcrEncoding>(pyColorSpace, "YcbcrEncoding");
|
||||||
auto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, "Range");
|
auto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, "Range");
|
||||||
|
auto pyPixelFormat = py::class_<PixelFormat>(m, "PixelFormat");
|
||||||
|
|
||||||
/* Global functions */
|
/* Global functions */
|
||||||
m.def("log_set_level", &logSetLevel);
|
m.def("log_set_level", &logSetLevel);
|
||||||
|
@ -404,14 +404,7 @@ PYBIND11_MODULE(_libcamera, m)
|
||||||
self.size.width = std::get<0>(size);
|
self.size.width = std::get<0>(size);
|
||||||
self.size.height = std::get<1>(size);
|
self.size.height = std::get<1>(size);
|
||||||
})
|
})
|
||||||
.def_property(
|
.def_readwrite("pixel_format", &StreamConfiguration::pixelFormat)
|
||||||
"pixel_format",
|
|
||||||
[](StreamConfiguration &self) {
|
|
||||||
return self.pixelFormat.toString();
|
|
||||||
},
|
|
||||||
[](StreamConfiguration &self, std::string fmt) {
|
|
||||||
self.pixelFormat = PixelFormat::fromString(fmt);
|
|
||||||
})
|
|
||||||
.def_readwrite("stride", &StreamConfiguration::stride)
|
.def_readwrite("stride", &StreamConfiguration::stride)
|
||||||
.def_readwrite("frame_size", &StreamConfiguration::frameSize)
|
.def_readwrite("frame_size", &StreamConfiguration::frameSize)
|
||||||
.def_readwrite("buffer_count", &StreamConfiguration::bufferCount)
|
.def_readwrite("buffer_count", &StreamConfiguration::bufferCount)
|
||||||
|
@ -420,22 +413,15 @@ PYBIND11_MODULE(_libcamera, m)
|
||||||
.def_readwrite("color_space", &StreamConfiguration::colorSpace);
|
.def_readwrite("color_space", &StreamConfiguration::colorSpace);
|
||||||
|
|
||||||
pyStreamFormats
|
pyStreamFormats
|
||||||
.def_property_readonly("pixel_formats", [](StreamFormats &self) {
|
.def_property_readonly("pixel_formats", &StreamFormats::pixelformats)
|
||||||
std::vector<std::string> fmts;
|
.def("sizes", [](StreamFormats &self, const PixelFormat &pixelFormat) {
|
||||||
for (auto &fmt : self.pixelformats())
|
|
||||||
fmts.push_back(fmt.toString());
|
|
||||||
return fmts;
|
|
||||||
})
|
|
||||||
.def("sizes", [](StreamFormats &self, const std::string &pixelFormat) {
|
|
||||||
auto fmt = PixelFormat::fromString(pixelFormat);
|
|
||||||
std::vector<std::tuple<uint32_t, uint32_t>> fmts;
|
std::vector<std::tuple<uint32_t, uint32_t>> fmts;
|
||||||
for (const auto &s : self.sizes(fmt))
|
for (const auto &s : self.sizes(pixelFormat))
|
||||||
fmts.push_back(std::make_tuple(s.width, s.height));
|
fmts.push_back(std::make_tuple(s.width, s.height));
|
||||||
return fmts;
|
return fmts;
|
||||||
})
|
})
|
||||||
.def("range", [](StreamFormats &self, const std::string &pixelFormat) {
|
.def("range", [](StreamFormats &self, const PixelFormat &pixelFormat) {
|
||||||
auto fmt = PixelFormat::fromString(pixelFormat);
|
const auto &range = self.range(pixelFormat);
|
||||||
const auto &range = self.range(fmt);
|
|
||||||
return make_tuple(std::make_tuple(range.hStep, range.vStep),
|
return make_tuple(std::make_tuple(range.hStep, range.vStep),
|
||||||
std::make_tuple(range.min.width, range.min.height),
|
std::make_tuple(range.min.width, range.min.height),
|
||||||
std::make_tuple(range.max.width, range.max.height));
|
std::make_tuple(range.max.width, range.max.height));
|
||||||
|
@ -648,4 +634,18 @@ PYBIND11_MODULE(_libcamera, m)
|
||||||
pyColorSpaceRange
|
pyColorSpaceRange
|
||||||
.value("Full", ColorSpace::Range::Full)
|
.value("Full", ColorSpace::Range::Full)
|
||||||
.value("Limited", ColorSpace::Range::Limited);
|
.value("Limited", ColorSpace::Range::Limited);
|
||||||
|
|
||||||
|
pyPixelFormat
|
||||||
|
.def(py::init<>())
|
||||||
|
.def(py::init<uint32_t, uint64_t>())
|
||||||
|
.def(py::init<>([](const std::string &str) {
|
||||||
|
return PixelFormat::fromString(str);
|
||||||
|
}))
|
||||||
|
.def_property_readonly("fourcc", &PixelFormat::fourcc)
|
||||||
|
.def_property_readonly("modifier", &PixelFormat::modifier)
|
||||||
|
.def(py::self == py::self)
|
||||||
|
.def("__str__", &PixelFormat::toString)
|
||||||
|
.def("__repr__", [](const PixelFormat &self) {
|
||||||
|
return "libcamera.PixelFormat('" + self.toString() + "')";
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue