summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/include/v4l2_videodevice.h39
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp4
-rw-r--r--src/libcamera/v4l2_videodevice.cpp91
3 files changed, 109 insertions, 25 deletions
diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index bc1c6a4d..2a380c0e 100644
--- a/src/libcamera/include/v4l2_videodevice.h
+++ b/src/libcamera/include/v4l2_videodevice.h
@@ -149,10 +149,33 @@ private:
unsigned int missCounter_;
};
+class V4L2PixelFormat
+{
+public:
+ V4L2PixelFormat()
+ : fourcc_(0)
+ {
+ }
+
+ V4L2PixelFormat(uint32_t fourcc)
+ : fourcc_(fourcc)
+ {
+ }
+
+ bool isValid() const { return fourcc_ != 0; }
+ uint32_t fourcc() const { return fourcc_; }
+ operator uint32_t() const { return fourcc_; }
+
+ std::string toString() const;
+
+private:
+ uint32_t fourcc_;
+};
+
class V4L2DeviceFormat
{
public:
- uint32_t fourcc;
+ V4L2PixelFormat fourcc;
Size size;
struct {
@@ -184,7 +207,7 @@ public:
int getFormat(V4L2DeviceFormat *format);
int setFormat(V4L2DeviceFormat *format);
- ImageFormats formats();
+ std::map<V4L2PixelFormat, std::vector<SizeRange>> formats();
int setCrop(Rectangle *rect);
int setCompose(Rectangle *rect);
@@ -205,10 +228,10 @@ public:
static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
const std::string &entity);
- static PixelFormat toPixelFormat(uint32_t v4l2Fourcc);
- uint32_t toV4L2Fourcc(const PixelFormat &pixelFormat);
- static uint32_t toV4L2Fourcc(const PixelFormat &pixelFormat,
- bool multiplanar);
+ static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);
+ V4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat);
+ static V4L2PixelFormat toV4L2Fourcc(const PixelFormat &pixelFormat,
+ bool multiplanar);
protected:
std::string logPrefix() const;
@@ -223,8 +246,8 @@ private:
int getFormatSingleplane(V4L2DeviceFormat *format);
int setFormatSingleplane(V4L2DeviceFormat *format);
- std::vector<unsigned int> enumPixelformats();
- std::vector<SizeRange> enumSizes(unsigned int pixelFormat);
+ std::vector<V4L2PixelFormat> enumPixelformats();
+ std::vector<SizeRange> enumSizes(V4L2PixelFormat pixelFormat);
int setSelection(unsigned int target, Rectangle *rect);
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 73114975..67750fbc 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -154,8 +154,8 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
if (roles.empty())
return config;
- std::map<unsigned int, std::vector<SizeRange>> v4l2Formats =
- data->video_->formats().data();
+ std::map<V4L2PixelFormat, std::vector<SizeRange>> v4l2Formats =
+ data->video_->formats();
std::map<PixelFormat, std::vector<SizeRange>> deviceFormats;
std::transform(v4l2Formats.begin(), v4l2Formats.end(),
std::inserter(deviceFormats, deviceFormats.begin()),
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 56251a46..1c60014c 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -279,6 +279,65 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
}
/**
+ * \class V4L2PixelFormat
+ * \brief V4L2 pixel format FourCC wrapper
+ *
+ * The V4L2PixelFormat class describes the pixel format of a V4L2 buffer. It
+ * wraps the V4L2 numerical FourCC, and shall be used in all APIs that deal with
+ * V4L2 pixel formats. Its purpose is to prevent unintentional confusion of
+ * V4L2 and DRM FourCCs in code by catching implicit conversion attempts at
+ * compile time.
+ */
+
+/**
+ * \fn V4L2PixelFormat::V4L2PixelFormat()
+ * \brief Construct a V4L2PixelFormat with an invalid format
+ *
+ * V4L2PixelFormat instances constructed with the default constructor are
+ * invalid, calling the isValid() function returns false.
+ */
+
+/**
+ * \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc)
+ * \brief Construct a V4L2PixelFormat from a FourCC value
+ * \param[in] fourcc The pixel format FourCC numerical value
+ */
+
+/**
+ * \fn bool V4L2PixelFormat::isValid() const
+ * \brief Check if the pixel format is valid
+ *
+ * V4L2PixelFormat instances constructed with the default constructor are
+ * invalid. Instances constructed with a FourCC defined in the V4L2 API are
+ * valid. The behaviour is undefined otherwise.
+ *
+ * \return True if the pixel format is valid, false otherwise
+ */
+
+/**
+ * \fn uint32_t V4L2PixelFormat::fourcc() const
+ * \brief Retrieve the pixel format FourCC numerical value
+ * \return The pixel format FourCC numerical value
+ */
+
+/**
+ * \fn V4L2PixelFormat::operator uint32_t() const
+ * \brief Convert to the pixel format FourCC numerical value
+ * \return The pixel format FourCC numerical value
+ */
+
+/**
+ * \brief Assemble and return a string describing the pixel format
+ * \return A string describing the pixel format
+ */
+std::string V4L2PixelFormat::toString() const
+{
+ char str[11];
+ snprintf(str, 11, "0x%08x", fourcc_);
+ return str;
+}
+
+/**
* \class V4L2DeviceFormat
* \brief The V4L2 video device image format and sizes
*
@@ -386,7 +445,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
const std::string V4L2DeviceFormat::toString() const
{
std::stringstream ss;
- ss << size.toString() << "-" << utils::hex(fourcc);
+ ss << size.toString() << "-" << fourcc.toString();
return ss.str();
}
@@ -901,29 +960,31 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
*
* \return A list of the supported video device formats
*/
-ImageFormats V4L2VideoDevice::formats()
+std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()
{
- ImageFormats formats;
+ std::map<V4L2PixelFormat, std::vector<SizeRange>> formats;
- for (unsigned int pixelformat : enumPixelformats()) {
- std::vector<SizeRange> sizes = enumSizes(pixelformat);
+ for (V4L2PixelFormat pixelFormat : enumPixelformats()) {
+ std::vector<SizeRange> sizes = enumSizes(pixelFormat);
if (sizes.empty())
return {};
- if (formats.addFormat(pixelformat, sizes)) {
+ if (formats.find(pixelFormat) != formats.end()) {
LOG(V4L2, Error)
<< "Could not add sizes for pixel format "
- << pixelformat;
+ << pixelFormat;
return {};
}
+
+ formats.emplace(pixelFormat, sizes);
}
return formats;
}
-std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()
+std::vector<V4L2PixelFormat> V4L2VideoDevice::enumPixelformats()
{
- std::vector<unsigned int> formats;
+ std::vector<V4L2PixelFormat> formats;
int ret;
for (unsigned int index = 0; ; index++) {
@@ -948,7 +1009,7 @@ std::vector<unsigned int> V4L2VideoDevice::enumPixelformats()
return formats;
}
-std::vector<SizeRange> V4L2VideoDevice::enumSizes(unsigned int pixelFormat)
+std::vector<SizeRange> V4L2VideoDevice::enumSizes(V4L2PixelFormat pixelFormat)
{
std::vector<SizeRange> sizes;
int ret;
@@ -1563,7 +1624,7 @@ V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media,
* \param[in] v4l2Fourcc The V4L2 pixel format (V4L2_PIX_FORMAT_*)
* \return The PixelFormat corresponding to \a v4l2Fourcc
*/
-PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
+PixelFormat V4L2VideoDevice::toPixelFormat(V4L2PixelFormat v4l2Fourcc)
{
switch (v4l2Fourcc) {
/* RGB formats. */
@@ -1612,7 +1673,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
LogError).stream()
<< "Unsupported V4L2 pixel format "
- << utils::hex(v4l2Fourcc);
+ << v4l2Fourcc.toString();
return PixelFormat();
}
}
@@ -1628,7 +1689,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
*
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
*/
-uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
{
return V4L2VideoDevice::toV4L2Fourcc(pixelFormat, caps_.isMultiplanar());
}
@@ -1646,8 +1707,8 @@ uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat)
*
* \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
*/
-uint32_t V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,
- bool multiplanar)
+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(const PixelFormat &pixelFormat,
+ bool multiplanar)
{
switch (pixelFormat) {
/* RGB formats. */