{"id":22354,"url":"https://patchwork.libcamera.org/api/patches/22354/?format=json","web_url":"https://patchwork.libcamera.org/patch/22354/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20241216154124.203650-9-stefan.klug@ideasonboard.com>","date":"2024-12-16T15:40:48","name":"[v4,08/20] libcamera: converter: Add function to query crop bounds","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"f1991c5022333e3a24b3a434ba21692ad8329dad","submitter":{"id":184,"url":"https://patchwork.libcamera.org/api/people/184/?format=json","name":"Stefan Klug","email":"stefan.klug@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/22354/mbox/","series":[{"id":4896,"url":"https://patchwork.libcamera.org/api/series/4896/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=4896","date":"2024-12-16T15:40:40","name":"rkisp1: Fix aspect ratio and ScalerCrop","version":4,"mbox":"https://patchwork.libcamera.org/series/4896/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/22354/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/22354/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 7F619C32F6\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 16 Dec 2024 15:42:13 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1E32067F89;\n\tMon, 16 Dec 2024 16:42:13 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B809367F7C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Dec 2024 16:42:08 +0100 (CET)","from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:bfdf:3a3c:e45:66e3])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2B8D082A;\n\tMon, 16 Dec 2024 16:41:32 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PZR4uHot\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1734363692;\n\tbh=A2hoAAODKjXuMBejnr8+ldG7/o0OpNQqa305QPLDEik=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=PZR4uHotGOFMjpg6BHN5zbAhKOgb2OeB3XkthZlRc42otnLhTDPFKLEdrYv1cBVYt\n\tGI0jvEE/9FPr8Zp1ynO1ZINYaYHACJzGH9aaoDd6FKLbJKVuDFJ0WJ2IKD2lBah749\n\tj3nGHjXGjBOse63k8WD0nGWHe1WDOEY3iq46tWvA=","From":"Stefan Klug <stefan.klug@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"Stefan Klug <stefan.klug@ideasonboard.com>","Subject":"[PATCH v4 08/20] libcamera: converter: Add function to query crop\n\tbounds","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","Content-Transfer-Encoding":"8bit","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"The inputCropBounds_ member of the V4L2M2MConverter::Stream class is\nonly initialized after a V4L2M2MConverter::configure() call, when the\nstreams are initialized.\n\nHowever, the converter has crop limits that do not depend on the\nconfigured Streams, and which are currently not accessible from the\nclass interface.\n\nAdd a new inputCropBounds() function to the V4L2M2MConverter class\nthat allows to retrieve the converter crop limits before any stream\nis configured.\n\nThis is particularly useful for pipelines to initialize controls and\nproperties and to implement validation before the Camera gets\nconfigured.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n\n---\n\nChanges in v4:\n- Split off from libcamera: converter_v4l2_m2m: Improve crop bounds\n  support\n- Added separate inputCropBounds() function to the dewarper class\n\nFuxup inputCrop()\n---\n include/libcamera/internal/converter.h         |  1 +\n .../internal/converter/converter_v4l2_m2m.h    |  2 ++\n src/libcamera/converter.cpp                    | 13 +++++++++++++\n src/libcamera/converter/converter_v4l2_m2m.cpp | 18 ++++++++++++------\n 4 files changed, 28 insertions(+), 6 deletions(-)","diff":"diff --git a/include/libcamera/internal/converter.h b/include/libcamera/internal/converter.h\nindex ffbb6f345cd5..04187a2a96e8 100644\n--- a/include/libcamera/internal/converter.h\n+++ b/include/libcamera/internal/converter.h\n@@ -66,6 +66,7 @@ public:\n \t\t\t\t const std::map<const Stream *, FrameBuffer *> &outputs) = 0;\n \n \tvirtual int setInputCrop(const Stream *stream, Rectangle *rect) = 0;\n+\tvirtual std::pair<Rectangle, Rectangle> inputCropBounds() = 0;\n \tvirtual std::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) = 0;\n \n \tSignal<FrameBuffer *> inputBufferReady;\ndiff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h\nindex 9b8e43ff0b91..402a803959b9 100644\n--- a/include/libcamera/internal/converter/converter_v4l2_m2m.h\n+++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h\n@@ -60,6 +60,7 @@ public:\n \t\t\t const std::map<const Stream *, FrameBuffer *> &outputs) override;\n \n \tint setInputCrop(const Stream *stream, Rectangle *rect) override;\n+\tstd::pair<Rectangle, Rectangle> inputCropBounds() override { return inputCropBounds_; }\n \tstd::pair<Rectangle, Rectangle> inputCropBounds(const Stream *stream) override;\n \n private:\n@@ -106,6 +107,7 @@ private:\n \n \tstd::map<const Stream *, std::unique_ptr<V4L2M2MStream>> streams_;\n \tstd::map<FrameBuffer *, unsigned int> queue_;\n+\tstd::pair<Rectangle, Rectangle> inputCropBounds_;\n };\n \n } /* namespace libcamera */\ndiff --git a/src/libcamera/converter.cpp b/src/libcamera/converter.cpp\nindex 3a3f84344c5e..73c02fdcf4bb 100644\n--- a/src/libcamera/converter.cpp\n+++ b/src/libcamera/converter.cpp\n@@ -185,6 +185,16 @@ Converter::~Converter()\n \n /**\n  * \\fn Converter::inputCropBounds()\n+ * \\brief Retrieve the crop bounds of the converter\n+ *\n+ * Retrieve the minimum and maximum crop bounds of the converter. This can be\n+ * used to query the crop bounds before configuring a stream.\n+ *\n+ * \\return A pair containing the minimum and maximum crop bound in that order\n+ */\n+\n+/**\n+ * \\fn Converter::inputCropBounds(const Stream *stream)\n  * \\brief Retrieve the crop bounds for \\a stream\n  * \\param[in] stream The output stream\n  *\n@@ -195,6 +205,9 @@ Converter::~Converter()\n  * this function should be called after the \\a stream has been configured using\n  * configure().\n  *\n+ * When called with an unconfigured \\a stream, this function returns a pair of\n+ * null rectangles.\n+ *\n  * \\return A pair containing the minimum and maximum crop bound in that order\n  */\n \ndiff --git a/src/libcamera/converter/converter_v4l2_m2m.cpp b/src/libcamera/converter/converter_v4l2_m2m.cpp\nindex 8c341fe199f6..342aa32dab52 100644\n--- a/src/libcamera/converter/converter_v4l2_m2m.cpp\n+++ b/src/libcamera/converter/converter_v4l2_m2m.cpp\n@@ -273,10 +273,9 @@ V4L2M2MConverter::V4L2M2MConverter(MediaDevice *media)\n \t\treturn;\n \t}\n \n-\tRectangle minCrop;\n-\tRectangle maxCrop;\n-\tret = getCropBounds(m2m_->output(), minCrop, maxCrop);\n-\tif (!ret && minCrop != maxCrop) {\n+\tret = getCropBounds(m2m_->output(), inputCropBounds_.first,\n+\t\t\t    inputCropBounds_.second);\n+\tif (!ret && inputCropBounds_.first != inputCropBounds_.second) {\n \t\tfeatures_ |= Feature::InputCrop;\n \n \t\tLOG(Converter, Info)\n@@ -469,14 +468,21 @@ int V4L2M2MConverter::setInputCrop(const Stream *stream, Rectangle *rect)\n }\n \n /**\n- * \\copydoc libcamera::Converter::inputCropBounds\n+ * \\fn libcamera::V4L2M2MConverter::inputCropBounds()\n+ * \\copydoc libcamera::Converter::inputCropBounds()\n+ */\n+\n+/**\n+ * \\copydoc libcamera::Converter::inputCropBounds(const Stream *stream)\n  */\n std::pair<Rectangle, Rectangle>\n V4L2M2MConverter::inputCropBounds(const Stream *stream)\n {\n \tauto iter = streams_.find(stream);\n-\tif (iter == streams_.end())\n+\tif (iter == streams_.end()) {\n+\t\tLOG(Converter, Error) << \"Invalid output stream\";\n \t\treturn {};\n+\t}\n \n \treturn iter->second->inputCropBounds();\n }\n","prefixes":["v4","08/20"]}