From patchwork Tue Jan 16 09:17:53 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Elder X-Patchwork-Id: 19411 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 A50E8C323E for ; Tue, 16 Jan 2024 09:18:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0460F628DA; Tue, 16 Jan 2024 10:18:36 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1705396716; bh=WjV4LZEMIYq5SMiBjkSsdtl5PoZahZ4ttfK6GttpLw8=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=h7YWLytyDVP1rWl0apmjPLSk0wRWbIA3fjIdA6kJtCvwcAoSmpdGmr5eedfw/tyqM vY5hMhyg9W5QZovVe7rdnDgLm8VLYluORO9E4Jj8znL0uxKyTXXjezhX0u8uSq4Vbv UlZmxP4z2vYY3Cian4r3FL/z7B7Es6gKlrANBEdJMFoa9lMrVef/ESZOlkrqgUrXLl FTwfD9KlRhUR0leQY4gvZl1B2DFXeAuxjOtkwbUB6dg0RWXQZAQJTOnnJb0mGcceNS TCAFhCMDB6K+nOEsn0q/GojtSeAzhO0p3juyG84ZjEAvaabNRCxY31iYiXdUinYeDz L6p1u/lPFv05A== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DBAAC628AD for ; Tue, 16 Jan 2024 10:18:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="lpUHgxsF"; dkim-atps=neutral Received: from pyrite.hamster-moth.ts.net (h175-177-049-156.catv02.itscom.jp [175.177.49.156]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 440AA3D9; Tue, 16 Jan 2024 10:17:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1705396645; bh=WjV4LZEMIYq5SMiBjkSsdtl5PoZahZ4ttfK6GttpLw8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lpUHgxsFZWOjwi78ZrJgyR0DV6sEkHdFD7Yti5z+peg6ZRlQ6ByZlU/5P/V3vFFfN Nij79APKGzG4i7deaRcg914tBBmMbMeylCB5PJpLuTexh3mRVACYXDh+/xqiPAlGLV AuzEKs8X6Kv2IwdmoZ5vhFNwynj8UBSyak1wUWec= To: libcamera-devel@lists.libcamera.org Date: Tue, 16 Jan 2024 18:17:53 +0900 Message-Id: <20240116091754.100654-3-paul.elder@ideasonboard.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240116091754.100654-1-paul.elder@ideasonboard.com> References: <20240116091754.100654-1-paul.elder@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] pipeline: rkisp1: Fix validation when sensor max is larger than ISP input 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: , X-Patchwork-Original-From: Paul Elder via libcamera-devel From: Paul Elder Reply-To: Paul Elder Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" If the maximum sensor output size is larger than the maximum ISP input size, the maximum sensor size could be selected and the pipeline would fail with an EPIPE. Fix this by clamping the sensor size to the ISP input size at validation time. Signed-off-by: Paul Elder Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 17 ++++++++++-- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 26 +++++++++---------- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 4 ++- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 586b46d64..fb67ba8f4 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -1202,11 +1202,24 @@ bool PipelineHandlerRkISP1::match(DeviceEnumerator *enumerator) if (param_->open() < 0) return false; + /* + * Retrieve ISP maximum input size for config validation in the path + * classes + */ + Size ispMaxInSize = { 0, 0 }; + V4L2Subdevice::Formats ispFormats = isp_->formats(0); + for (const auto &[mbus, sizes] : ispFormats) { + for (const auto &size : sizes) { + if (ispMaxInSize < size.max) + ispMaxInSize = size.max; + } + } + /* Locate and open the ISP main and self paths. */ - if (!mainPath_.init(media_)) + if (!mainPath_.init(media_, ispMaxInSize)) return false; - if (hasSelfPath_ && !selfPath_.init(media_)) + if (hasSelfPath_ && !selfPath_.init(media_, ispMaxInSize)) 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 b62b645ca..eaab7e857 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, const Size &ispMaxInSize) { std::string resizer = std::string("rkisp1_resizer_") + name_ + "path"; std::string video = std::string("rkisp1_") + name_ + "path"; @@ -76,6 +76,7 @@ bool RkISP1Path::init(MediaDevice *media) return false; populateFormats(); + ispMaxInSize_ = ispMaxInSize; link_ = media->link("rkisp1_isp", 2, resizer, 0); if (!link_) @@ -172,7 +173,9 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size, /* Add all the RAW sizes the sensor can produce for this code. */ for (const auto &rawSize : sensor->sizes(mbusCode)) { if (rawSize.width > maxResolution_.width || - rawSize.height > maxResolution_.height) + rawSize.height > maxResolution_.height || + rawSize.width > ispMaxInSize_.width || + rawSize.height > ispMaxInSize_.height) continue; streamFormats[format].push_back({ rawSize, rawSize }); @@ -275,8 +278,9 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor, if (!found) cfg->pixelFormat = isRaw ? rawFormat : formats::NV12; - Size minResolution; - Size maxResolution; + Size maxResolution = maxResolution_.boundedToAspectRatio(resolution) + .boundedTo(resolution); + Size minResolution = minResolution_.expandedToAspectRatio(resolution); if (isRaw) { /* @@ -287,16 +291,10 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor, V4L2SubdeviceFormat sensorFormat = sensor->getFormat({ mbusCode }, cfg->size); - minResolution = sensorFormat.size; - maxResolution = sensorFormat.size; - } else { - /* - * Adjust the size based on the sensor resolution and absolute - * limits of the ISP. - */ - minResolution = minResolution_.expandedToAspectRatio(resolution); - maxResolution = maxResolution_.boundedToAspectRatio(resolution) - .boundedTo(resolution); + if (!sensorFormat.size.isNull()) { + minResolution = sensorFormat.size.boundedTo(ispMaxInSize_); + maxResolution = sensorFormat.size.boundedTo(ispMaxInSize_); + } } cfg->size.boundTo(maxResolution); diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index cd77957ee..c96bd5557 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, const Size &ispMaxInSize); int setEnabled(bool enable) { return link_->setEnabled(enable); } bool isEnabled() const { return link_->flags() & MEDIA_LNK_FL_ENABLED; } @@ -77,6 +77,8 @@ private: std::unique_ptr resizer_; std::unique_ptr video_; MediaLink *link_; + + Size ispMaxInSize_; }; class RkISP1MainPath : public RkISP1Path