[{"id":30471,"web_url":"https://patchwork.libcamera.org/comment/30471/","msgid":"<6ztspkss3a2tuw4tzulizjjdkl43bfmyscgbzw2r2nraahnfka@ttiegljjg2ss>","date":"2024-07-24T13:46:48","subject":"Re: [RFC PATCH 6/6] libcamera: converter_dw100: Load and apply\n\tdewarp vertex maps","submitter":{"id":143,"url":"https://patchwork.libcamera.org/api/people/143/","name":"Jacopo Mondi","email":"jacopo.mondi@ideasonboard.com"},"content":"Hi Umang\n\nOn Fri, Jul 12, 2024 at 10:59:20AM GMT, Umang Jain wrote:\n> Load the dewarp vertex maps for different configurations using the\n> LIBCAMERA_DEWARP_CONFIG_FILE environment variable.\n\nThe env variable needs to be documented\n\n>\n> In addition, provide a applyMappings(stream) API for converter_dw100, in\n> order to apply mappings for the given stream. Plumb it into rkisp1\n> pipeline handler, if the dewarper is being used.\n>\n> \\todo The parsing of dewarp configuration file is yet to be determined.\n\nWhat are you unsure about here ? The configuration file format ?\n\n> I've used the same parsing logic as made in previous attempts:\n> https://patchwork.libcamera.org/patch/17348/\n>\n> Signed-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(+)\n>\n> diff --git a/include/libcamera/internal/converter/converter_dw100.h b/include/libcamera/internal/converter/converter_dw100.h\n> index 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\nDoesn't this 'override' the one declared in the V4L2M2MConverter base\nclass ?\n\n> +\n> +private:\n> +\tint loadDewarpMaps();\n>  };\n>\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp\n> index 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\nReturn value is useless if only called at construction time\n\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\nIs the dewarper usable without a config file ?\n\nShould we have an example of a mapping file somewhere or it is not\nneeded ?\n\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\nDoes\n        for (const YamlObject &mapping : mappings)\n\nwork ?\n\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 */\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 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> --\n> 2.45.0\n>","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 BA9E9BDB1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 24 Jul 2024 13:46:55 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C611C6336F;\n\tWed, 24 Jul 2024 15:46:54 +0200 (CEST)","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 B147A619A0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 24 Jul 2024 15:46:52 +0200 (CEST)","from ideasonboard.com (unknown [91.80.74.127])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 60CF511D1;\n\tWed, 24 Jul 2024 15:46:09 +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=\"g1xi/zvf\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1721828769;\n\tbh=jBz7qVlb9WOXidh5+obLxO0oZgoTdNUmRBRqIFk3kcs=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=g1xi/zvfYUn5YUzcLtZReMIQX+OPNvF1boVwCqpUKzp0OlbMYuw/de9xNZ0EgjJ7y\n\t5pPNwyb1z4MePskfwr/6+IzI/UMlN6U25wWCJ3KXTNyhjyx4e/o4AUaBMvhf4LaN9W\n\tf7e+E+1BO4qiucdF0L4uoXhfJJiQOH+Hk+KN8DHE=","Date":"Wed, 24 Jul 2024 15:46:48 +0200","From":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","To":"Umang Jain <umang.jain@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org, \n\tXavier Roumegue <xavier.roumegue@oss.nxp.com>","Subject":"Re: [RFC PATCH 6/6] libcamera: converter_dw100: Load and apply\n\tdewarp vertex maps","Message-ID":"<6ztspkss3a2tuw4tzulizjjdkl43bfmyscgbzw2r2nraahnfka@ttiegljjg2ss>","References":"<20240712052920.33396-1-umang.jain@ideasonboard.com>\n\t<20240712052920.33396-7-umang.jain@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20240712052920.33396-7-umang.jain@ideasonboard.com>","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>"}},{"id":30558,"web_url":"https://patchwork.libcamera.org/comment/30558/","msgid":"<20240802230110.GG3319@pendragon.ideasonboard.com>","date":"2024-08-02T23:01:10","subject":"Re: [RFC PATCH 6/6] libcamera: converter_dw100: Load and apply\n\tdewarp vertex maps","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Wed, Jul 24, 2024 at 03:46:48PM +0200, Jacopo Mondi wrote:\n> On Fri, Jul 12, 2024 at 10:59:20AM GMT, Umang Jain wrote:\n> > Load the dewarp vertex maps for different configurations using the\n> > LIBCAMERA_DEWARP_CONFIG_FILE environment variable.\n> \n> The env variable needs to be documented\n\nAnd this should not come from an environment variable :-)\n\n> > In addition, provide a applyMappings(stream) API for converter_dw100, in\n> > order to apply mappings for the given stream. Plumb it into rkisp1\n> > pipeline handler, if the dewarper is being used.\n> >\n> > \\todo The parsing of dewarp configuration file is yet to be determined.\n> \n> What are you unsure about here ? The configuration file format ?\n> \n> > I've used the same parsing logic as made in previous attempts:\n> > https://patchwork.libcamera.org/patch/17348/\n> >\n> > Signed-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(+)\n> >\n> > diff --git a/include/libcamera/internal/converter/converter_dw100.h b/include/libcamera/internal/converter/converter_dw100.h\n> > index 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> Doesn't this 'override' the one declared in the V4L2M2MConverter base\n> class ?\n\nNo, because the function in the base class isn't volatile.\n\n> > +\n> > +private:\n> > +\tint loadDewarpMaps();\n> >  };\n> >\n> >  } /* namespace libcamera */\n> > diff --git a/src/libcamera/converter/converter_dw100.cpp b/src/libcamera/converter/converter_dw100.cpp\n> > index 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> Return value is useless if only called at construction time\n> \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> Is the dewarper usable without a config file ?\n\nUsable, yes, but without dewarping. It can still be used as a scaler.\n\n> Should we have an example of a mapping file somewhere or it is not\n> needed ?\n> \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> \n> Does\n>         for (const YamlObject &mapping : mappings)\n> \n> work ?\n> \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\nIs that the resolution before or after the input crop is applied ?\n\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\nThe YAML parser supports Size natively.\n\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\nThis significantly reduces the usability of the dewarper. I'd like to\nsee a proposal to do better.\n\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 */\n> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> > index 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> >","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 3B9EEC323E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri,  2 Aug 2024 23:01:35 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1C9CA63381;\n\tSat,  3 Aug 2024 01:01:34 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 14B956195B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  3 Aug 2024 01:01:32 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi\n\t[81.175.209.231])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 330023C7;\n\tSat,  3 Aug 2024 01:00:42 +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=\"dMGW9F7z\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1722639642;\n\tbh=URXEHYV3Kjpm+CM1wd5od2OoHZ9P7dViX/ufd/Rr08Y=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=dMGW9F7zxqpd9nfjkkQCNsQqJ8BpHGs6W4AqcW517WO4zx12dwi20Noru3RLBuim4\n\twQVt6ihmHz9lRPc7dd0X2M8e13EU91F8Q8JfYwUO5j1AgqEO7hC6XDai0UBOjp6Jwp\n\tj+QHrgOiF6vjicgTCDCWrJ07RffQ4JhismbsHMA0=","Date":"Sat, 3 Aug 2024 02:01:10 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo.mondi@ideasonboard.com>","Cc":"Umang Jain <umang.jain@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org,\n\tXavier Roumegue <xavier.roumegue@oss.nxp.com>","Subject":"Re: [RFC PATCH 6/6] libcamera: converter_dw100: Load and apply\n\tdewarp vertex maps","Message-ID":"<20240802230110.GG3319@pendragon.ideasonboard.com>","References":"<20240712052920.33396-1-umang.jain@ideasonboard.com>\n\t<20240712052920.33396-7-umang.jain@ideasonboard.com>\n\t<6ztspkss3a2tuw4tzulizjjdkl43bfmyscgbzw2r2nraahnfka@ttiegljjg2ss>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<6ztspkss3a2tuw4tzulizjjdkl43bfmyscgbzw2r2nraahnfka@ttiegljjg2ss>","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>"}}]