[libcamera-devel] [RFC 2/6] libcamera: formats: Turn ImageFormats into a template

Niklas Söderlund niklas.soderlund at ragnatech.se
Fri Feb 28 04:29:09 CET 2020


The ImageFormats class is used to carry both V4L2 pixelformats and mbus
codes as keys to lookup different supported sizes. The reason for this
is that both V4L2 pixelformats and mbus codes are unsigned integers and
the keyword PixelFormat is currently defined as such.

Going forward PixelFormat will be reworked into a class so their is a
need to have ImageFormats instances with two different key types, turn
it into an template and update all sites to use unsigned int where a
mbus code is the key and PixelFormat otherwise.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
---
 src/libcamera/camera_sensor.cpp          |  2 +-
 src/libcamera/formats.cpp                | 19 +++++++++++++------
 src/libcamera/include/formats.h          | 11 ++++++-----
 src/libcamera/include/v4l2_subdevice.h   |  2 +-
 src/libcamera/include/v4l2_videodevice.h |  2 +-
 src/libcamera/pipeline/uvcvideo.cpp      |  2 +-
 src/libcamera/pipeline/vimc.cpp          |  2 +-
 src/libcamera/v4l2_subdevice.cpp         |  4 ++--
 src/libcamera/v4l2_videodevice.cpp       |  4 ++--
 test/v4l2_subdevice/list_formats.cpp     |  2 +-
 10 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index 2219a43074362834..23fdafb690117d91 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -131,7 +131,7 @@ int CameraSensor::init()
 	properties_.set(properties::Rotation, propertyValue);
 
 	/* Enumerate and cache media bus codes and sizes. */
-	const ImageFormats formats = subdev_->formats(0);
+	const ImageFormats<unsigned int> formats = subdev_->formats(0);
 	if (formats.isEmpty()) {
 		LOG(CameraSensor, Error) << "No image format found";
 		return -EINVAL;
diff --git a/src/libcamera/formats.cpp b/src/libcamera/formats.cpp
index 5f6552a4e06c5231..98817deee2b54c84 100644
--- a/src/libcamera/formats.cpp
+++ b/src/libcamera/formats.cpp
@@ -39,7 +39,8 @@ namespace libcamera {
  * \return 0 on success or a negative error code otherwise
  * \retval -EEXIST The format is already described
  */
-int ImageFormats::addFormat(unsigned int format, const std::vector<SizeRange> &sizes)
+template<typename T>
+int ImageFormats<T>::addFormat(T format, const std::vector<SizeRange> &sizes)
 {
 	if (data_.find(format) != data_.end())
 		return -EEXIST;
@@ -53,7 +54,8 @@ int ImageFormats::addFormat(unsigned int format, const std::vector<SizeRange> &s
  * \brief Check if the list of devices supported formats is empty
  * \return True if the list of supported formats is empty
  */
-bool ImageFormats::isEmpty() const
+template<typename T>
+bool ImageFormats<T>::isEmpty() const
 {
 	return data_.empty();
 }
@@ -62,9 +64,10 @@ bool ImageFormats::isEmpty() const
  * \brief Retrieve a list of all supported image formats
  * \return List of pixel formats or media bus codes
  */
-std::vector<unsigned int> ImageFormats::formats() const
+template<typename T>
+std::vector<T> ImageFormats<T>::formats() const
 {
-	std::vector<unsigned int> formats;
+	std::vector<T> formats;
 	formats.reserve(data_.size());
 
 	/* \todo: Should this be cached instead of computed each time? */
@@ -84,7 +87,8 @@ std::vector<unsigned int> ImageFormats::formats() const
  * \return The list of image sizes supported for \a format, or an empty list if
  * the format is not supported
  */
-const std::vector<SizeRange> &ImageFormats::sizes(unsigned int format) const
+template<typename T>
+const std::vector<SizeRange> &ImageFormats<T>::sizes(T format) const
 {
 	static const std::vector<SizeRange> empty;
 
@@ -99,9 +103,12 @@ const std::vector<SizeRange> &ImageFormats::sizes(unsigned int format) const
  * \brief Retrieve the map that associates formats to image sizes
  * \return The map that associates formats to image sizes
  */
-const std::map<unsigned int, std::vector<SizeRange>> &ImageFormats::data() const
+template<typename T>
+const std::map<T, std::vector<SizeRange>> &ImageFormats<T>::data() const
 {
 	return data_;
 }
 
+template class ImageFormats<unsigned int>;
+
 } /* namespace libcamera */
diff --git a/src/libcamera/include/formats.h b/src/libcamera/include/formats.h
index f43bc8c004f690b4..566be9c09550a830 100644
--- a/src/libcamera/include/formats.h
+++ b/src/libcamera/include/formats.h
@@ -15,18 +15,19 @@
 
 namespace libcamera {
 
+template<typename T>
 class ImageFormats
 {
 public:
-	int addFormat(unsigned int format, const std::vector<SizeRange> &sizes);
+	int addFormat(T format, const std::vector<SizeRange> &sizes);
 
 	bool isEmpty() const;
-	std::vector<unsigned int> formats() const;
-	const std::vector<SizeRange> &sizes(unsigned int format) const;
-	const std::map<unsigned int, std::vector<SizeRange>> &data() const;
+	std::vector<T> formats() const;
+	const std::vector<SizeRange> &sizes(T format) const;
+	const std::map<T, std::vector<SizeRange>> &data() const;
 
 private:
-	std::map<unsigned int, std::vector<SizeRange>> data_;
+	std::map<T, std::vector<SizeRange>> data_;
 };
 
 } /* namespace libcamera */
diff --git a/src/libcamera/include/v4l2_subdevice.h b/src/libcamera/include/v4l2_subdevice.h
index 9c077674f997dae6..53c73617efe4b860 100644
--- a/src/libcamera/include/v4l2_subdevice.h
+++ b/src/libcamera/include/v4l2_subdevice.h
@@ -44,7 +44,7 @@ public:
 	int setCrop(unsigned int pad, Rectangle *rect);
 	int setCompose(unsigned int pad, Rectangle *rect);
 
-	ImageFormats formats(unsigned int pad);
+	ImageFormats<unsigned int> formats(unsigned int pad);
 
 	int getFormat(unsigned int pad, V4L2SubdeviceFormat *format);
 	int setFormat(unsigned int pad, V4L2SubdeviceFormat *format);
diff --git a/src/libcamera/include/v4l2_videodevice.h b/src/libcamera/include/v4l2_videodevice.h
index fcf072641420dacf..982df9d2f918e49c 100644
--- a/src/libcamera/include/v4l2_videodevice.h
+++ b/src/libcamera/include/v4l2_videodevice.h
@@ -180,7 +180,7 @@ public:
 
 	int getFormat(V4L2DeviceFormat *format);
 	int setFormat(V4L2DeviceFormat *format);
-	ImageFormats formats();
+	ImageFormats<PixelFormat> formats();
 
 	int setCrop(Rectangle *rect);
 	int setCompose(Rectangle *rect);
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index cf419e8b25a87389..8efd188e75a3d135 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -155,7 +155,7 @@ CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera,
 	if (roles.empty())
 		return config;
 
-	ImageFormats v4l2formats = data->video_->formats();
+	ImageFormats<PixelFormat> v4l2formats = data->video_->formats();
 	StreamFormats formats(v4l2formats.data());
 	StreamConfiguration cfg(formats);
 
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index 93d89729e1faa29f..9fbe33c626e327d4 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -175,7 +175,7 @@ CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera,
 	if (roles.empty())
 		return config;
 
-	ImageFormats formats;
+	ImageFormats<PixelFormat> formats;
 
 	for (PixelFormat pixelformat : pixelformats) {
 		/* The scaler hardcodes a x3 scale-up ratio. */
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index f2bcd7f73c5c75a1..bec14f80c960d854 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -155,9 +155,9 @@ int V4L2Subdevice::setCompose(unsigned int pad, Rectangle *rect)
  *
  * \return A list of the supported device formats
  */
-ImageFormats V4L2Subdevice::formats(unsigned int pad)
+ImageFormats<unsigned int> V4L2Subdevice::formats(unsigned int pad)
 {
-	ImageFormats formats;
+	ImageFormats<unsigned int> formats;
 
 	if (pad >= entity_->pads().size()) {
 		LOG(V4L2, Error) << "Invalid pad: " << pad;
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 99470ce11421c77c..f84bd00570afa38c 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -837,9 +837,9 @@ int V4L2VideoDevice::setFormatSingleplane(V4L2DeviceFormat *format)
  *
  * \return A list of the supported video device formats
  */
-ImageFormats V4L2VideoDevice::formats()
+ImageFormats<PixelFormat> V4L2VideoDevice::formats()
 {
-	ImageFormats formats;
+	ImageFormats<PixelFormat> formats;
 
 	for (unsigned int pixelformat : enumPixelformats()) {
 		std::vector<SizeRange> sizes = enumSizes(pixelformat);
diff --git a/test/v4l2_subdevice/list_formats.cpp b/test/v4l2_subdevice/list_formats.cpp
index 067dc5ed30f4edd9..201a294c72a09b4d 100644
--- a/test/v4l2_subdevice/list_formats.cpp
+++ b/test/v4l2_subdevice/list_formats.cpp
@@ -47,7 +47,7 @@ void ListFormatsTest::printFormats(unsigned int pad,
 int ListFormatsTest::run()
 {
 	/* List all formats available on existing "Scaler" pads. */
-	ImageFormats formats;
+	ImageFormats<unsigned int> formats;
 
 	formats = scaler_->formats(0);
 	if (formats.isEmpty()) {
-- 
2.25.1



More information about the libcamera-devel mailing list