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

Jacopo Mondi jacopo at jmondi.org
Fri Feb 28 10:46:51 CET 2020


Hi Niklas,

On Fri, Feb 28, 2020 at 04:29:09AM +0100, Niklas Söderlund wrote:
> 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.
>

Sorry, but I'm not sure to follow.

ImageFormats is said to report image formats for V4L2Device and
V4L2Subdevices at the moment and indeed it uses an unsigned int as key
which could be interpreted as either a v4l2 fourcc in case we're
dealing with a video device, or as an mbus media code if we're dealing
with a v4l2 subdev.

PixelFormat is designed to be exposed to applications, and I would
really avoid create dependencies between the V4L2VideoDevice 4cc
codes and the application facing one.

I agree ImageFormats is not a descriptive name, and I would be in
favour of renaming it to, say, DeviceFormat or whatever, but I'm not
sure what we gain by making v4l2 devices tied to the same class we use
to report image formats to application.

Will I find it out later in the series ?

Thanks
   j

> 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
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.libcamera.org/pipermail/libcamera-devel/attachments/20200228/656378b5/attachment.sig>


More information about the libcamera-devel mailing list