From patchwork Fri Sep 13 10:37:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 21260 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 85F86C3257 for ; Fri, 13 Sep 2024 10:38:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 343F4634FC; Fri, 13 Sep 2024 12:38:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="v9olU9cd"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B8A1634E3 for ; Fri, 13 Sep 2024 12:38:08 +0200 (CEST) Received: from ATX.abc.com (unknown [IPv6:2405:201:2015:f873:55f8:639e:8e9f:12ec]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C67F6EA5; Fri, 13 Sep 2024 12:36:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1726223809; bh=yVj/SIPMZy7M9m0HCZSpq2RwX556oqea0I6BQ86aEQk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v9olU9cdKRscSlas1VFapq2RteUrDG+O9BTSWMbganxcuqgemLadov5SQIMUdWu3N B28h5KPe2pJGvb7OacWK9zBhT0mKq1owqhm0KpiYbBG1EjJOPOweR6DAi2Ixkr9gDM d2tJ6wE1zPuJANxO2S0aTi1b3lHvoUxh9BqtEXpw= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v2 1/2] pipeline: rkisp1: Bound RkISP1 path to ISP maximum input Date: Fri, 13 Sep 2024 16:07:58 +0530 Message-ID: <20240913103759.2166-2-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240913103759.2166-1-umang.jain@ideasonboard.com> References: <20240913103759.2166-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The RkISP1Path class has maximum resolution defined by RKISP1_RSZ_*_SRC_MAX macros. It might get updated in populateFormats() by querying the formats on the rkisp1_*path video nodes. However, it does not take into account the maximum resolution that the ISP can handle. For instance on i.MX8MP, 4096x3072 is the maximum supported ISP resolution however, RkISP1MainPath had the maximum resolution of RKISP1_RSZ_MP_SRC_MAX, prior to this patch. Fix it by bounding the maximum resolution of RkISP1Path class by passing the maximum resolution of the ISP during RkISP1Path::init(). Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 15 +++++++++++++-- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 13 ++++++++++++- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 0a794d63..00b0dad8 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1274,6 +1274,17 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (isp_->open() < 0) return false; + /* + * Retrieve the ISP maximum input size for config validation in the + * path classes. + * + * The ISP maximum input size is independent of the media bus formats + * hence, pick the one first entry of ispFormats and its size range. + */ + const V4L2Subdevice::Formats ispFormats = isp_->formats(0); + const SizeRange range = ispFormats.cbegin()->second[0]; + const Size ispMaxInputSize = range.max; + /* Locate and open the optional CSI-2 receiver. */ ispSink_ = isp_->entity()->getPadByIndex(0); if (!ispSink_ || ispSink_->links().empty()) @@ -1300,10 +1311,10 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) return false; /* Locate and open the ISP main and self paths. */ - if (!mainPath_.init(media_)) + if (!mainPath_.init(media_, ispMaxInputSize)) return false; - if (hasSelfPath_ && !selfPath_.init(media_)) + if (hasSelfPath_ && !selfPath_.init(media_, ispMaxInputSize)) return false; mainPath_.bufferReady().connect(this, &PipelineHandlerRkISP1::bufferReady); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index c49017d1..08b39e1e 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -62,7 +62,7 @@ RkISP1Path::RkISP1Path(const char *name, const Span &formats, { } -bool RkISP1Path::init(MediaDevice *media) +bool RkISP1Path::init(MediaDevice *media, Size ispMaxInputSize) { std::string resizer = std::string("rkisp1_resizer_") + name_ + "path"; std::string video = std::string("rkisp1_") + name_ + "path"; @@ -77,6 +77,17 @@ bool RkISP1Path::init(MediaDevice *media) populateFormats(); + /* + * The maximum size reported by the video node during populateFormats() + * is hard coded to a fixed size which can exceed the platform specific + * ISP limitations. + * + * The video node should report a maximum size according to the ISP + * model. This should be fixed in the kernel. For now, restrict the + * maximum size to the ISP limitations correctly. + */ + maxResolution_.boundTo(ispMaxInputSize); + link_ = media->link("rkisp1_isp", 2, resizer, 0); if (!link_) return false; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 08edefec..13ba4b62 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -35,7 +35,7 @@ public: RkISP1Path(const char *name, const Span &formats, const Size &minResolution, const Size &maxResolution); - bool init(MediaDevice *media); + bool init(MediaDevice *media, Size ispMaxInputSize); int setEnabled(bool enable) { return link_->setEnabled(enable); } bool isEnabled() const { return link_->flags() & MEDIA_LNK_FL_ENABLED; } From patchwork Fri Sep 13 10:37:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 21261 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 9B06AC3261 for ; Fri, 13 Sep 2024 10:38:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D648E634FE; Fri, 13 Sep 2024 12:38:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="eGSXhYon"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3D8EE634E3 for ; Fri, 13 Sep 2024 12:38:09 +0200 (CEST) Received: from ATX.abc.com (unknown [IPv6:2405:201:2015:f873:55f8:639e:8e9f:12ec]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id C9B2B74C; Fri, 13 Sep 2024 12:36:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1726223810; bh=6Lxe43CgxArDNTN3+HfUGCc6yqNQW7Ex/SUrgOFP0NI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eGSXhYon1/FoDfDKKmy10rkLyeCkGpPvAfD9Iwf14+Cvic5HkAK0++8v2lYWtK22s CG3iKhXMbgeLYzdnc4JDAe81SuAsLQMWDY7bhIGMcpMNoLELvDBm/y1NK0ZGA4Or5B ZBHB+Qh+shFEA3llzABEFwvjlR0JzV74d2iEIWdc= From: Umang Jain To: libcamera-devel@lists.libcamera.org Cc: Umang Jain , Kieran Bingham Subject: [PATCH v2 2/2] pipeline: rkisp1: Filter out sensor sizes not supported by the pipeline Date: Fri, 13 Sep 2024 16:07:59 +0530 Message-ID: <20240913103759.2166-3-umang.jain@ideasonboard.com> X-Mailer: git-send-email 2.45.0 In-Reply-To: <20240913103759.2166-1-umang.jain@ideasonboard.com> References: <20240913103759.2166-1-umang.jain@ideasonboard.com> MIME-Version: 1.0 X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" It is possible that the maximum sensor size (returned by CameraSensor::resolution()) is not supported by the pipeline. In such cases, a filter function is required to filter out resolutions of the camera sensor, which cannot be supported by the pipeline. Introduce the filter function filterSensorResolution() in RkISP1Path class and use it for validate() and generateConfiguration(). The maximum sensor resolution is picked from that filtered set of resolutions instead of CameraSensor::resolution(). Signed-off-by: Umang Jain Reviewed-by: Kieran Bingham Tested-by: Kieran Bingham --- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 51 ++++++++++++++++++- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 8 +++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 08b39e1e..1d818b32 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -137,12 +137,59 @@ void RkISP1Path::populateFormats() } } +/** + * \brief Filter the sensor resolutions that can be supported + * \param[in] sensor The camera sensor + * + * This function retrieves all the sizes supported by the sensor and + * filters all the resolutions that can be supported on the pipeline. + * It is possible that the sensor's maximum output resolution is higher + * than the ISP maximum input. In that case, this function filters out all + * the resolution incapable of being supported and returns the maximum + * sensor resolution that can be supported by the pipeline. + * + * \return Maximum sensor size supported on the pipeline + */ +Size RkISP1Path::filterSensorResolution(const CameraSensor *sensor) +{ + auto iter = sensorSizesMap_.find(sensor); + if (iter != sensorSizesMap_.end() && !iter->second.empty()) + return iter->second.back(); + + sensorSizesMap_.emplace(sensor, std::vector()); + + std::vector sensorSizes; + const std::vector &mbusCodes = sensor->mbusCodes(); + for (const auto it : mbusCodes) { + std::vector sizes = sensor->sizes(it); + for (Size sz : sizes) + sensorSizes.push_back(sz); + } + + std::sort(sensorSizes.begin(), sensorSizes.end()); + + /* Remove duplicates. */ + auto last = std::unique(sensorSizes.begin(), sensorSizes.end()); + sensorSizes.erase(last, sensorSizes.end()); + + /* Discard any sizes that the pipeline is unable to support. */ + for (auto sz : sensorSizes) { + if (sz.width > maxResolution_.width || + sz.height > maxResolution_.height) + continue; + + sensorSizesMap_[sensor].push_back(sz); + } + + return sensorSizesMap_[sensor].back(); +} + StreamConfiguration RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size, StreamRole role) { const std::vector &mbusCodes = sensor->mbusCodes(); - const Size &resolution = sensor->resolution(); + Size resolution = filterSensorResolution(sensor); /* Min and max resolutions to populate the available stream formats. */ Size maxResolution = maxResolution_.boundedToAspectRatio(resolution) @@ -231,7 +278,7 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor, StreamConfiguration *cfg) { const std::vector &mbusCodes = sensor->mbusCodes(); - const Size &resolution = sensor->resolution(); + Size resolution = filterSensorResolution(sensor); const StreamConfiguration reqCfg = *cfg; CameraConfiguration::Status status = CameraConfiguration::Valid; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 13ba4b62..457c9ac9 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -63,6 +64,7 @@ public: private: void populateFormats(); + Size filterSensorResolution(const CameraSensor *sensor); static constexpr unsigned int RKISP1_BUFFER_COUNT = 4; @@ -77,6 +79,12 @@ private: std::unique_ptr resizer_; std::unique_ptr video_; MediaLink *link_; + + /* + * Map from camera sensors to the sizes (in increasing order), + * which are guaranteed to be supported by the pipeline. + */ + std::map> sensorSizesMap_; }; class RkISP1MainPath : public RkISP1Path