[{"id":23054,"web_url":"https://patchwork.libcamera.org/comment/23054/","msgid":"<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","date":"2022-05-18T13:54:39","subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nThank you for the patch.\n\nOn Wed, May 18, 2022 at 04:13:28PM +0300, Tomi Valkeinen wrote:\n> Generate a list of pixel formats under \"libcamera.formats\".\n> \n> I'm not super happy about this solution, as the user can change the\n> formats (libcamera.formats.XRGB8888 = None) and, for some reason,\n\nI won't make it a blocker for this patch, but is there a way this could\nbe fixed ?\n\n> pybind11-stubgen doesn't produce stubs for this.\n> \n> However, other than the two issues above, it works, and I haven't\n> figured out a better way.\n> \n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> ---\n>  src/py/libcamera/gen-py-formats.py           | 56 ++++++++++++++++++++\n>  src/py/libcamera/meson.build                 | 12 +++++\n>  src/py/libcamera/py_formats_generated.cpp.in | 21 ++++++++\n>  src/py/libcamera/py_main.cpp                 |  3 ++\n>  4 files changed, 92 insertions(+)\n>  create mode 100755 src/py/libcamera/gen-py-formats.py\n>  create mode 100644 src/py/libcamera/py_formats_generated.cpp.in\n> \n> diff --git a/src/py/libcamera/gen-py-formats.py b/src/py/libcamera/gen-py-formats.py\n> new file mode 100755\n> index 00000000..72565a25\n> --- /dev/null\n> +++ b/src/py/libcamera/gen-py-formats.py\n> @@ -0,0 +1,56 @@\n> +#!/usr/bin/env python3\n> +# SPDX-License-Identifier: GPL-2.0-or-later\n> +#\n> +# Generate Python format definitions from YAML\n> +\n> +import argparse\n> +import string\n> +import sys\n> +import yaml\n> +\n> +\n> +def generate(formats):\n> +    fmts = []\n> +\n> +    for format in formats:\n> +        name, format = format.popitem()\n> +        fmts.append(f'formats.attr(\"{name}\") = &libcamera::formats::{name};')\n> +\n> +    return {'formats': '\\n'.join(fmts)}\n> +\n> +\n> +def fill_template(template, data):\n> +    with open(template, encoding='utf-8') as f:\n> +        template = f.read()\n> +\n> +    template = string.Template(template)\n> +    return template.substitute(data)\n> +\n> +\n> +def main(argv):\n> +    parser = argparse.ArgumentParser()\n> +    parser.add_argument('-o', dest='output', metavar='file', type=str,\n> +                        help='Output file name. Defaults to standard output if not specified.')\n> +    parser.add_argument('input', type=str,\n> +                        help='Input file name.')\n> +    parser.add_argument('template', type=str,\n> +                        help='Template file name.')\n> +    args = parser.parse_args(argv[1:])\n> +\n> +    with open(args.input, encoding='utf-8') as f:\n> +        formats = yaml.safe_load(f)['formats']\n> +\n> +    data = generate(formats)\n> +    data = fill_template(args.template, data)\n> +\n> +    if args.output:\n> +        with open(args.output, 'w', encoding='utf-8') as f:\n> +            f.write(data)\n> +    else:\n> +        sys.stdout.write(data)\n> +\n> +    return 0\n> +\n> +\n> +if __name__ == '__main__':\n> +    sys.exit(main(sys.argv))\n> diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\n> index a3388c63..0a7b65f3 100644\n> --- a/src/py/libcamera/meson.build\n> +++ b/src/py/libcamera/meson.build\n> @@ -30,6 +30,18 @@ pycamera_sources += custom_target('py_gen_controls',\n>                                    output : ['py_control_enums_generated.cpp'],\n>                                    command : [gen_py_control_enums, '-o', '@OUTPUT@', '@INPUT@'])\n>  \n> +gen_py_formats_input_files = files([\n> +    '../../libcamera/formats.yaml',\n> +    'py_formats_generated.cpp.in',\n> +])\n> +\n> +gen_py_formats = files('gen-py-formats.py')\n> +\n> +pycamera_sources += custom_target('py_gen_formats',\n> +                                  input : gen_py_formats_input_files,\n> +                                  output : ['py_formats_generated.cpp'],\n> +                                  command : [gen_py_formats, '-o', '@OUTPUT@', '@INPUT@'])\n> +\n>  pycamera_deps = [\n>      libcamera_public,\n>      py3_dep,\n> diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in\n> new file mode 100644\n> index 00000000..1100c024\n> --- /dev/null\n> +++ b/src/py/libcamera/py_formats_generated.cpp.in\n> @@ -0,0 +1,21 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> + *\n> + * Python bindings - Auto-generated formats\n> + *\n> + * This file is auto-generated. Do not edit.\n> + */\n> +\n> +#include <libcamera/formats.h>\n> +\n> +#include <pybind11/smart_holder.h>\n> +\n> +namespace py = pybind11;\n> +\n> +void init_py_formats_generated(py::module& m)\n> +{\n> +auto formats = m.def_submodule(\"formats\");\n> +\n> +${formats}\n\nCould you indent this ? It's nicer to keep generated files readable.\n\nApart from that,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +}\n> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> index 1d941160..e7066841 100644\n> --- a/src/py/libcamera/py_main.cpp\n> +++ b/src/py/libcamera/py_main.cpp\n> @@ -132,6 +132,7 @@ static void handleRequestCompleted(Request *req)\n>  \n>  void init_py_enums(py::module &m);\n>  void init_py_control_enums_generated(py::module &m);\n> +void init_py_formats_generated(py::module &m);\n>  void init_py_geometry(py::module &m);\n>  \n>  PYBIND11_MODULE(_libcamera, m)\n> @@ -171,6 +172,8 @@ PYBIND11_MODULE(_libcamera, m)\n>  \tauto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, \"Range\");\n>  \tauto pyPixelFormat = py::class_<PixelFormat>(m, \"PixelFormat\");\n>  \n> +\tinit_py_formats_generated(m);\n> +\n>  \t/* Global functions */\n>  \tm.def(\"log_set_level\", &logSetLevel);\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 298C5C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 May 2022 13:54:51 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 70C6865659;\n\tWed, 18 May 2022 15:54:50 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id AC56C65656\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 May 2022 15:54:47 +0200 (CEST)","from pendragon.ideasonboard.com (unknown [45.131.31.124])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 54ADAE50;\n\tWed, 18 May 2022 15:54:46 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652882090;\n\tbh=Ds40xP4KNww+VVB2EBjfFAa68NwwED7gw5oM+089bug=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=2c46Xy7pD6o6VWclLEEhtJRpvb4hS+PRklznmjFx4WiIJqKW/1HVtMYpKX3EWhVx5\n\tS+JAyhh0n49MGYdsuDtxBfXE8iMQ73343fyaRTO0K8BCY74umetAd+cY15zjdRBWBC\n\t1Bbrw7eua0ywUpH1at8codp9Nr0xEl94PYayeSC/YGZsWPEOfrfMNLPJcP9NQ6qevb\n\t24ny1BX9IhIBh6Ow6W/nlT5HMBtiobvwvhCTEmfJDWrIk3PUtluZfgIi+1B1g66+Iz\n\tAtrbe/YReDcZ0iwSVY6x8pjEITGVf9LjxFStfai/w463ZpJgqIULh4G9Ev5VZ6OEO5\n\tukkEkv8kCUpUQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652882086;\n\tbh=Ds40xP4KNww+VVB2EBjfFAa68NwwED7gw5oM+089bug=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=fantesU6Zj0N7NDWFSIUQbuNbZmM4pvEKjurQdxzDZRG+eTyIDCWOdkdq4TGx1GrK\n\te7N5Qjo0rqNciIX3deHNiW00j4IWI7LEVfGy9vbKI1wORtexDSG6ZrIOdqtHexj9y5\n\teCMgXz+bRzKeSzWoztrISKiOsIqpCrjdCCGjd+Pk="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"fantesU6\"; dkim-atps=neutral","Date":"Wed, 18 May 2022 16:54:39 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","References":"<20220518131329.66994-1-tomi.valkeinen@ideasonboard.com>\n\t<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23058,"web_url":"https://patchwork.libcamera.org/comment/23058/","msgid":"<5139628f-1b5a-f4db-92e4-784e2022db3c@ideasonboard.com>","date":"2022-05-18T14:09:22","subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 18/05/2022 16:54, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> Thank you for the patch.\n> \n> On Wed, May 18, 2022 at 04:13:28PM +0300, Tomi Valkeinen wrote:\n>> Generate a list of pixel formats under \"libcamera.formats\".\n>>\n>> I'm not super happy about this solution, as the user can change the\n>> formats (libcamera.formats.XRGB8888 = None) and, for some reason,\n> \n> I won't make it a blocker for this patch, but is there a way this could\n> be fixed ?\n\nI don't know. I don't think it's a big issue. Usually you can overwrite \nall kinds of things in Python, so this is no different.\n\nI think another way would be to implement this in pure python (generated \n.py file). Perhaps a Python enum would work here.\n\nWhatever we figure out in the future, I believe the style the user uses \nwill stay the same (libcamera.format.XRGB8888).\n\n>> pybind11-stubgen doesn't produce stubs for this.\n>>\n>> However, other than the two issues above, it works, and I haven't\n>> figured out a better way.\n>>\n>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n>> ---\n>>   src/py/libcamera/gen-py-formats.py           | 56 ++++++++++++++++++++\n>>   src/py/libcamera/meson.build                 | 12 +++++\n>>   src/py/libcamera/py_formats_generated.cpp.in | 21 ++++++++\n>>   src/py/libcamera/py_main.cpp                 |  3 ++\n>>   4 files changed, 92 insertions(+)\n>>   create mode 100755 src/py/libcamera/gen-py-formats.py\n>>   create mode 100644 src/py/libcamera/py_formats_generated.cpp.in\n>>\n>> diff --git a/src/py/libcamera/gen-py-formats.py b/src/py/libcamera/gen-py-formats.py\n>> new file mode 100755\n>> index 00000000..72565a25\n>> --- /dev/null\n>> +++ b/src/py/libcamera/gen-py-formats.py\n>> @@ -0,0 +1,56 @@\n>> +#!/usr/bin/env python3\n>> +# SPDX-License-Identifier: GPL-2.0-or-later\n>> +#\n>> +# Generate Python format definitions from YAML\n>> +\n>> +import argparse\n>> +import string\n>> +import sys\n>> +import yaml\n>> +\n>> +\n>> +def generate(formats):\n>> +    fmts = []\n>> +\n>> +    for format in formats:\n>> +        name, format = format.popitem()\n>> +        fmts.append(f'formats.attr(\"{name}\") = &libcamera::formats::{name};')\n>> +\n>> +    return {'formats': '\\n'.join(fmts)}\n>> +\n>> +\n>> +def fill_template(template, data):\n>> +    with open(template, encoding='utf-8') as f:\n>> +        template = f.read()\n>> +\n>> +    template = string.Template(template)\n>> +    return template.substitute(data)\n>> +\n>> +\n>> +def main(argv):\n>> +    parser = argparse.ArgumentParser()\n>> +    parser.add_argument('-o', dest='output', metavar='file', type=str,\n>> +                        help='Output file name. Defaults to standard output if not specified.')\n>> +    parser.add_argument('input', type=str,\n>> +                        help='Input file name.')\n>> +    parser.add_argument('template', type=str,\n>> +                        help='Template file name.')\n>> +    args = parser.parse_args(argv[1:])\n>> +\n>> +    with open(args.input, encoding='utf-8') as f:\n>> +        formats = yaml.safe_load(f)['formats']\n>> +\n>> +    data = generate(formats)\n>> +    data = fill_template(args.template, data)\n>> +\n>> +    if args.output:\n>> +        with open(args.output, 'w', encoding='utf-8') as f:\n>> +            f.write(data)\n>> +    else:\n>> +        sys.stdout.write(data)\n>> +\n>> +    return 0\n>> +\n>> +\n>> +if __name__ == '__main__':\n>> +    sys.exit(main(sys.argv))\n>> diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\n>> index a3388c63..0a7b65f3 100644\n>> --- a/src/py/libcamera/meson.build\n>> +++ b/src/py/libcamera/meson.build\n>> @@ -30,6 +30,18 @@ pycamera_sources += custom_target('py_gen_controls',\n>>                                     output : ['py_control_enums_generated.cpp'],\n>>                                     command : [gen_py_control_enums, '-o', '@OUTPUT@', '@INPUT@'])\n>>   \n>> +gen_py_formats_input_files = files([\n>> +    '../../libcamera/formats.yaml',\n>> +    'py_formats_generated.cpp.in',\n>> +])\n>> +\n>> +gen_py_formats = files('gen-py-formats.py')\n>> +\n>> +pycamera_sources += custom_target('py_gen_formats',\n>> +                                  input : gen_py_formats_input_files,\n>> +                                  output : ['py_formats_generated.cpp'],\n>> +                                  command : [gen_py_formats, '-o', '@OUTPUT@', '@INPUT@'])\n>> +\n>>   pycamera_deps = [\n>>       libcamera_public,\n>>       py3_dep,\n>> diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in\n>> new file mode 100644\n>> index 00000000..1100c024\n>> --- /dev/null\n>> +++ b/src/py/libcamera/py_formats_generated.cpp.in\n>> @@ -0,0 +1,21 @@\n>> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n>> +/*\n>> + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n>> + *\n>> + * Python bindings - Auto-generated formats\n>> + *\n>> + * This file is auto-generated. Do not edit.\n>> + */\n>> +\n>> +#include <libcamera/formats.h>\n>> +\n>> +#include <pybind11/smart_holder.h>\n>> +\n>> +namespace py = pybind11;\n>> +\n>> +void init_py_formats_generated(py::module& m)\n>> +{\n>> +auto formats = m.def_submodule(\"formats\");\n>> +\n>> +${formats}\n> \n> Could you indent this ? It's nicer to keep generated files readable.\n\nSure.\n\n  Tomi","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 D6701C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 May 2022 14:09:27 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 876846565B;\n\tWed, 18 May 2022 16:09:27 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id E213C65656\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 May 2022 16:09:25 +0200 (CEST)","from [192.168.1.111] (91-156-85-209.elisa-laajakaista.fi\n\t[91.156.85.209])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 6DE17E50;\n\tWed, 18 May 2022 16:09:25 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652882967;\n\tbh=8fQIeDuYACDUrvdGbFzNDvh2RLZN2EKS1iWxJSZCBeQ=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=cKuf0JvO1C3qGOFHj/6OeFNkqtL8zrn48tLl+azditmXYzo0fpcOG6NSWFJoF1U5M\n\tI+A0or17UFxJo5xYixsHNgQ4Ki/yqFJH3EHr0i5riM5vASejg0cbvT/t8XKUcCNbsB\n\t7b4B08CU0kPY3OH60bNkj/AE9hfrI2Pdm4EqBS9fcaEeEsw1kDQO80QFWDsJ9kM0cw\n\tr8oQVW4emAEJsoCYPQ2hMVzzShn64rOJJPlvSGZcVj4KZLzeds+0RuxvKBEt7PX0OV\n\tv1lcsMMa7ezoGGGwu6By1fEGvgJHDj7xI7E1tYfs0XCetoo9RZNvNqBYpPd8B1MsZo\n\tsgIyr/EUx988w==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652882965;\n\tbh=8fQIeDuYACDUrvdGbFzNDvh2RLZN2EKS1iWxJSZCBeQ=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=Ie1Guo9R3yxb/pgDC5TOGECuUGuGZe/N84Y1yO5QN53GkmApq/nZ8tbvHG4+IKhRq\n\tb9hAJ4lPHS+6Er4afUh27CaZIUkDZF7Vv/fj7YMGtilMTgrRrkLodvUq+CLD5J845c\n\tFbyJX4t0gxlBz0yK0egqVbQP4L191mKvxcyeHAkY="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Ie1Guo9R\"; dkim-atps=neutral","Message-ID":"<5139628f-1b5a-f4db-92e4-784e2022db3c@ideasonboard.com>","Date":"Wed, 18 May 2022 17:09:22 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.8.0","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220518131329.66994-1-tomi.valkeinen@ideasonboard.com>\n\t<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>\n\t<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","In-Reply-To":"<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","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>","From":"Tomi Valkeinen via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23061,"web_url":"https://patchwork.libcamera.org/comment/23061/","msgid":"<165288336668.368702.15516559515324535259@Monstersaurus>","date":"2022-05-18T14:16:06","subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","submitter":{"id":4,"url":"https://patchwork.libcamera.org/api/people/4/","name":"Kieran Bingham","email":"kieran.bingham@ideasonboard.com"},"content":"Quoting Laurent Pinchart (2022-05-18 14:54:39)\n> Hi Tomi,\n> \n> Thank you for the patch.\n> \n> On Wed, May 18, 2022 at 04:13:28PM +0300, Tomi Valkeinen wrote:\n> > Generate a list of pixel formats under \"libcamera.formats\".\n> > \n> > I'm not super happy about this solution, as the user can change the\n> > formats (libcamera.formats.XRGB8888 = None) and, for some reason,\n> \n> I won't make it a blocker for this patch, but is there a way this could\n> be fixed ?\n> \n\nAre these types generated with this name 'libcamera.' or is that\ninherited by being in the module?\n\nI.e. would\n \"import libcamera as cam\"\nmake these cam.formats.XRGB8888 ?\n\n> > pybind11-stubgen doesn't produce stubs for this.\n> > \n> > However, other than the two issues above, it works, and I haven't\n> > figured out a better way.\n> > \n> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > ---\n> >  src/py/libcamera/gen-py-formats.py           | 56 ++++++++++++++++++++\n> >  src/py/libcamera/meson.build                 | 12 +++++\n> >  src/py/libcamera/py_formats_generated.cpp.in | 21 ++++++++\n> >  src/py/libcamera/py_main.cpp                 |  3 ++\n> >  4 files changed, 92 insertions(+)\n> >  create mode 100755 src/py/libcamera/gen-py-formats.py\n> >  create mode 100644 src/py/libcamera/py_formats_generated.cpp.in\n> > \n> > diff --git a/src/py/libcamera/gen-py-formats.py b/src/py/libcamera/gen-py-formats.py\n> > new file mode 100755\n> > index 00000000..72565a25\n> > --- /dev/null\n> > +++ b/src/py/libcamera/gen-py-formats.py\n> > @@ -0,0 +1,56 @@\n> > +#!/usr/bin/env python3\n> > +# SPDX-License-Identifier: GPL-2.0-or-later\n> > +#\n> > +# Generate Python format definitions from YAML\n> > +\n> > +import argparse\n> > +import string\n> > +import sys\n> > +import yaml\n> > +\n> > +\n> > +def generate(formats):\n> > +    fmts = []\n> > +\n> > +    for format in formats:\n> > +        name, format = format.popitem()\n> > +        fmts.append(f'formats.attr(\"{name}\") = &libcamera::formats::{name};')\n> > +\n> > +    return {'formats': '\\n'.join(fmts)}\n> > +\n> > +\n> > +def fill_template(template, data):\n> > +    with open(template, encoding='utf-8') as f:\n> > +        template = f.read()\n> > +\n> > +    template = string.Template(template)\n> > +    return template.substitute(data)\n> > +\n> > +\n> > +def main(argv):\n> > +    parser = argparse.ArgumentParser()\n> > +    parser.add_argument('-o', dest='output', metavar='file', type=str,\n> > +                        help='Output file name. Defaults to standard output if not specified.')\n> > +    parser.add_argument('input', type=str,\n> > +                        help='Input file name.')\n> > +    parser.add_argument('template', type=str,\n> > +                        help='Template file name.')\n> > +    args = parser.parse_args(argv[1:])\n> > +\n> > +    with open(args.input, encoding='utf-8') as f:\n> > +        formats = yaml.safe_load(f)['formats']\n> > +\n> > +    data = generate(formats)\n> > +    data = fill_template(args.template, data)\n> > +\n> > +    if args.output:\n> > +        with open(args.output, 'w', encoding='utf-8') as f:\n> > +            f.write(data)\n> > +    else:\n> > +        sys.stdout.write(data)\n> > +\n> > +    return 0\n> > +\n> > +\n> > +if __name__ == '__main__':\n> > +    sys.exit(main(sys.argv))\n> > diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build\n> > index a3388c63..0a7b65f3 100644\n> > --- a/src/py/libcamera/meson.build\n> > +++ b/src/py/libcamera/meson.build\n> > @@ -30,6 +30,18 @@ pycamera_sources += custom_target('py_gen_controls',\n> >                                    output : ['py_control_enums_generated.cpp'],\n> >                                    command : [gen_py_control_enums, '-o', '@OUTPUT@', '@INPUT@'])\n> >  \n> > +gen_py_formats_input_files = files([\n> > +    '../../libcamera/formats.yaml',\n> > +    'py_formats_generated.cpp.in',\n> > +])\n> > +\n> > +gen_py_formats = files('gen-py-formats.py')\n> > +\n> > +pycamera_sources += custom_target('py_gen_formats',\n> > +                                  input : gen_py_formats_input_files,\n> > +                                  output : ['py_formats_generated.cpp'],\n> > +                                  command : [gen_py_formats, '-o', '@OUTPUT@', '@INPUT@'])\n> > +\n> >  pycamera_deps = [\n> >      libcamera_public,\n> >      py3_dep,\n> > diff --git a/src/py/libcamera/py_formats_generated.cpp.in b/src/py/libcamera/py_formats_generated.cpp.in\n> > new file mode 100644\n> > index 00000000..1100c024\n> > --- /dev/null\n> > +++ b/src/py/libcamera/py_formats_generated.cpp.in\n> > @@ -0,0 +1,21 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n> > + *\n> > + * Python bindings - Auto-generated formats\n> > + *\n> > + * This file is auto-generated. Do not edit.\n> > + */\n> > +\n> > +#include <libcamera/formats.h>\n> > +\n> > +#include <pybind11/smart_holder.h>\n> > +\n> > +namespace py = pybind11;\n> > +\n> > +void init_py_formats_generated(py::module& m)\n> > +{\n> > +auto formats = m.def_submodule(\"formats\");\n> > +\n> > +${formats}\n> \n> Could you indent this ? It's nicer to keep generated files readable.\n> \n> Apart from that,\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n\nReviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n\n> \n> > +}\n> > diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp\n> > index 1d941160..e7066841 100644\n> > --- a/src/py/libcamera/py_main.cpp\n> > +++ b/src/py/libcamera/py_main.cpp\n> > @@ -132,6 +132,7 @@ static void handleRequestCompleted(Request *req)\n> >  \n> >  void init_py_enums(py::module &m);\n> >  void init_py_control_enums_generated(py::module &m);\n> > +void init_py_formats_generated(py::module &m);\n> >  void init_py_geometry(py::module &m);\n> >  \n> >  PYBIND11_MODULE(_libcamera, m)\n> > @@ -171,6 +172,8 @@ PYBIND11_MODULE(_libcamera, m)\n> >       auto pyColorSpaceRange = py::enum_<ColorSpace::Range>(pyColorSpace, \"Range\");\n> >       auto pyPixelFormat = py::class_<PixelFormat>(m, \"PixelFormat\");\n> >  \n> > +     init_py_formats_generated(m);\n> > +\n> >       /* Global functions */\n> >       m.def(\"log_set_level\", &logSetLevel);\n> >  \n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","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 CE40EC0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 May 2022 14:16:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 171F165659;\n\tWed, 18 May 2022 16:16:11 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 58F5A65656\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 May 2022 16:16:09 +0200 (CEST)","from pendragon.ideasonboard.com\n\t(cpc89244-aztw30-2-0-cust3082.18-1.cable.virginm.net [86.31.172.11])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C9397E50;\n\tWed, 18 May 2022 16:16:08 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652883371;\n\tbh=f3OsRzc3PF/QOaEYzH4mZj6KWQ86+ioHpXzNYEZPekw=;\n\th=In-Reply-To:References:To:Date:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=jSa9WPmov+MjPyc99S4uHGF1HchR9y7JL+YEJ2DFpdl8HfxZPkMseG8QMplxZLGWR\n\tvuRaq+HSvKK+G0xVWLrKNXDeVPCn9fBNLod0LCZ93H4GRRRidRUPfWWpBCBb3ZyMc8\n\tN7u8tdo7t5lB35kqzdsodPZU7lwP8WasXgyTP4y0NOlhYsWVjlL79/cmbA59otzHGX\n\ti45DQFTeIB5GCBzdhq96rkzvuHWGYN4CeEDbxg8eFjMrvYRsnW3OxZZ0+d6smIR4db\n\t9D88GoCodrSTuqLfBDSiRIhnallOKK9661oZvyX1Zmve0a0oougqaZWEzst3NbGTQB\n\teMfb6oh9rFfvQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652883368;\n\tbh=f3OsRzc3PF/QOaEYzH4mZj6KWQ86+ioHpXzNYEZPekw=;\n\th=In-Reply-To:References:Subject:From:Cc:To:Date:From;\n\tb=J3Lfqs8zcib3pejj3NXmZUDZq5Q9Lb5SjmOeg33R4E/D0IRSSNG1VANy4gnhLWzLZ\n\tuOutfBXD7jA+TJZtQQ8s0s2BXXWsz3/W/Bbnfg7gjN4U8CvNLUdcC7/92Qxr+9NvQX\n\tPBoBRvz4AKg0lEg2F7UGUs9jK9rgJBkCZLYDVF14="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"J3Lfqs8z\"; dkim-atps=neutral","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","References":"<20220518131329.66994-1-tomi.valkeinen@ideasonboard.com>\n\t<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>\n\t<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>,\n\tTomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Date":"Wed, 18 May 2022 15:16:06 +0100","Message-ID":"<165288336668.368702.15516559515324535259@Monstersaurus>","User-Agent":"alot/0.10","Subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","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>","From":"Kieran Bingham via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Kieran Bingham <kieran.bingham@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23065,"web_url":"https://patchwork.libcamera.org/comment/23065/","msgid":"<e7e8158e-bee6-41fd-5d0b-677a7665bb7d@ideasonboard.com>","date":"2022-05-18T15:00:01","subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","submitter":{"id":109,"url":"https://patchwork.libcamera.org/api/people/109/","name":"Tomi Valkeinen","email":"tomi.valkeinen@ideasonboard.com"},"content":"On 18/05/2022 16:54, Laurent Pinchart wrote:\n> Hi Tomi,\n> \n> Thank you for the patch.\n> \n> On Wed, May 18, 2022 at 04:13:28PM +0300, Tomi Valkeinen wrote:\n>> Generate a list of pixel formats under \"libcamera.formats\".\n>>\n>> I'm not super happy about this solution, as the user can change the\n>> formats (libcamera.formats.XRGB8888 = None) and, for some reason,\n> \n> I won't make it a blocker for this patch, but is there a way this could\n> be fixed ?\n\nAnother way would be to:\n\nclass dummy_base {};\n\nvoid init_py_formats_generated(py::module& m)\n{\n         py::class_<dummy_base>(m, \"formats\")\n                 .def_readonly_static(\"R8\", &libcamera::formats::R8)\n                 .def_readonly_static(\"R10\", &libcamera::formats::R10)\n                 .def_readonly_static(\"R12\", &libcamera::formats::R12)\n\t\t...\n\nSo, we would create a class to hold the formats, and then we can use \ndef_readonly_static. We do need a C++ base class, thus the dummy_base...\n\nIf we don't mind changing the API a bit, we could have these readonly \nstatics inside PixelFormat, so:\n\nlibcamera.PixelFormat.MJPEG\n\n  Tomi","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 8F2D6C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 May 2022 15:00:11 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1B26465659;\n\tWed, 18 May 2022 17:00:06 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 5863965656\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 May 2022 17:00:04 +0200 (CEST)","from [192.168.1.111] (91-156-85-209.elisa-laajakaista.fi\n\t[91.156.85.209])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 4E26EE50;\n\tWed, 18 May 2022 17:00:03 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652886006;\n\tbh=AktYGysXKSNQrdt9Pv6JbrAvDDOcEXWY9mdIAgrPthc=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=LzQZb0uybAiKbjpq1ZoQzU8qntBYpK9qvIbTCF61ezx814menB5YehVzF50xkm5b3\n\tfZjgZzckrZXT+XPLFuYdepcd1iczVdfYFXlvY8ePOjri5+fl91tqT7jCrYqLf3W1lv\n\tNL5uXMLVASlIIitRPHHkYxRVCUaRwkNwCYQiR4FinoJ5CHbWyiQqqJ0j0Pf/ar71QK\n\ttag1bOCKMjMo3qDl6uNnJGwda1VMwyQpSK+KoQOly2Zq2npBiPpOMlgLF6axcFyyOL\n\t+FQl9NECwerL3mlNM/BRHU1gD6S5SIRHSG0ZBMlq93b0Ala3qf0Y/hBK4QPMwR9R97\n\tFlPi0jVIh3QbQ==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652886003;\n\tbh=AktYGysXKSNQrdt9Pv6JbrAvDDOcEXWY9mdIAgrPthc=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=h2nG8TI3sUEC84dtXShypb6jw1MsEAefGxihsuaqKqEJKszlYCzZzSUC4scCEiEm6\n\tCylTZDGTQrxj/e+FGFNjg5vWxm6cn9TOPUsL7PyavW7QV9dKosX0ALogVUw+K2xJS8\n\tb55mwxZ8CDCQGCd9lUXC04yZ8nG/ls6dzsdLNP2Q="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"h2nG8TI3\"; dkim-atps=neutral","Message-ID":"<e7e8158e-bee6-41fd-5d0b-677a7665bb7d@ideasonboard.com>","Date":"Wed, 18 May 2022 18:00:01 +0300","MIME-Version":"1.0","User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101\n\tThunderbird/91.8.0","Content-Language":"en-US","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20220518131329.66994-1-tomi.valkeinen@ideasonboard.com>\n\t<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>\n\t<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","In-Reply-To":"<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"7bit","Subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","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>","From":"Tomi Valkeinen via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":23067,"web_url":"https://patchwork.libcamera.org/comment/23067/","msgid":"<YoUWaQOzzYaIN+Rp@pendragon.ideasonboard.com>","date":"2022-05-18T15:53:13","subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Tomi,\n\nOn Wed, May 18, 2022 at 06:00:01PM +0300, Tomi Valkeinen wrote:\n> On 18/05/2022 16:54, Laurent Pinchart wrote:\n> > On Wed, May 18, 2022 at 04:13:28PM +0300, Tomi Valkeinen wrote:\n> >> Generate a list of pixel formats under \"libcamera.formats\".\n> >>\n> >> I'm not super happy about this solution, as the user can change the\n> >> formats (libcamera.formats.XRGB8888 = None) and, for some reason,\n> > \n> > I won't make it a blocker for this patch, but is there a way this could\n> > be fixed ?\n> \n> Another way would be to:\n> \n> class dummy_base {};\n> \n> void init_py_formats_generated(py::module& m)\n> {\n>          py::class_<dummy_base>(m, \"formats\")\n>                  .def_readonly_static(\"R8\", &libcamera::formats::R8)\n>                  .def_readonly_static(\"R10\", &libcamera::formats::R10)\n>                  .def_readonly_static(\"R12\", &libcamera::formats::R12)\n> \t\t...\n> \n> So, we would create a class to hold the formats, and then we can use \n> def_readonly_static. We do need a C++ base class, thus the dummy_base...\n\nThe dummy_base class name is internal, not exposed to Python, right ?\nI'm then fine with this. We should use a name that would be a bit more\nexplicit, such as PyFormats for instance.\n\n> If we don't mind changing the API a bit, we could have these readonly \n> statics inside PixelFormat, so:\n> \n> libcamera.PixelFormat.MJPEG\n\nIf possible I'd like to keep the two APIs as close as possible.","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 48176C3256\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 18 May 2022 15:53:25 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6C23B65659;\n\tWed, 18 May 2022 17:53:24 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 4456A65656\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 18 May 2022 17:53:22 +0200 (CEST)","from pendragon.ideasonboard.com (unknown [45.131.31.124])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 5F18FE50;\n\tWed, 18 May 2022 17:53:21 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652889204;\n\tbh=zTz98pkaax0DFT3hXTFZm8U23g2y8lSzUDy+KOKm3yg=;\n\th=Date:To:References:In-Reply-To:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:\n\tFrom;\n\tb=AhPx3eaOwLCZ/P2YPZJJZN5fW33FNSwZr5ZHzJYoGH1C4wwQMiEZ4af5Zj3Gbiuje\n\texmMARSHQpEhaz1ggAxIIqj9cg7dzR43+8XAnGfXSVaZKsVng5JfYtHqWoY/Vv9wEp\n\tp9tU2a+/OW7qVsNO05cz8a5nSf36xeKXjrMgc7xgoCw71vEBfqT7vF+V3QgGuLi1bs\n\tjZCwU+NAB6e6jZo95b4+QifE37Av+2QcWl8XtSUhKla6M14Bg+qDQuOJvQFx6KSiBr\n\tZVjZkRYRYJHzPLqd8v3shgYSBHGjllIPE3NeZK/1X3PUhNwffuGGz4kRJfvX7cgpt7\n\tmrhN5VqVsNRhw==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652889201;\n\tbh=zTz98pkaax0DFT3hXTFZm8U23g2y8lSzUDy+KOKm3yg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Xr6Bl75KF92HpLGAW/m3Ks18iB3yqzVK8jzBt9TMoAA6p2nzFcrBUGJQtve80aEIW\n\t2huERy8/iM449YyrqFB+XXK3Igxi3AVl2VB5CDha0YcGLK4Ko0LEwJ5lG/ff+kxPXy\n\tJIBi2uIprTfZoADTYt56jFlDFsB5FKJEBtCrQVWs="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"Xr6Bl75K\"; dkim-atps=neutral","Date":"Wed, 18 May 2022 18:53:13 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YoUWaQOzzYaIN+Rp@pendragon.ideasonboard.com>","References":"<20220518131329.66994-1-tomi.valkeinen@ideasonboard.com>\n\t<20220518131329.66994-18-tomi.valkeinen@ideasonboard.com>\n\t<YoT6n3AYSqnFfVtf@pendragon.ideasonboard.com>\n\t<e7e8158e-bee6-41fd-5d0b-677a7665bb7d@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<e7e8158e-bee6-41fd-5d0b-677a7665bb7d@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 17/18] py: generate pixel formats\n\tlist","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>","From":"Laurent Pinchart via libcamera-devel\n\t<libcamera-devel@lists.libcamera.org>","Reply-To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]