From patchwork Mon Dec 16 15:40:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 22354 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 7F619C32F6 for ; Mon, 16 Dec 2024 15:42:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1E32067F89; Mon, 16 Dec 2024 16:42:13 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="PZR4uHot"; 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 B809367F7C for ; Mon, 16 Dec 2024 16:42:08 +0100 (CET) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:bfdf:3a3c:e45:66e3]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 2B8D082A; Mon, 16 Dec 2024 16:41:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1734363692; bh=A2hoAAODKjXuMBejnr8+ldG7/o0OpNQqa305QPLDEik=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PZR4uHotGOFMjpg6BHN5zbAhKOgb2OeB3XkthZlRc42otnLhTDPFKLEdrYv1cBVYt GI0jvEE/9FPr8Zp1ynO1ZINYaYHACJzGH9aaoDd6FKLbJKVuDFJ0WJ2IKD2lBah749 j3nGHjXGjBOse63k8WD0nGWHe1WDOEY3iq46tWvA= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v4 08/20] libcamera: converter: Add function to query crop bounds Date: Mon, 16 Dec 2024 16:40:48 +0100 Message-ID: <20241216154124.203650-9-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241216154124.203650-1-stefan.klug@ideasonboard.com> References: <20241216154124.203650-1-stefan.klug@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 inputCropBounds_ member of the V4L2M2MConverter::Stream class is only initialized after a V4L2M2MConverter::configure() call, when the streams are initialized. However, the converter has crop limits that do not depend on the configured Streams, and which are currently not accessible from the class interface. Add a new inputCropBounds() function to the V4L2M2MConverter class that allows to retrieve the converter crop limits before any stream is configured. This is particularly useful for pipelines to initialize controls and properties and to implement validation before the Camera gets configured. Signed-off-by: Stefan Klug Reviewed-by: Paul Elder Reviewed-by: Jacopo Mondi --- Changes in v4: - Split off from libcamera: converter_v4l2_m2m: Improve crop bounds support - Added separate inputCropBounds() function to the dewarper class Fuxup inputCrop() --- include/libcamera/internal/converter.h | 1 + .../internal/converter/converter_v4l2_m2m.h | 2 ++ src/libcamera/converter.cpp | 13 +++++++++++++ src/libcamera/converter/converter_v4l2_m2m.cpp | 18 ++++++++++++------ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h index ffbb6f345cd5..04187a2a96e8 100644 --- a/include/libcamera/internal/converter.h +++ b/include/libcamera/internal/converter.h @@ -66,6 +66,7 @@ public: const std::map &outputs) = 0; virtual int setInputCrop(const Stream *stream, Rectangle *rect) = 0; + virtual std::pair inputCropBounds() = 0; virtual std::pair inputCropBounds(const Stream *stream) = 0; Signal inputBufferReady; diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h index 9b8e43ff0b91..402a803959b9 100644 --- a/include/libcamera/internal/converter/converter_v4l2_m2m.h +++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h @@ -60,6 +60,7 @@ public: const std::map &outputs) override; int setInputCrop(const Stream *stream, Rectangle *rect) override; + std::pair inputCropBounds() override { return inputCropBounds_; } std::pair inputCropBounds(const Stream *stream) override; private: @@ -106,6 +107,7 @@ private: std::map> streams_; std::map queue_; + std::pair inputCropBounds_; }; } /* namespace libcamera */ diff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp index 3a3f84344c5e..73c02fdcf4bb 100644 --- a/src/libcamera/converter.cpp +++ b/src/libcamera/converter.cpp @@ -185,6 +185,16 @@ Converter::~Converter() /** * \fn Converter::inputCropBounds() + * \brief Retrieve the crop bounds of the converter + * + * Retrieve the minimum and maximum crop bounds of the converter. This can be + * used to query the crop bounds before configuring a stream. + * + * \return A pair containing the minimum and maximum crop bound in that order + */ + +/** + * \fn Converter::inputCropBounds(const Stream *stream) * \brief Retrieve the crop bounds for \a stream * \param[in] stream The output stream * @@ -195,6 +205,9 @@ Converter::~Converter() * this function should be called after the \a stream has been configured using * configure(). * + * When called with an unconfigured \a stream, this function returns a pair of + * null rectangles. + * * \return A pair containing the minimum and maximum crop bound in that order */ diff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp index 8c341fe199f6..342aa32dab52 100644 --- a/src/libcamera/converter/converter_v4l2_m2m.cpp +++ b/src/libcamera/converter/converter_v4l2_m2m.cpp @@ -273,10 +273,9 @@ V4L2M2MConverter::V4L2M2MConverter(MediaDevice *media) return; } - Rectangle minCrop; - Rectangle maxCrop; - ret = getCropBounds(m2m_->output(), minCrop, maxCrop); - if (!ret && minCrop != maxCrop) { + ret = getCropBounds(m2m_->output(), inputCropBounds_.first, + inputCropBounds_.second); + if (!ret && inputCropBounds_.first != inputCropBounds_.second) { features_ |= Feature::InputCrop; LOG(Converter, Info) @@ -469,14 +468,21 @@ int V4L2M2MConverter::setInputCrop(const Stream *stream, Rectangle *rect) } /** - * \copydoc libcamera::Converter::inputCropBounds + * \fn libcamera::V4L2M2MConverter::inputCropBounds() + * \copydoc libcamera::Converter::inputCropBounds() + */ + +/** + * \copydoc libcamera::Converter::inputCropBounds(const Stream *stream) */ std::pair V4L2M2MConverter::inputCropBounds(const Stream *stream) { auto iter = streams_.find(stream); - if (iter == streams_.end()) + if (iter == streams_.end()) { + LOG(Converter, Error) << "Invalid output stream"; return {}; + } return iter->second->inputCropBounds(); }