summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Elder <paul.elder@ideasonboard.com>2022-07-21 01:40:04 +0900
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-11-25 10:52:06 +0200
commit4c30ed47f656d67b619470b9091ebf6661b8a778 (patch)
treed40635f78715e841a0ea58d048ce313dbc6808d5
parent72721611fa5d772a3a2b7cd037e38c5db13dc265 (diff)
pipeline: rkisp1: Query the driver for formats
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@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1_path.cpp51
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1_path.h8
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 2d38f0fb..7a2b0d17 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, Info)
+ << "Failed to enumerate supported formats and sizes, using defaults";
+
+ 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 f3f1ae39..d88effbb 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_;