diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index b3000f3c5133..49d2ca357efa 100644
--- a/src/libcamera/include/v4l2_videodevice.h
+++ b/src/libcamera/include/v4l2_videodevice.h
@@ -149,10 +149,31 @@ private:
 	unsigned int missCounter_;
 };
 
+class V4L2PixelFormat
+{
+public:
+	V4L2PixelFormat()
+		: fourcc_(0)
+	{
+	}
+
+	V4L2PixelFormat(uint32_t fourcc)
+		: fourcc_(fourcc)
+	{
+	}
+
+	bool isValid() const { return fourcc_ != 0; }
+	uint32_t value() const { return fourcc_; }
+	operator uint32_t() const { return fourcc_; }
+
+private:
+	uint32_t fourcc_;
+};
+
 class V4L2DeviceFormat
 {
 public:
-	uint32_t fourcc;
+	V4L2PixelFormat fourcc;
 	Size size;
 
 	struct {
@@ -184,7 +205,7 @@ public:
 
 	int getFormat(V4L2DeviceFormat *format);
 	int setFormat(V4L2DeviceFormat *format);
-	std::map<unsigned int, std::vector<SizeRange>> formats();
+	std::map<V4L2PixelFormat, std::vector<SizeRange>> formats();
 
 	int setCrop(Rectangle *rect);
 	int setCompose(Rectangle *rect);
@@ -203,9 +224,9 @@ public:
 	static V4L2VideoDevice *fromEntityName(const MediaDevice *media,
 					       const std::string &entity);
 
-	static PixelFormat toPixelFormat(uint32_t v4l2Fourcc);
-	uint32_t toV4L2Fourcc(PixelFormat pixelFormat);
-	static uint32_t toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar);
+	static PixelFormat toPixelFormat(V4L2PixelFormat v4l2Fourcc);
+	V4L2PixelFormat toV4L2Fourcc(PixelFormat pixelFormat);
+	static V4L2PixelFormat toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar);
 
 protected:
 	std::string logPrefix() const;
@@ -220,8 +241,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/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 81911e764fde..40396c22aa45 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -277,6 +277,46 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
 	return true;
 }
 
+/**
+ * \class V4L2PixelFormat
+ * \brief V4L2 pixel format 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 an invalid V4L2 pixel format with a numerical value of 0
+ */
+
+/**
+ * \fn V4L2PixelFormat::V4L2PixelFormat(uint32_t fourcc)
+ * \brief Construct a V4L2 pixel format from a FourCC value
+ * \param[in] fourcc The pixel format numerical value
+ */
+
+/**
+ * \fn bool V4L2PixelFormat::isValid() const
+ * \brief Check if the pixel format is valid
+ * \return True if the pixel format has a non-zero value, false otherwise
+ */
+
+/**
+ * \fn uint32_t V4L2PixelFormat::value() const
+ * \brief Retrieve the pixel format numerical value
+ * \return The pixel format numerical value
+ */
+
+/**
+ * \fn V4L2PixelFormat::operator uint32_t() const
+ * \brief Convert the the pixel format numerical value
+ * \return The pixel format numerical value
+ */
+
 /**
  * \class V4L2DeviceFormat
  * \brief The V4L2 video device image format and sizes
@@ -385,7 +425,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() << "-" << utils::hex(fourcc.value());
 	return ss.str();
 }
 
@@ -844,11 +884,11 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
  *
  * \return A list of the supported video device formats
  */
-std::map<unsigned int, std::vector<SizeRange>> V4L2VideoDevice::formats()
+std::map<V4L2PixelFormat, std::vector<SizeRange>> V4L2VideoDevice::formats()
 {
-	std::map<unsigned int, std::vector<SizeRange>> formats;
+	std::map<V4L2PixelFormat, std::vector<SizeRange>> formats;
 
-	for (unsigned int pixelformat : enumPixelformats()) {
+	for (V4L2PixelFormat pixelformat : enumPixelformats()) {
 		std::vector<SizeRange> sizes = enumSizes(pixelformat);
 		if (sizes.empty())
 			return {};
@@ -859,9 +899,9 @@ std::map<unsigned int, std::vector<SizeRange>> V4L2VideoDevice::formats()
 	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++) {
@@ -886,7 +926,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;
@@ -1417,7 +1457,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. */
@@ -1466,7 +1506,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
 		libcamera::_log(__FILE__, __LINE__, _LOG_CATEGORY(V4L2)(),
 				LogError).stream()
 			<< "Unsupported V4L2 pixel format "
-			<< utils::hex(v4l2Fourcc);
+			<< utils::hex(v4l2Fourcc.value());
 		return PixelFormat();
 	}
 }
@@ -1482,7 +1522,7 @@ PixelFormat V4L2VideoDevice::toPixelFormat(uint32_t v4l2Fourcc)
  *
  * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
  */
-uint32_t V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat)
+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat)
 {
 	return V4L2VideoDevice::toV4L2Fourcc(pixelFormat, caps_.isMultiplanar());
 }
@@ -1500,7 +1540,7 @@ uint32_t V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat)
  *
  * \return The V4L2_PIX_FMT_* pixel format code corresponding to \a pixelFormat
  */
-uint32_t V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar)
+V4L2PixelFormat V4L2VideoDevice::toV4L2Fourcc(PixelFormat pixelFormat, bool multiplanar)
 {
 	switch (pixelFormat.fourcc()) {
 	/* RGB formats. */
