pycamera: Fix FrameBuffer::planes wrapper
diff mbox series

Message ID 20250916133234.947678-1-stefan.klug@ideasonboard.com
State New
Headers show
Series
  • pycamera: Fix FrameBuffer::planes wrapper
Related show

Commit Message

Stefan Klug Sept. 16, 2025, 1:31 p.m. UTC
In commit b8d332cdcc13 ("libcamera: framebuffer: Replace vector with
span in constructor") the FrameBuffer::planes() function was modified to
return a Span instead of a vector. This leads to the following runtime
exception in the python binding:

TypeError: Unregistered type : libcamera::Span<libcamera::FrameBuffer::Plane const, 18446744073709551615ul>

Fix that by manually converting the Span to a vector.

Note: The best solution would be to implement a Span type caster for
pybind11. But implementing and testing that properly is a bit more
involved than expected. As we don't need bidirectional mapping, the same
workaround as for FrameMetadata::planes() was used for now.

Fixes: b8d332cdcc13 ("libcamera: framebuffer: Replace vector with span in constructor")
Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
---
 src/py/libcamera/py_main.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Comments

Laurent Pinchart Sept. 16, 2025, 1:34 p.m. UTC | #1
On Tue, Sep 16, 2025 at 03:31:53PM +0200, Stefan Klug wrote:
> In commit b8d332cdcc13 ("libcamera: framebuffer: Replace vector with
> span in constructor") the FrameBuffer::planes() function was modified to
> return a Span instead of a vector. This leads to the following runtime
> exception in the python binding:
> 
> TypeError: Unregistered type : libcamera::Span<libcamera::FrameBuffer::Plane const, 18446744073709551615ul>
> 
> Fix that by manually converting the Span to a vector.
> 
> Note: The best solution would be to implement a Span type caster for
> pybind11. But implementing and testing that properly is a bit more
> involved than expected. As we don't need bidirectional mapping, the same
> workaround as for FrameMetadata::planes() was used for now.

"use the same workaround as for FrameMetadata::planes() for now"

> Fixes: b8d332cdcc13 ("libcamera: framebuffer: Replace vector with span in constructor")
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> ---
>  src/py/libcamera/py_main.cpp | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> index 441a70ab4d5e..70245ec78f9a 100644
> --- a/src/py/libcamera/py_main.cpp
> +++ b/src/py/libcamera/py_main.cpp
> @@ -372,7 +372,13 @@ PYBIND11_MODULE(_libcamera, m)
>  		.def(py::init<std::vector<FrameBuffer::Plane>, unsigned int>(),
>  		     py::arg("planes"), py::arg("cookie") = 0)
>  		.def_property_readonly("metadata", &FrameBuffer::metadata, py::return_value_policy::reference_internal)
> -		.def_property_readonly("planes", &FrameBuffer::planes)
> +		.def_property_readonly("planes", [](const FrameBuffer &self) {
> +			/* Convert from Span<> to std::vector<> */
> +			/* Note: this creates copies */
> +			std::vector<FrameBuffer::Plane> v(self.planes().begin(),
> +							  self.planes().end());
> +			return v;
> +		})
>  		.def_property("cookie", &FrameBuffer::cookie, &FrameBuffer::setCookie);
>  
>  	pyFrameBufferPlane
Kieran Bingham Sept. 16, 2025, 1:38 p.m. UTC | #2
Quoting Laurent Pinchart (2025-09-16 14:34:45)
> On Tue, Sep 16, 2025 at 03:31:53PM +0200, Stefan Klug wrote:
> > In commit b8d332cdcc13 ("libcamera: framebuffer: Replace vector with
> > span in constructor") the FrameBuffer::planes() function was modified to
> > return a Span instead of a vector. This leads to the following runtime
> > exception in the python binding:
> > 
> > TypeError: Unregistered type : libcamera::Span<libcamera::FrameBuffer::Plane const, 18446744073709551615ul>
> > 
> > Fix that by manually converting the Span to a vector.
> > 
> > Note: The best solution would be to implement a Span type caster for
> > pybind11. But implementing and testing that properly is a bit more
> > involved than expected. As we don't need bidirectional mapping, the same
> > workaround as for FrameMetadata::planes() was used for now.
> 
> "use the same workaround as for FrameMetadata::planes() for now"
> 
> > Fixes: b8d332cdcc13 ("libcamera: framebuffer: Replace vector with span in constructor")
> > Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>

> > ---
> >  src/py/libcamera/py_main.cpp | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> > index 441a70ab4d5e..70245ec78f9a 100644
> > --- a/src/py/libcamera/py_main.cpp
> > +++ b/src/py/libcamera/py_main.cpp
> > @@ -372,7 +372,13 @@ PYBIND11_MODULE(_libcamera, m)
> >               .def(py::init<std::vector<FrameBuffer::Plane>, unsigned int>(),
> >                    py::arg("planes"), py::arg("cookie") = 0)
> >               .def_property_readonly("metadata", &FrameBuffer::metadata, py::return_value_policy::reference_internal)
> > -             .def_property_readonly("planes", &FrameBuffer::planes)
> > +             .def_property_readonly("planes", [](const FrameBuffer &self) {
> > +                     /* Convert from Span<> to std::vector<> */
> > +                     /* Note: this creates copies */
> > +                     std::vector<FrameBuffer::Plane> v(self.planes().begin(),
> > +                                                       self.planes().end());
> > +                     return v;
> > +             })
> >               .def_property("cookie", &FrameBuffer::cookie, &FrameBuffer::setCookie);
> >  
> >       pyFrameBufferPlane
> 
> -- 
> Regards,
> 
> Laurent Pinchart
Barnabás Pőcze Sept. 16, 2025, 1:43 p.m. UTC | #3
Hi

2025. 09. 16. 15:31 keltezéssel, Stefan Klug írta:
> In commit b8d332cdcc13 ("libcamera: framebuffer: Replace vector with
> span in constructor") the FrameBuffer::planes() function was modified to
> return a Span instead of a vector. This leads to the following runtime
> exception in the python binding:
> 
> TypeError: Unregistered type : libcamera::Span<libcamera::FrameBuffer::Plane const, 18446744073709551615ul>
> 
> Fix that by manually converting the Span to a vector.
> 
> Note: The best solution would be to implement a Span type caster for
> pybind11. But implementing and testing that properly is a bit more
> involved than expected. As we don't need bidirectional mapping, the same
> workaround as for FrameMetadata::planes() was used for now.
> 
> Fixes: b8d332cdcc13 ("libcamera: framebuffer: Replace vector with span in constructor")
> Signed-off-by: Stefan Klug <stefan.klug@ideasonboard.com>
> ---
>   src/py/libcamera/py_main.cpp | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> index 441a70ab4d5e..70245ec78f9a 100644
> --- a/src/py/libcamera/py_main.cpp
> +++ b/src/py/libcamera/py_main.cpp
> @@ -372,7 +372,13 @@ PYBIND11_MODULE(_libcamera, m)
>   		.def(py::init<std::vector<FrameBuffer::Plane>, unsigned int>(),
>   		     py::arg("planes"), py::arg("cookie") = 0)
>   		.def_property_readonly("metadata", &FrameBuffer::metadata, py::return_value_policy::reference_internal)
> -		.def_property_readonly("planes", &FrameBuffer::planes)
> +		.def_property_readonly("planes", [](const FrameBuffer &self) {
> +			/* Convert from Span<> to std::vector<> */
> +			/* Note: this creates copies */
> +			std::vector<FrameBuffer::Plane> v(self.planes().begin(),
> +							  self.planes().end());

Could we make it so that `self.planes()` is called only once?

Reviewed-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>


Regards,
Barnabás Pőcze


> +			return v;
> +		})
>   		.def_property("cookie", &FrameBuffer::cookie, &FrameBuffer::setCookie);
>   
>   	pyFrameBufferPlane

Patch
diff mbox series

diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
index 441a70ab4d5e..70245ec78f9a 100644
--- a/src/py/libcamera/py_main.cpp
+++ b/src/py/libcamera/py_main.cpp
@@ -372,7 +372,13 @@  PYBIND11_MODULE(_libcamera, m)
 		.def(py::init<std::vector<FrameBuffer::Plane>, unsigned int>(),
 		     py::arg("planes"), py::arg("cookie") = 0)
 		.def_property_readonly("metadata", &FrameBuffer::metadata, py::return_value_policy::reference_internal)
-		.def_property_readonly("planes", &FrameBuffer::planes)
+		.def_property_readonly("planes", [](const FrameBuffer &self) {
+			/* Convert from Span<> to std::vector<> */
+			/* Note: this creates copies */
+			std::vector<FrameBuffer::Plane> v(self.planes().begin(),
+							  self.planes().end());
+			return v;
+		})
 		.def_property("cookie", &FrameBuffer::cookie, &FrameBuffer::setCookie);
 
 	pyFrameBufferPlane