[libcamera-devel] [PATCH v2] py: Add the SensorConfiguration class

David Plowman david.plowman at raspberrypi.com
Fri Oct 20 10:17:08 CEST 2023


Hi Tomi

Thanks for that. I had no idea you could write that... the joys of C++!

Would folks like me to send another update?

David

On Fri, 20 Oct 2023 at 08:51, Tomi Valkeinen
<tomi.valkeinen at ideasonboard.com> wrote:
>
> On 12/10/2023 11:29, Kieran Bingham via libcamera-devel wrote:
> > Hi David,
> >
> > Quoting David Plowman via libcamera-devel (2023-10-11 15:02:38)
> >> We provide access to the various fields of the new SensorConfiguration
> >> class. The class also needs a constructor so that Python applications
> >> can make one and put it into the CameraConfiguration.
> >>
> >> Signed-off-by: David Plowman <david.plowman at raspberrypi.com>
> >> ---
> >>   src/py/libcamera/py_main.cpp | 36 ++++++++++++++++++++++++++++++++++++
> >>   1 file changed, 36 insertions(+)
> >>
> >> diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> >> index 01fb15a9..d2ce3722 100644
> >> --- a/src/py/libcamera/py_main.cpp
> >> +++ b/src/py/libcamera/py_main.cpp
> >> @@ -112,6 +112,7 @@ PYBIND11_MODULE(_libcamera, m)
> >>
> >>          auto pyCameraManager = py::class_<PyCameraManager, std::shared_ptr<PyCameraManager>>(m, "CameraManager");
> >>          auto pyCamera = py::class_<Camera, PyCameraSmartPtr<Camera>>(m, "Camera");
> >> +       auto pySensorConfiguration = py::class_<SensorConfiguration>(m, "SensorConfiguration");
> >>          auto pyCameraConfiguration = py::class_<CameraConfiguration>(m, "CameraConfiguration");
> >>          auto pyCameraConfigurationStatus = py::enum_<CameraConfiguration::Status>(pyCameraConfiguration, "Status");
> >>          auto pyStreamConfiguration = py::class_<StreamConfiguration>(m, "StreamConfiguration");
> >> @@ -281,6 +282,40 @@ PYBIND11_MODULE(_libcamera, m)
> >>                          return ret;
> >>                  });
> >>
> >> +       pySensorConfiguration
> >> +               .def(py::init<>())
> >> +               .def_readwrite("bit_depth", &SensorConfiguration::bitDepth)
> >> +               .def_readwrite("analog_crop", &SensorConfiguration::analogCrop)
> >> +               .def_property(
> >> +                       "binning",
> >> +                       [](SensorConfiguration &self) {
> >> +                               return py::make_tuple(self.binning.binX, self.binning.binY);
> >> +                       },
> >> +                       [](SensorConfiguration &self, py::object value) {
> >> +                               auto vec = value.cast<std::vector<unsigned int>>();
> >> +                               if (vec.size() != 2)
> >> +                                       throw std::runtime_error("binning requires iterable of 2 values");
> >> +                               self.binning.binX = vec[0];
> >> +                               self.binning.binY = vec[1];
> >
> > This seems reasonable to me. Partially filling in either of binning or
> > skipping would be invalid.
> >
> > Thanks for filling in the rest of the logic:
> >
> > Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
> >
> > Tomi - Are you happy with this?
>
> I think it's simpler and better to do:
>
> .def_property(
>         "binning",
>         [](SensorConfiguration &self) {
>                 return std::make_tuple(self.binning.binX, self.binning.binY);
>         },
>         [](SensorConfiguration &self, std::tuple<uint32_t, uint32_t> value) {
>                 self.binning.binX = std::get<0>(value);
>                 self.binning.binY = std::get<1>(value);
>         })
>
>   Tomi
>
>
> >
> >
> >
> >> +                       })
> >> +               .def_property(
> >> +                       "skipping",
> >> +                       [](SensorConfiguration &self) {
> >> +                               return py::make_tuple(self.skipping.xOddInc, self.skipping.xEvenInc,
> >> +                                                     self.skipping.yOddInc, self.skipping.yEvenInc);
> >> +                       },
> >> +                       [](SensorConfiguration &self, py::object value) {
> >> +                               auto vec = value.cast<std::vector<unsigned int>>();
> >> +                               if (vec.size() != 4)
> >> +                                       throw std::runtime_error("skipping requires iterable of 4 values");
> >> +                               self.skipping.xOddInc = vec[0];
> >> +                               self.skipping.xEvenInc = vec[1];
> >> +                               self.skipping.yOddInc = vec[2];
> >> +                               self.skipping.yEvenInc = vec[3];
> >> +                       })
> >> +               .def_readwrite("output_size", &SensorConfiguration::outputSize)
> >> +               .def("is_valid", &SensorConfiguration::isValid);
> >> +
> >>          pyCameraConfiguration
> >>                  .def("__iter__", [](CameraConfiguration &self) {
> >>                          return py::make_iterator<py::return_value_policy::reference_internal>(self);
> >> @@ -293,6 +328,7 @@ PYBIND11_MODULE(_libcamera, m)
> >>                       py::return_value_policy::reference_internal)
> >>                  .def_property_readonly("size", &CameraConfiguration::size)
> >>                  .def_property_readonly("empty", &CameraConfiguration::empty)
> >> +               .def_readwrite("sensor_config", &CameraConfiguration::sensorConfig)
> >>                  .def_readwrite("transform", &CameraConfiguration::transform);
> >>
> >>          pyCameraConfigurationStatus
> >> --
> >> 2.39.2
> >>
>


More information about the libcamera-devel mailing list