Patch Detail
Show a patch.
GET /api/patches/22198/?format=api
{ "id": 22198, "url": "https://patchwork.libcamera.org/api/patches/22198/?format=api", "web_url": "https://patchwork.libcamera.org/patch/22198/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20241206101344.767170-7-stefan.klug@ideasonboard.com>", "date": "2024-12-06T10:13:28", "name": "[v3,06/17] libcamera: converter_v4l2_m2m: Improve crop bounds support", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "9e793d8e058839fb22ef4b1006a063be5534e480", "submitter": { "id": 184, "url": "https://patchwork.libcamera.org/api/people/184/?format=api", "name": "Stefan Klug", "email": "stefan.klug@ideasonboard.com" }, "delegate": { "id": 17, "url": "https://patchwork.libcamera.org/api/users/17/?format=api", "username": "epaul", "first_name": "Paul", "last_name": "Elder", "email": "paul.elder@ideasonboard.com" }, "mbox": "https://patchwork.libcamera.org/patch/22198/mbox/", "series": [ { "id": 4854, "url": "https://patchwork.libcamera.org/api/series/4854/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4854", "date": "2024-12-06T10:13:22", "name": "rkisp1: Fix aspect ratio and ScalerCrop", "version": 3, "mbox": "https://patchwork.libcamera.org/series/4854/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/22198/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/22198/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 275F3BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 6 Dec 2024 10:14:09 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C370566148;\n\tFri, 6 Dec 2024 11:14:08 +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 944126613D\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 6 Dec 2024 11:14:05 +0100 (CET)", "from ideasonboard.com (unknown\n\t[IPv6:2a00:6020:448c:6c00:3543:aebe:e043:ef86])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 3BD469FC;\n\tFri, 6 Dec 2024 11:13:36 +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=\"qlo48CKQ\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1733480016;\n\tbh=V/J4wJ4pkpHSj6jhg+sH3h5VyeMjLU9+u+us9Tt+Ack=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=qlo48CKQl1GbIr10HQs27hU6b64vP7/8VGrKltwi7tSrjlJzJEHA+cPmycUMr0Swj\n\trx1Q4LvXQimsnNo/wx/emYlJRHJhDLAdg8jSBPaKqzvONOslRn0UiKDPDlGaQhvQCA\n\t+aiF4DOjkat5TuiQO/hA0U3gIF2Gzh9yvgGZrrVM=", "From": "Stefan Klug <stefan.klug@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Stefan Klug <stefan.klug@ideasonboard.com>", "Subject": "[PATCH v3 06/17] libcamera: converter_v4l2_m2m: Improve crop bounds\n\tsupport", "Date": "Fri, 6 Dec 2024 11:13:28 +0100", "Message-ID": "<20241206101344.767170-7-stefan.klug@ideasonboard.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20241206101344.767170-1-stefan.klug@ideasonboard.com>", "References": "<20241206101344.767170-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": "When a converter (dw100 on imx8mp in this case) is used in a pipeline,\nthe ScalerCrop control get's created at createCamera() time. As this is\nbefore configure(), no streams were configured on the converter and the\nstream specific crop bounds are not known. Extend the converter class to\nreport the default crop bounds in case the provided stream is not found.\n\nSigned-off-by: Stefan Klug <stefan.klug@ideasonboard.com>\n---\n .../internal/converter/converter_v4l2_m2m.h | 1 +\n src/libcamera/converter.cpp | 3 +\n .../converter/converter_v4l2_m2m.cpp | 113 +++++++++---------\n 3 files changed, 59 insertions(+), 58 deletions(-)", "diff": "diff --git a/include/libcamera/internal/converter/converter_v4l2_m2m.h b/include/libcamera/internal/converter/converter_v4l2_m2m.h\nindex 0bc0d053e2c4..a5286166f574 100644\n--- a/include/libcamera/internal/converter/converter_v4l2_m2m.h\n+++ b/include/libcamera/internal/converter/converter_v4l2_m2m.h\n@@ -105,6 +105,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..aa16970cd446 100644\n--- a/src/libcamera/converter.cpp\n+++ b/src/libcamera/converter.cpp\n@@ -195,6 +195,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 invalid \\a stream, the function returns the default crop\n+ * bounds of the converter.\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 d63ef2f8028f..bd7e5cce600d 100644\n--- a/src/libcamera/converter/converter_v4l2_m2m.cpp\n+++ b/src/libcamera/converter/converter_v4l2_m2m.cpp\n@@ -30,6 +30,52 @@ namespace libcamera {\n \n LOG_DECLARE_CATEGORY(Converter)\n \n+namespace {\n+\n+int getCropBounds(V4L2VideoDevice *device, Rectangle &minCrop,\n+\t\t Rectangle &maxCrop)\n+{\n+\tRectangle minC;\n+\tRectangle maxC;\n+\n+\t/* Find crop bounds */\n+\tminC.width = 1;\n+\tminC.height = 1;\n+\tmaxC.width = UINT_MAX;\n+\tmaxC.height = UINT_MAX;\n+\n+\tint ret = device->setSelection(V4L2_SEL_TGT_CROP, &minC);\n+\tif (ret) {\n+\t\tLOG(Converter, Error)\n+\t\t\t<< \"Could not query minimum selection crop: \"\n+\t\t\t<< strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\tret = device->getSelection(V4L2_SEL_TGT_CROP_BOUNDS, &maxC);\n+\tif (ret) {\n+\t\tLOG(Converter, Error)\n+\t\t\t<< \"Could not query maximum selection crop: \"\n+\t\t\t<< strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\t/* Reset the crop to its maximum */\n+\tret = device->setSelection(V4L2_SEL_TGT_CROP, &maxC);\n+\tif (ret) {\n+\t\tLOG(Converter, Error)\n+\t\t\t<< \"Could not reset selection crop: \"\n+\t\t\t<< strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\tminCrop = minC;\n+\tmaxCrop = maxC;\n+\treturn 0;\n+}\n+\n+} /* namespace */\n+\n /* -----------------------------------------------------------------------------\n * V4L2M2MConverter::V4L2M2MStream\n */\n@@ -98,41 +144,10 @@ int V4L2M2MConverter::V4L2M2MStream::configure(const StreamConfiguration &inputC\n \toutputBufferCount_ = outputCfg.bufferCount;\n \n \tif (converter_->features() & Feature::InputCrop) {\n-\t\tRectangle minCrop;\n-\t\tRectangle maxCrop;\n-\n-\t\t/* Find crop bounds */\n-\t\tminCrop.width = 1;\n-\t\tminCrop.height = 1;\n-\t\tmaxCrop.width = UINT_MAX;\n-\t\tmaxCrop.height = UINT_MAX;\n-\n-\t\tret = setInputSelection(V4L2_SEL_TGT_CROP, &minCrop);\n-\t\tif (ret) {\n-\t\t\tLOG(Converter, Error)\n-\t\t\t\t<< \"Could not query minimum selection crop: \"\n-\t\t\t\t<< strerror(-ret);\n-\t\t\treturn ret;\n-\t\t}\n-\n-\t\tret = getInputSelection(V4L2_SEL_TGT_CROP_BOUNDS, &maxCrop);\n-\t\tif (ret) {\n-\t\t\tLOG(Converter, Error)\n-\t\t\t\t<< \"Could not query maximum selection crop: \"\n-\t\t\t\t<< strerror(-ret);\n-\t\t\treturn ret;\n-\t\t}\n-\n-\t\t/* Reset the crop to its maximum */\n-\t\tret = setInputSelection(V4L2_SEL_TGT_CROP, &maxCrop);\n-\t\tif (ret) {\n-\t\t\tLOG(Converter, Error)\n-\t\t\t\t<< \"Could not reset selection crop: \"\n-\t\t\t\t<< strerror(-ret);\n+\t\tret = getCropBounds(m2m_->output(), inputCropBounds_.first,\n+\t\t\t\t inputCropBounds_.second);\n+\t\tif (ret)\n \t\t\treturn ret;\n-\t\t}\n-\n-\t\tinputCropBounds_ = { minCrop, maxCrop };\n \t}\n \n \treturn 0;\n@@ -258,27 +273,9 @@ V4L2M2MConverter::V4L2M2MConverter(MediaDevice *media)\n \t\treturn;\n \t}\n \n-\t/* Discover Feature::InputCrop */\n-\tRectangle maxCrop;\n-\tmaxCrop.width = UINT_MAX;\n-\tmaxCrop.height = UINT_MAX;\n-\n-\tret = m2m_->output()->setSelection(V4L2_SEL_TGT_CROP, &maxCrop);\n-\tif (ret)\n-\t\treturn;\n-\n-\t/*\n-\t * Rectangles for cropping targets are defined even if the device\n-\t * does not support cropping. Their sizes and positions will be\n-\t * fixed in such cases.\n-\t *\n-\t * Set and inspect a crop equivalent to half of the maximum crop\n-\t * returned earlier. Use this to determine whether the crop on\n-\t * input is really supported.\n-\t */\n-\tRectangle halfCrop(maxCrop.size() / 2);\n-\tret = m2m_->output()->setSelection(V4L2_SEL_TGT_CROP, &halfCrop);\n-\tif (!ret && halfCrop != 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@@ -477,10 +474,10 @@ std::pair<Rectangle, Rectangle>\n V4L2M2MConverter::inputCropBounds(const Stream *stream)\n {\n \tauto iter = streams_.find(stream);\n-\tif (iter == streams_.end())\n-\t\treturn {};\n+\tif (iter != streams_.end())\n+\t\treturn iter->second->inputCropBounds();\n \n-\treturn iter->second->inputCropBounds();\n+\treturn inputCropBounds_;\n }\n \n /**\n", "prefixes": [ "v3", "06/17" ] }