[libcamera-devel] [PATCH v3 10/13] pipeline: rkisp1: Query the driver for formats
Jacopo Mondi
jacopo at jmondi.org
Wed Oct 26 17:32:41 CEST 2022
Hi Laurent
On Mon, Oct 24, 2022 at 03:03:53AM +0300, Laurent Pinchart via libcamera-devel wrote:
> From: Paul Elder <paul.elder at ideasonboard.com>
>
> Query the driver for the output formats and sizes that it supports,
> instead of hardcoding them. This allows future-proofing for formats that
> are supported by some but not all versions of the driver.
>
> As the rkisp1 driver currently does not support VIDIOC_ENUM_FRAMESIZES,
> fallback to the hardcoded list of supported formats and framesizes. This
> feature will be added to the driver in parallel, though we cannot
> guarantee that users will have a new enough kernel for it.
>
> Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> Changes since v2:
>
> - Don't pass V4L2VideoDevice to RkISP1Path::populateFormats()
> - Use structured binding in for range loop
> - Use std::set::count() to replace std::find_if()
> - Don't cache sizes, use std::set instead of std::map
> - Update min and max resolutions based on enumerated sizes
> - Drop comment about aspect ratio
>
> Changes since v1:
>
> - Enumerate and cache framesizes as well
> - Massage generateConfiguration accordingly
> - This lets us skip modifying V4L2VideoDevice::formats() to support lack
> of ENUM_FRAMESIZES
> - Also requires us to keep the list of hardcoded formats for backward
> compatibility
> ---
> src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 51 +++++++++++++++++--
> src/libcamera/pipeline/rkisp1/rkisp1_path.h | 8 ++-
> 2 files changed, 54 insertions(+), 5 deletions(-)
>
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
> index 2d38f0fb37ab..8077a54494a5 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp
> @@ -41,6 +41,8 @@ bool RkISP1Path::init(MediaDevice *media)
> if (video_->open() < 0)
> return false;
>
> + populateFormats();
> +
> link_ = media->link("rkisp1_isp", 2, resizer, 0);
> if (!link_)
> return false;
> @@ -48,6 +50,41 @@ bool RkISP1Path::init(MediaDevice *media)
> return true;
> }
>
> +void RkISP1Path::populateFormats()
> +{
> + V4L2VideoDevice::Formats v4l2Formats = video_->formats();
> + if (v4l2Formats.empty()) {
> + LOG(RkISP1, Warning)
This might warn users that something went wrong, while as the driver
has been upstream without this feature for some time and there's
nothing wrong. I would demote the error
This apart
Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
> + << "Failed to enumerate framesizes. Loading default framesizes";
> +
> + for (const PixelFormat &format : formats_)
> + streamFormats_.insert(format);
> + return;
> + }
> +
> + minResolution_ = { 65535, 65535 };
> + maxResolution_ = { 0, 0 };
> +
> + std::vector<PixelFormat> formats;
> + for (const auto &[format, sizes] : v4l2Formats) {
> + const PixelFormat pixelFormat = format.toPixelFormat();
> + const PixelFormatInfo &info = PixelFormatInfo::info(pixelFormat);
> +
> + /* \todo Add support for RAW formats. */
> + if (info.colourEncoding == PixelFormatInfo::ColourEncodingRAW)
> + continue;
> +
> + streamFormats_.insert(pixelFormat);
> +
> + for (const auto &size : sizes) {
> + if (minResolution_ > size.min)
> + minResolution_ = size.min;
> + if (maxResolution_ < size.max)
> + maxResolution_ = size.max;
> + }
> + }
> +}
> +
> StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution)
> {
> Size maxResolution = maxResolution_.boundedToAspectRatio(resolution)
> @@ -55,7 +92,7 @@ StreamConfiguration RkISP1Path::generateConfiguration(const Size &resolution)
> Size minResolution = minResolution_.expandedToAspectRatio(resolution);
>
> std::map<PixelFormat, std::vector<SizeRange>> streamFormats;
> - for (const PixelFormat &format : formats_)
> + for (const auto &format : streamFormats_)
> streamFormats[format] = { { minResolution, maxResolution } };
>
> StreamFormats formats(streamFormats);
> @@ -72,8 +109,12 @@ CameraConfiguration::Status RkISP1Path::validate(StreamConfiguration *cfg)
> const StreamConfiguration reqCfg = *cfg;
> CameraConfiguration::Status status = CameraConfiguration::Valid;
>
> - if (std::find(formats_.begin(), formats_.end(), cfg->pixelFormat) ==
> - formats_.end())
> + /*
> + * Default to NV12 if the requested format is not supported. All
> + * versions of the ISP are guaranteed to support NV12 on both the main
> + * and self paths.
> + */
> + if (!streamFormats_.count(cfg->pixelFormat))
> cfg->pixelFormat = formats::NV12;
>
> cfg->size.boundTo(maxResolution_);
> @@ -204,6 +245,10 @@ void RkISP1Path::stop()
> running_ = false;
> }
>
> +/*
> + * \todo Remove the hardcoded resolutions and formats once all users will have
> + * migrated to a recent enough kernel.
> + */
> namespace {
> constexpr Size RKISP1_RSZ_MP_SRC_MIN{ 32, 16 };
> constexpr Size RKISP1_RSZ_MP_SRC_MAX{ 4416, 3312 };
> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
> index f3f1ae391d65..d88effbb6f56 100644
> --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h
> +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h
> @@ -8,6 +8,7 @@
> #pragma once
>
> #include <memory>
> +#include <set>
> #include <vector>
>
> #include <libcamera/base/signal.h>
> @@ -57,14 +58,17 @@ public:
> Signal<FrameBuffer *> &bufferReady() { return video_->bufferReady; }
>
> private:
> + void populateFormats();
> +
> static constexpr unsigned int RKISP1_BUFFER_COUNT = 4;
>
> const char *name_;
> bool running_;
>
> const Span<const PixelFormat> formats_;
> - const Size minResolution_;
> - const Size maxResolution_;
> + std::set<PixelFormat> streamFormats_;
> + Size minResolution_;
> + Size maxResolution_;
>
> std::unique_ptr<V4L2Subdevice> resizer_;
> std::unique_ptr<V4L2VideoDevice> video_;
> --
> Regards,
>
> Laurent Pinchart
>
More information about the libcamera-devel
mailing list