Patch Detail
Show a patch.
GET /api/1.1/patches/20654/?format=api
{ "id": 20654, "url": "https://patchwork.libcamera.org/api/1.1/patches/20654/?format=api", "web_url": "https://patchwork.libcamera.org/patch/20654/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/1.1/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": "<20240712052920.33396-7-umang.jain@ideasonboard.com>", "date": "2024-07-12T05:29:20", "name": "[RFC,6/6] libcamera: converter_dw100: Load and apply dewarp vertex maps", "commit_ref": null, "pull_url": null, "state": "not-applicable", "archived": false, "hash": "bc8d73b627e77ded2ecd3105a009d384764ca5aa", "submitter": { "id": 86, "url": "https://patchwork.libcamera.org/api/1.1/people/86/?format=api", "name": "Umang Jain", "email": "umang.jain@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/20654/mbox/", "series": [ { "id": 4451, "url": "https://patchwork.libcamera.org/api/1.1/series/4451/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=4451", "date": "2024-07-12T05:29:14", "name": "converter_dw100: Add vertex map support", "version": 1, "mbox": "https://patchwork.libcamera.org/series/4451/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/20654/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/20654/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 F2512BDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 12 Jul 2024 05:29:51 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 7050D63374;\n\tFri, 12 Jul 2024 07:29:51 +0200 (CEST)", "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D921263373\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 12 Jul 2024 07:29:40 +0200 (CEST)", "from localhost.localdomain (unknown\n\t[IPv6:2405:201:2015:f873:55f8:639e:8e9f:12ec])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C120DCC8;\n\tFri, 12 Jul 2024 07:29:05 +0200 (CEST)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"PMl6w/gV\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1720762146;\n\tbh=ie7HwfJuw/xdXZQNuu2T2/iCexCnVjC/rUn72ssmos8=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=PMl6w/gVyS5en74MjT8ZaNLfIPybK5e+KF9MiDuXfVHwGVW51JaoqdMi3LBvzhoWf\n\t2uTWNWh1NjGxEUyDBdLLhnWLpGP8y5VwT1TxbvKVAfXY+LaIWx+4PzvqjGqIYdaaam\n\tpuxgY33cHD43WbyfZ5/77TvdXn6Nl4lXSopHgz6Q=", "From": "Umang Jain <umang.jain@ideasonboard.com>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "Xavier Roumegue <xavier.roumegue@oss.nxp.com>,\n\tUmang Jain <umang.jain@ideasonboard.com>", "Subject": "[RFC PATCH 6/6] libcamera: converter_dw100: Load and apply dewarp\n\tvertex maps", "Date": "Fri, 12 Jul 2024 10:59:20 +0530", "Message-ID": "<20240712052920.33396-7-umang.jain@ideasonboard.com>", "X-Mailer": "git-send-email 2.45.0", "In-Reply-To": "<20240712052920.33396-1-umang.jain@ideasonboard.com>", "References": "<20240712052920.33396-1-umang.jain@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": "Load the dewarp vertex maps for different configurations using the\nLIBCAMERA_DEWARP_CONFIG_FILE environment variable.\n\nIn addition, provide a applyMappings(stream) API for converter_dw100, in\norder to apply mappings for the given stream. Plumb it into rkisp1\npipeline handler, if the dewarper is being used.\n\n\\todo The parsing of dewarp configuration file is yet to be determined.\nI've used the same parsing logic as made in previous attempts:\nhttps://patchwork.libcamera.org/patch/17348/\n\nSigned-off-by: Umang Jain <umang.jain@ideasonboard.com>\n---\n .../internal/converter/converter_dw100.h | 5 +\n src/libcamera/converter/converter_dw100.cpp | 127 ++++++++++++++++++\n src/libcamera/pipeline/rkisp1/rkisp1.cpp | 4 +\n 3 files changed, 136 insertions(+)", "diff": "diff --git a/include/libcamera/internal/converter/converter_dw100.h b/include/libcamera/internal/converter/converter_dw100.h\nindex dc41f365..a3062e84 100644\n--- a/include/libcamera/internal/converter/converter_dw100.h\n+++ b/include/libcamera/internal/converter/converter_dw100.h\n@@ -19,6 +19,11 @@ class ConverterDW100 : public V4L2M2MConverter\n {\n public:\n \tConverterDW100(std::shared_ptr<MediaDevice> media);\n+\n+\tint applyMappings(const Stream *stream);\n+\n+private:\n+\tint loadDewarpMaps();\n };\n \n } /* namespace libcamera */\ndiff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp\nindex 3061fc71..1a641779 100644\n--- a/src/libcamera/converter/converter_dw100.cpp\n+++ b/src/libcamera/converter/converter_dw100.cpp\n@@ -7,12 +7,17 @@\n \n #include \"libcamera/internal/converter/converter_dw100.h\"\n \n+#include <linux/dw100.h>\n+\n+#include <libcamera/base/file.h>\n #include <libcamera/base/log.h>\n \n+#include <libcamera/stream.h>\n #include <libcamera/geometry.h>\n \n #include \"libcamera/internal/media_device.h\"\n #include \"libcamera/internal/v4l2_videodevice.h\"\n+#include \"libcamera/internal/yaml_parser.h\"\n \n namespace libcamera {\n \n@@ -32,6 +37,128 @@ LOG_DECLARE_CATEGORY(Converter)\n ConverterDW100::ConverterDW100(std::shared_ptr<MediaDevice> media)\n \t: V4L2M2MConverter(media.get(), Feature::Crop)\n {\n+\tloadDewarpMaps();\n+}\n+\n+int ConverterDW100::loadDewarpMaps()\n+{\n+\tint ret;\n+\n+\tchar const *configFromEnv = utils::secure_getenv(\"LIBCAMERA_DEWARP_CONFIG_FILE\");\n+\tif (!configFromEnv || *configFromEnv == '\\0')\n+\t\treturn 0;\n+\n+\tLOG(Converter, Info) << \"Parsing dewarp configuration file \" << configFromEnv;\n+\n+\tstd::string filename = std::string(configFromEnv);\n+\tFile file(filename);\n+\n+\tif (!file.open(File::OpenModeFlag::ReadOnly)) {\n+\t\tret = file.error();\n+\t\tLOG(Converter, Error) << \"Failed to open configuration file \"\n+\t\t\t\t << filename << \": \" << strerror(-ret);\n+\t\treturn ret;\n+\t}\n+\n+\tstd::unique_ptr<libcamera::YamlObject> data = YamlParser::parse(file);\n+\tif (!data)\n+\t\treturn -EINVAL;\n+\n+\tif (!data->contains(\"mappings\")) {\n+\t\tLOG(Converter, Error) << \"Vertex mapping key missing\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tconst YamlObject &mappings = (*data)[\"mappings\"];\n+\tif (!mappings.isList() || mappings.size() == 0) {\n+\t\tLOG(Converter, Error) << \"Invalid mappings entry\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tLOG(Converter, Debug) << \"Parsing \" << mappings.size() << \" mappings\";\n+\tmappings_.clear();\n+\tmappings_.reserve(mappings.size());\n+\n+\tfor (std::size_t i = 0; i < mappings.size(); i++) {\n+\t\tconst YamlObject &mapping = mappings[i];\n+\t\tif (!mapping.isDictionary()) {\n+\t\t\tLOG(Converter, Error) << \"Mapping is not a dictionary\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!mapping.contains(\"input-resolution\")) {\n+\t\t\tLOG(Converter, Error) << \"Input resolution missing\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!mapping.contains(\"output-resolution\")) {\n+\t\t\tLOG(Converter, Error) << \"Output resolution missing\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!mapping.contains(\"mapping\")) {\n+\t\t\tLOG(Converter, Error) << \"Mapping table missing\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tconst YamlObject &input_res = mapping[\"input-resolution\"];\n+\t\tif (!input_res.isList() || input_res.size() != 2) {\n+\t\t\tLOG(Converter, Error) << \"Incorrect input resolution\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tconst YamlObject &output_res = mapping[\"output-resolution\"];\n+\t\tif (!output_res.isList() || output_res.size() != 2) {\n+\t\t\tLOG(Converter, Error) << \"Incorrect output resolution\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tconst YamlObject &map = mapping[\"mapping\"];\n+\t\tif (!map.isList() || map.size() == 0) {\n+\t\t\tLOG(Converter, Error) << \"Incorrect mapping entries\";\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tSize input(input_res[0].get<uint32_t>(0), input_res[1].get<uint32_t>(0));\n+\t\tSize output(output_res[0].get<uint32_t>(0), output_res[1].get<uint32_t>(0));\n+\t\tconst auto &mapVector = map.getList<uint32_t>().value_or(std::vector<uint32_t>{});\n+\n+\t\tLOG(Converter, Debug)\n+\t\t\t<< \"Input/Output mapping resolution \" << input << \" -> \" << output;\n+\n+\t\tmappings_.emplace_back(Mapping(input, output, mapVector));\n+\t}\n+\n+\treturn mappings.size();\n+}\n+\n+/*\n+ * \\brief Apply\n+ * \\todo this is just a wrapper, trying to test waters\n+ * \\param[in] media The media device implementing the converter\n+ */\n+int ConverterDW100::applyMappings(const Stream *stream)\n+{\n+\tconst StreamConfiguration &config = stream->configuration();\n+\tControlList ctrls;\n+\tint ret = 0;\n+\n+\tfor (const auto &map : mappings_) {\n+\t\t/* Currently DW100's input and output configuration are same. */\n+\t\tif (map.inputSize() == config.size &&\n+\t\t map.outputSize() == config.size) {\n+\t\t\tauto value = Span<const int32_t>(reinterpret_cast<const int32_t *>(map.mapping()), map.size());\n+\n+\t\t\tControlValue c(value);\n+\t\t\tctrls.set(V4L2_CID_DW100_DEWARPING_16x16_VERTEX_MAP, c);\n+\t\t\tret = applyControls(stream, ctrls);\n+\n+\t\t\tLOG(Converter, Debug) << \"Dewarp mapping applied for \" << config.toString();\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+ return ret;\n }\n \n } /* namespace libcamera */\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 881e10e1..f102b364 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -1019,6 +1019,10 @@ int PipelineHandlerRkISP1::start(Camera *camera, [[maybe_unused]] const ControlL\n \t\t\t\tLOG(RkISP1, Error) << \"Failed to start dewarper\";\n \t\t\t\treturn ret;\n \t\t\t}\n+\n+\t\t\tret = dewarper_->applyMappings(&data->mainPathStream_);\n+\t\t\tif (ret)\n+\t\t\t\tLOG(RkISP1, Warning) << \"Dewarper mapping couldn't be applied\";\n \t\t}\n \t}\n \n", "prefixes": [ "RFC", "6/6" ] }