diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
index 56f4ddb51ffad4d3..f5841b38cea5686c 100644
--- a/src/libcamera/formats.cpp
+++ b/src/libcamera/formats.cpp
@@ -24,4 +24,162 @@ namespace libcamera {
  * resolutions represented by SizeRange items.
  */
 
+
+/**
+ * \class DeviceFormats
+ * \brief Base class for V4L2Device and V4L2SubDevice Formats
+ *
+ * The base class holds common functionallity between V4L2DeviceFormats and
+ * V4L2SubDeviceForamts.
+ *
+ * \sa V4L2DeviceFormats
+ * \sa V4L2SubDeviceForamts
+ */
+
+/**
+ * \brief Create an empty DeviceFormats
+ */
+DeviceFormats::DeviceFormats()
+{
+}
+
+/**
+ * \brief Create a DeviceFormats with data
+ */
+DeviceFormats::DeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data)
+	: data_(data)
+{
+}
+
+DeviceFormats::~DeviceFormats()
+{
+}
+
+/**
+ * \brief Retrieve all sizes for a specific format
+ * \param[in] format A pixelformat or mbus code
+ *
+ * Retrieves all SizeRanges for a specific format. For V4L2Device \a format is a
+ * pixelformoat while for a V4L2Subdevice \a format is a media bus code.
+ *
+ * \return List of SizeRanges for \a format, empty list if format is not valid
+ */
+std::vector<SizeRange> DeviceFormats::sizes(unsigned int format) const
+{
+	auto const &it = data_.find(format);
+	if (it == data_.end())
+		return {};
+
+	return it->second;
+}
+
+/**
+ * \brief Check if the device formats is empty
+ * \return True if the formats are empty
+ */
+bool DeviceFormats::empty() const
+{
+	return data_.empty();
+}
+
+/**
+ * \brief Retrieve the raw dataA
+ * \return Raw map containgin formats to SizeRanges
+ */
+const std::map<unsigned int, std::vector<SizeRange>> &DeviceFormats::data()
+{
+	return data_;
+}
+
+/**
+ * \brief Retrieve a list all contained formats
+ *
+ * This is a helper function intended to be used by V4L2DeviceFormats and
+ * V4L2SubdeviceFormats.
+ *
+ * \return A list of formats contained
+ */
+std::vector<unsigned int> DeviceFormats::formats() const
+{
+	std::vector<unsigned int> formats;
+
+	for (auto const &it : data_)
+		formats.push_back(it.first);
+
+	return formats;
+}
+
+/**
+ * \var DeviceFormats::data_
+ * \brief The map holding format and SizeRange information
+ */
+
+/**
+ * \class V4L2SubdeviceFormats
+ * \brief Holds media bus codes to frame sizes information for a v4l2 subdevice
+ *
+ * Hold media bus codes and frame sizes which describes a v4l2 subdevice. The
+ * intended user of this object is pipeline handlers which can create it
+ * from a V4L2Subdevice and use it to describe and validate formats.
+ */
+
+/**
+ * \brief Create an empty V4L2SubdeviceFormats
+ */
+V4L2SubdeviceFormats::V4L2SubdeviceFormats()
+	: DeviceFormats()
+{
+}
+
+/**
+ * \brief Create an V4L2SubdeviceFormats with data
+ */
+V4L2SubdeviceFormats::V4L2SubdeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data)
+	: DeviceFormats(data)
+{
+}
+
+/**
+ * \brief Retrieve media bus codes which are described
+ * \return List of media bus codes
+ */
+std::vector<unsigned int> V4L2SubdeviceFormats::codes() const
+{
+	return formats();
+}
+
+/**
+ * \class V4L2DeviceFormats
+ * \brief Holds pixelformats to frame sizes information for a v4l2 device
+ *
+ * Hold pixelformats and frame sizes which describes a v4l2 device. The
+ * intended user of this object is pipeline handlers which can create it
+ * from a V4L2Device and use it to describe and validate formats.
+ */
+
+/**
+ * \brief Create an empty V4L2DeviceFormats
+ */
+V4L2DeviceFormats::V4L2DeviceFormats()
+	: DeviceFormats()
+{
+}
+
+/**
+ * \brief Create an V4L2DeviceFormats with data
+ */
+V4L2DeviceFormats::V4L2DeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data)
+	: DeviceFormats(data)
+{
+}
+
+/**
+ * \brief Retrieve pixelformats which are described
+ * \return List of pixelformats
+ */
+std::vector<unsigned int> V4L2DeviceFormats::pixelformats() const
+{
+	return formats();
+}
+
 } /* namespace libcamera */
diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h
index a73772b1eda068b4..372f6e6d71b236dd 100644
--- a/src/libcamera/include/formats.h
+++ b/src/libcamera/include/formats.h
@@ -17,6 +17,41 @@ namespace libcamera {
 
 typedef std::map<unsigned int, std::vector<SizeRange>> FormatEnum;
 
+class DeviceFormats
+{
+public:
+	virtual ~DeviceFormats();
+
+	std::vector<SizeRange> sizes(unsigned int format) const;
+	bool empty() const;
+	const std::map<unsigned int, std::vector<SizeRange>> &data();
+
+protected:
+	DeviceFormats();
+	DeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data);
+	std::vector<unsigned int> formats() const;
+
+	std::map<unsigned int, std::vector<SizeRange>> data_;
+};
+
+class V4L2SubdeviceFormats : public DeviceFormats
+{
+public:
+	V4L2SubdeviceFormats();
+	V4L2SubdeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data);
+
+	std::vector<unsigned int> codes() const;
+};
+
+class V4L2DeviceFormats : public DeviceFormats
+{
+public:
+	V4L2DeviceFormats();
+	V4L2DeviceFormats(const std::map<unsigned int, std::vector<SizeRange>> &data);
+
+	std::vector<unsigned int> pixelformats() const;
+};
+
 } /* namespace libcamera */
 
 #endif /* __LIBCAMERA_FORMATS_H__ */
