[{"id":22976,"web_url":"https://patchwork.libcamera.org/comment/22976/","msgid":"<YoNfdHnMl1y2t+UQ@pendragon.ideasonboard.com>","date":"2022-05-17T08:40:20","subject":"Re: [libcamera-devel] [PATCH 12/14] py: use geometry classes","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 Mon, May 16, 2022 at 05:10:20PM +0300, Tomi Valkeinen wrote:\n> Now that we have proper geometry classes in the Python bindings, change\n> the existing bindings and the .py files accordingly.\n> \n> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>\n\nNeat :-)\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> ---\n>  src/py/cam/cam.py              |  7 ++++--\n>  src/py/cam/cam_kms.py          |  3 ++-\n>  src/py/cam/cam_qt.py           |  3 ++-\n>  src/py/cam/cam_qtgl.py         |  3 ++-\n>  src/py/libcamera/pymain.cpp    | 41 ++++++++--------------------------\n>  src/py/libcamera/utils/conv.py |  4 ++--\n>  6 files changed, 22 insertions(+), 39 deletions(-)\n> \n> diff --git a/src/py/cam/cam.py b/src/py/cam/cam.py\n> index 63c67126..347175b7 100755\n> --- a/src/py/cam/cam.py\n> +++ b/src/py/cam/cam.py\n> @@ -160,8 +160,11 @@ def configure(ctx):\n>      for idx, stream_opts in enumerate(streams):\n>          stream_config = camconfig.at(idx)\n>  \n> -        if 'width' in stream_opts and 'height' in stream_opts:\n> -            stream_config.size = (stream_opts['width'], stream_opts['height'])\n> +        if 'width' in stream_opts:\n> +            stream_config.size.width = stream_opts['width']\n> +\n> +        if 'height' in stream_opts:\n> +            stream_config.size.height = stream_opts['height']\n>  \n>          if 'pixelformat' in stream_opts:\n>              stream_config.pixel_format = libcam.PixelFormat.from_name(stream_opts['pixelformat'])\n> diff --git a/src/py/cam/cam_kms.py b/src/py/cam/cam_kms.py\n> index 7d11564b..da3dd4e0 100644\n> --- a/src/py/cam/cam_kms.py\n> +++ b/src/py/cam/cam_kms.py\n> @@ -125,7 +125,8 @@ class KMSRenderer:\n>                  })\n>  \n>                  for fb in ctx['allocator'].buffers(stream):\n> -                    w, h = cfg.size\n> +                    w = cfg.size.width\n> +                    h = cfg.size.height\n>                      stride = cfg.stride\n>                      fd = fb.fd(0)\n>                      drmfb = pykms.DmabufFramebuffer(self.card, w, h, fmt,\n> diff --git a/src/py/cam/cam_qt.py b/src/py/cam/cam_qt.py\n> index 64f49f33..8bef9b57 100644\n> --- a/src/py/cam/cam_qt.py\n> +++ b/src/py/cam/cam_qt.py\n> @@ -136,7 +136,8 @@ class MainWindow(QtWidgets.QWidget):\n>      def buf_to_qpixmap(self, stream, fb):\n>          with fb.mmap() as mfb:\n>              cfg = stream.configuration\n> -            w, h = cfg.size\n> +            w = cfg.size.width\n> +            h = cfg.size.height\n>              pitch = cfg.stride\n>  \n>              if cfg.pixel_format.name == 'MJPEG':\n> diff --git a/src/py/cam/cam_qtgl.py b/src/py/cam/cam_qtgl.py\n> index 261accb8..4bbcda6c 100644\n> --- a/src/py/cam/cam_qtgl.py\n> +++ b/src/py/cam/cam_qtgl.py\n> @@ -268,7 +268,8 @@ class MainWindow(QtWidgets.QWidget):\n>      def create_texture(self, stream, fb):\n>          cfg = stream.configuration\n>          fmt = cfg.pixel_format.fourcc\n> -        w, h = cfg.size\n> +        w = cfg.size.width\n> +        h = cfg.size.height\n>  \n>          attribs = [\n>              EGL_WIDTH, w,\n> diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp\n> index 1dd70d9c..d7bd71ef 100644\n> --- a/src/py/libcamera/pymain.cpp\n> +++ b/src/py/libcamera/pymain.cpp\n> @@ -6,7 +6,6 @@\n>   */\n>  \n>  /*\n> - * \\todo Add geometry classes (Point, Rectangle...)\n>   * \\todo Add bindings for the ControlInfo class\n>   */\n>  \n> @@ -61,11 +60,11 @@ static py::object controlValueToPy(const ControlValue &cv)\n>  \t\treturn py::cast(cv.get<std::string>());\n>  \tcase ControlTypeRectangle: {\n>  \t\tconst Rectangle *v = reinterpret_cast<const Rectangle *>(cv.data().data());\n> -\t\treturn py::make_tuple(v->x, v->y, v->width, v->height);\n> +\t\treturn py::cast(v);\n>  \t}\n>  \tcase ControlTypeSize: {\n>  \t\tconst Size *v = reinterpret_cast<const Size *>(cv.data().data());\n> -\t\treturn py::make_tuple(v->width, v->height);\n> +\t\treturn py::cast(v);\n>  \t}\n>  \tcase ControlTypeNone:\n>  \tdefault:\n> @@ -99,14 +98,10 @@ static ControlValue pyToControlValue(const py::object &ob, ControlType type)\n>  \t\treturn controlValueMaybeArray<float>(ob);\n>  \tcase ControlTypeString:\n>  \t\treturn ControlValue(ob.cast<std::string>());\n> -\tcase ControlTypeRectangle: {\n> -\t\tauto array = ob.cast<std::array<int32_t, 4>>();\n> -\t\treturn ControlValue(Rectangle(array[0], array[1], array[2], array[3]));\n> -\t}\n> -\tcase ControlTypeSize: {\n> -\t\tauto array = ob.cast<std::array<int32_t, 2>>();\n> -\t\treturn ControlValue(Size(array[0], array[1]));\n> -\t}\n> +\tcase ControlTypeRectangle:\n> +\t\treturn ControlValue(ob.cast<Rectangle>());\n> +\tcase ControlTypeSize:\n> +\t\treturn ControlValue(ob.cast<Size>());\n>  \tcase ControlTypeNone:\n>  \tdefault:\n>  \t\tthrow std::runtime_error(\"Control type not implemented\");\n> @@ -397,15 +392,7 @@ PYBIND11_MODULE(_libcamera, m)\n>  \t\t.def(\"__str__\", &StreamConfiguration::toString)\n>  \t\t.def_property_readonly(\"stream\", &StreamConfiguration::stream,\n>  \t\t\t\t       py::return_value_policy::reference_internal)\n> -\t\t.def_property(\n> -\t\t\t\"size\",\n> -\t\t\t[](StreamConfiguration &self) {\n> -\t\t\t\treturn std::make_tuple(self.size.width, self.size.height);\n> -\t\t\t},\n> -\t\t\t[](StreamConfiguration &self, std::tuple<uint32_t, uint32_t> size) {\n> -\t\t\t\tself.size.width = std::get<0>(size);\n> -\t\t\t\tself.size.height = std::get<1>(size);\n> -\t\t\t})\n> +\t\t.def_readwrite(\"size\", &StreamConfiguration::size)\n>  \t\t.def_readwrite(\"pixel_format\", &StreamConfiguration::pixelFormat)\n>  \t\t.def_readwrite(\"stride\", &StreamConfiguration::stride)\n>  \t\t.def_readwrite(\"frame_size\", &StreamConfiguration::frameSize)\n> @@ -416,18 +403,8 @@ PYBIND11_MODULE(_libcamera, m)\n>  \n>  \tpyStreamFormats\n>  \t\t.def_property_readonly(\"pixel_formats\", &StreamFormats::pixelformats)\n> -\t\t.def(\"sizes\", [](StreamFormats &self, const PixelFormat &pixelFormat) {\n> -\t\t\tstd::vector<std::tuple<uint32_t, uint32_t>> fmts;\n> -\t\t\tfor (const auto &s : self.sizes(pixelFormat))\n> -\t\t\t\tfmts.push_back(std::make_tuple(s.width, s.height));\n> -\t\t\treturn fmts;\n> -\t\t})\n> -\t\t.def(\"range\", [](StreamFormats &self, const PixelFormat &pixelFormat) {\n> -\t\t\tconst auto &range = self.range(pixelFormat);\n> -\t\t\treturn make_tuple(std::make_tuple(range.hStep, range.vStep),\n> -\t\t\t\t\t  std::make_tuple(range.min.width, range.min.height),\n> -\t\t\t\t\t  std::make_tuple(range.max.width, range.max.height));\n> -\t\t});\n> +\t\t.def(\"sizes\", &StreamFormats::sizes)\n> +\t\t.def(\"range\", &StreamFormats::range);\n>  \n>  \tpyFrameBufferAllocator\n>  \t\t.def(py::init<std::shared_ptr<Camera>>(), py::keep_alive<1, 2>())\n> diff --git a/src/py/libcamera/utils/conv.py b/src/py/libcamera/utils/conv.py\n> index 30f6733e..5a4bc282 100644\n> --- a/src/py/libcamera/utils/conv.py\n> +++ b/src/py/libcamera/utils/conv.py\n> @@ -73,8 +73,8 @@ def demosaic(data, r0, g0, g1, b0):\n>  \n>  \n>  def to_rgb(fmt, size, data):\n> -    w = size[0]\n> -    h = size[1]\n> +    w = size.width\n> +    h = size.height\n>  \n>      fmt = fmt.name\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 23551C0F2A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 17 May 2022 08:40:29 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 81E7765656;\n\tTue, 17 May 2022 10:40:28 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 301F060420\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 17 May 2022 10:40:27 +0200 (CEST)","from pendragon.ideasonboard.com (unknown [45.131.31.124])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 523FC48F;\n\tTue, 17 May 2022 10:40:26 +0200 (CEST)"],"DKIM-Signature":["v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1652776828;\n\tbh=4bdroMqxTwH15ou0ZPaLAkUC0NlmOmUQLXmJ93f7lnQ=;\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=VN4isybgXRdetIH/fEYhRIYtSgmvxJp76xWNCRELGD8DXw9e4eZbGz7siiqKn0Xjk\n\tsrWuemH6zXdtR2nVHDnIQk7yuMCs/j2CQKtFMe7i2gSaKvlM/8gygbT9KdLc3znjYU\n\tCvtttdhUF+cvyAd+Y4+dtn7Ur7xV6rUdQCd2bculG3hqebY1Eri3b1SM2G0mv6b1RZ\n\tozXhi+6OcM+dx+3mPDFjSWpNgM7Grl8L/UdzjUD+CPnI1qK8+jC0EzC+5kI7oqSV8K\n\tlhYklFK8Xr2RVqFDPfZ2r1Th1VNRJAFDf/6CGf2HtGeWQ0ZXkK8E9/vGYzunm30qbY\n\tZR69nzfzoylPg==","v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1652776826;\n\tbh=4bdroMqxTwH15ou0ZPaLAkUC0NlmOmUQLXmJ93f7lnQ=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=b49IGRmr7h4ep8qiq0GOsfxvsYMRliSa6Ola0ahVRcHmiZ0TwdJhOG8Dx1s9wDWZX\n\tEvOtk1f4IubnjURhqd6lXTGkPavqh8go3KgBHx/0i/q5h3rLDl+LvO31ZtK6p5PfHA\n\tb840z/EQ2zuC+n66emedoHiMvWAxuK7pr2Ot91mM="],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"b49IGRmr\"; dkim-atps=neutral","Date":"Tue, 17 May 2022 11:40:20 +0300","To":"Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>","Message-ID":"<YoNfdHnMl1y2t+UQ@pendragon.ideasonboard.com>","References":"<20220516141022.96327-1-tomi.valkeinen@ideasonboard.com>\n\t<20220516141022.96327-13-tomi.valkeinen@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20220516141022.96327-13-tomi.valkeinen@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 12/14] py: use geometry classes","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>"}}]