@@ -164,7 +164,7 @@ def configure(ctx):
stream_config.size = (stream_opts['width'], stream_opts['height'])
if 'pixelformat' in stream_opts:
- stream_config.pixel_format = stream_opts['pixelformat']
+ stream_config.pixel_format = libcam.PixelFormat(stream_opts['pixelformat'])
stat = camconfig.validate()
@@ -5,14 +5,6 @@ import pykms
import selectors
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:
def __init__(self, state):
@@ -120,7 +112,7 @@ class KMSRenderer:
cfg = stream.configuration
fmt = cfg.pixel_format
- fmt = FMT_MAP[fmt]
+ fmt = pykms.PixelFormat(fmt.fourcc)
plane = self.resman.reserve_generic_plane(self.crtc, fmt)
assert(plane is not None)
@@ -87,6 +87,8 @@ def to_rgb(fmt, size, data):
w = size[0]
h = size[1]
+ fmt = str(fmt)
+
if fmt == 'YUYV':
# YUV422
yuyv = data.reshape((h, w // 2 * 4))
@@ -293,7 +295,7 @@ class MainWindow(QtWidgets.QWidget):
w, h = cfg.size
pitch = cfg.stride
- if cfg.pixel_format == 'MJPEG':
+ if str(cfg.pixel_format) == 'MJPEG':
img = Image.open(BytesIO(mfb.planes[0]))
qim = ImageQt(img).copy()
pix = QtGui.QPixmap.fromImage(qim)
@@ -30,14 +30,6 @@ from OpenGL.GL import shaders
from gl_helpers import *
-# libcamera format string -> DRM fourcc
-FMT_MAP = {
- 'RGB888': 'RG24',
- 'XRGB8888': 'XR24',
- 'ARGB8888': 'AR24',
- 'YUYV': 'YUYV',
-}
-
class EglState:
def __init__(self):
@@ -204,12 +196,6 @@ class MainWindow(QtWidgets.QWidget):
self.current[ctx['idx']] = []
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
num_tiles = len(self.textures)
@@ -281,8 +267,7 @@ class MainWindow(QtWidgets.QWidget):
def create_texture(self, stream, fb):
cfg = stream.configuration
- fmt = cfg.pixel_format
- fmt = str_to_fourcc(FMT_MAP[fmt])
+ fmt = cfg.pixel_format.fourcc
w, h = cfg.size
attribs = [
@@ -30,14 +30,6 @@ def 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():
n = GLint()
@@ -8,7 +8,6 @@
/*
* \todo Add geometry classes (Point, Rectangle...)
* \todo Add bindings for the ControlInfo class
- * \todo Add bindings for the PixelFormat class
*/
#include <mutex>
@@ -173,6 +172,7 @@ PYBIND11_MODULE(_libcamera, m)
auto pyColorSpaceTransferFunction = py::enum_<ColorSpace::TransferFunction>(pyColorSpace, "TransferFunction");
auto pyColorSpaceYcbcrEncoding = py::enum_<ColorSpace::YcbcrEncoding>(pyColorSpace, "YcbcrEncoding");
auto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, "Range");
+ auto pyPixelFormat = py::class_<PixelFormat>(m, "PixelFormat");
/* Global functions */
m.def("log_set_level", &logSetLevel);
@@ -404,14 +404,7 @@ PYBIND11_MODULE(_libcamera, m)
self.size.width = std::get<0>(size);
self.size.height = std::get<1>(size);
})
- .def_property(
- "pixel_format",
- [](StreamConfiguration &self) {
- return self.pixelFormat.toString();
- },
- [](StreamConfiguration &self, std::string fmt) {
- self.pixelFormat = PixelFormat::fromString(fmt);
- })
+ .def_readwrite("pixel_format", &StreamConfiguration::pixelFormat)
.def_readwrite("stride", &StreamConfiguration::stride)
.def_readwrite("frame_size", &StreamConfiguration::frameSize)
.def_readwrite("buffer_count", &StreamConfiguration::bufferCount)
@@ -420,22 +413,15 @@ PYBIND11_MODULE(_libcamera, m)
.def_readwrite("color_space", &StreamConfiguration::colorSpace);
pyStreamFormats
- .def_property_readonly("pixel_formats", [](StreamFormats &self) {
- std::vector<std::string> fmts;
- 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);
+ .def_property_readonly("pixel_formats", &StreamFormats::pixelformats)
+ .def("sizes", [](StreamFormats &self, const PixelFormat &pixelFormat) {
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));
return fmts;
})
- .def("range", [](StreamFormats &self, const std::string &pixelFormat) {
- auto fmt = PixelFormat::fromString(pixelFormat);
- const auto &range = self.range(fmt);
+ .def("range", [](StreamFormats &self, const PixelFormat &pixelFormat) {
+ const auto &range = self.range(pixelFormat);
return make_tuple(std::make_tuple(range.hStep, range.vStep),
std::make_tuple(range.min.width, range.min.height),
std::make_tuple(range.max.width, range.max.height));
@@ -648,4 +634,18 @@ PYBIND11_MODULE(_libcamera, m)
pyColorSpaceRange
.value("Full", ColorSpace::Range::Full)
.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() + "')";
+ });
}