[libcamera-devel] [RFC v1 3/7] py: Move ControlValue helpers to py_helpers.cpp
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Fri Jun 24 14:37:33 CEST 2022
On Fri, Jun 24, 2022 at 09:22:17AM +0100, Kieran Bingham wrote:
> Quoting Tomi Valkeinen (2022-06-23 15:47:32)
> > Clean up the py_main.cpp a bit by moving the ControlValue helpers to a
> > separate file.
> >
> > Signed-off-by: Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > ---
> > src/py/libcamera/meson.build | 1 +
> > src/py/libcamera/py_helpers.cpp | 98 +++++++++++++++++++++++++++++++++
> > src/py/libcamera/py_helpers.h | 13 +++++
> > src/py/libcamera/py_main.cpp | 83 +---------------------------
> > 4 files changed, 114 insertions(+), 81 deletions(-)
> > create mode 100644 src/py/libcamera/py_helpers.cpp
> > create mode 100644 src/py/libcamera/py_helpers.h
> >
> > diff --git a/src/py/libcamera/meson.build b/src/py/libcamera/meson.build
> > index eb884538..04578bac 100644
> > --- a/src/py/libcamera/meson.build
> > +++ b/src/py/libcamera/meson.build
> > @@ -15,6 +15,7 @@ pybind11_dep = pybind11_proj.get_variable('pybind11_dep')
> > pycamera_sources = files([
> > 'py_enums.cpp',
> > 'py_geometry.cpp',
> > + 'py_helpers.cpp',
>
> Should this be called py_controls? Or do you expect other support code
> to go in here too. Or maybe it's more about types, 'py_types' ..
>
> > 'py_main.cpp',
> > ])
> >
> > diff --git a/src/py/libcamera/py_helpers.cpp b/src/py/libcamera/py_helpers.cpp
> > new file mode 100644
> > index 00000000..d0a8b5c4
> > --- /dev/null
> > +++ b/src/py/libcamera/py_helpers.cpp
> > @@ -0,0 +1,98 @@
> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> > +/*
> > + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > + */
> > +
> > +#include "py_helpers.h"
> > +
> > +#include <libcamera/libcamera.h>
> > +
> > +#include <pybind11/functional.h>
> > +#include <pybind11/smart_holder.h>
>
> You have this in the py_helpers header too, so I don't think it needs to
> be duplicated here.
>
> What's it used for? I thought it was just for the Camera destructor or
> something, I don't see Camera used here ?
>
> Anyway, the code move to it's own component file makes sense to me.
>
>
> Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> > +#include <pybind11/stl.h>
> > +#include <pybind11/stl_bind.h>
> > +
> > +namespace py = pybind11;
> > +
> > +using namespace libcamera;
> > +
> > +template<typename T>
> > +static py::object valueOrTuple(const ControlValue &cv)
> > +{
> > + if (cv.isArray()) {
> > + const T *v = reinterpret_cast<const T *>(cv.data().data());
> > + auto t = py::tuple(cv.numElements());
> > +
> > + for (size_t i = 0; i < cv.numElements(); ++i)
> > + t[i] = v[i];
> > +
> > + return std::move(t);
> > + }
> > +
> > + return py::cast(cv.get<T>());
> > +}
> > +
> > +py::object controlValueToPy(const ControlValue &cv)
> > +{
> > + switch (cv.type()) {
> > + case ControlTypeBool:
> > + return valueOrTuple<bool>(cv);
> > + case ControlTypeByte:
> > + return valueOrTuple<uint8_t>(cv);
> > + case ControlTypeInteger32:
> > + return valueOrTuple<int32_t>(cv);
> > + case ControlTypeInteger64:
> > + return valueOrTuple<int64_t>(cv);
> > + case ControlTypeFloat:
> > + return valueOrTuple<float>(cv);
> > + case ControlTypeString:
> > + return py::cast(cv.get<std::string>());
> > + case ControlTypeRectangle: {
> > + const Rectangle *v = reinterpret_cast<const Rectangle *>(cv.data().data());
> > + return py::cast(v);
> > + }
> > + case ControlTypeSize: {
> > + const Size *v = reinterpret_cast<const Size *>(cv.data().data());
> > + return py::cast(v);
> > + }
> > + case ControlTypeNone:
> > + default:
> > + throw std::runtime_error("Unsupported ControlValue type");
> > + }
> > +}
> > +
> > +template<typename T>
> > +static ControlValue controlValueMaybeArray(const py::object &ob)
> > +{
> > + if (py::isinstance<py::list>(ob) || py::isinstance<py::tuple>(ob)) {
> > + std::vector<T> vec = ob.cast<std::vector<T>>();
> > + return ControlValue(Span<const T>(vec));
> > + }
> > +
> > + return ControlValue(ob.cast<T>());
> > +}
> > +
> > +ControlValue pyToControlValue(const py::object &ob, ControlType type)
> > +{
> > + switch (type) {
> > + case ControlTypeBool:
> > + return ControlValue(ob.cast<bool>());
> > + case ControlTypeByte:
> > + return controlValueMaybeArray<uint8_t>(ob);
> > + case ControlTypeInteger32:
> > + return controlValueMaybeArray<int32_t>(ob);
> > + case ControlTypeInteger64:
> > + return controlValueMaybeArray<int64_t>(ob);
> > + case ControlTypeFloat:
> > + return controlValueMaybeArray<float>(ob);
> > + case ControlTypeString:
> > + return ControlValue(ob.cast<std::string>());
> > + case ControlTypeRectangle:
> > + return ControlValue(ob.cast<Rectangle>());
> > + case ControlTypeSize:
> > + return ControlValue(ob.cast<Size>());
> > + case ControlTypeNone:
> > + default:
> > + throw std::runtime_error("Control type not implemented");
> > + }
> > +}
> > diff --git a/src/py/libcamera/py_helpers.h b/src/py/libcamera/py_helpers.h
> > new file mode 100644
> > index 00000000..cd31e2cc
> > --- /dev/null
> > +++ b/src/py/libcamera/py_helpers.h
> > @@ -0,0 +1,13 @@
> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> > +/*
> > + * Copyright (C) 2022, Tomi Valkeinen <tomi.valkeinen at ideasonboard.com>
> > + */
> > +
> > +#pragma once
> > +
> > +#include <libcamera/libcamera.h>
> > +
> > +#include <pybind11/smart_holder.h>
> > +
> > +pybind11::object controlValueToPy(const libcamera::ControlValue &cv);
> > +libcamera::ControlValue pyToControlValue(const pybind11::object &ob, libcamera::ControlType type);
> > diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp
> > index 17b17f60..5a423ece 100644
> > --- a/src/py/libcamera/py_main.cpp
> > +++ b/src/py/libcamera/py_main.cpp
> > @@ -21,93 +21,14 @@
> > #include <pybind11/stl.h>
> > #include <pybind11/stl_bind.h>
> >
> > +#include "py_helpers.h"
> > +
> > namespace py = pybind11;
> >
> > using namespace libcamera;
> >
> > LOG_DEFINE_CATEGORY(Python)
> >
> > -template<typename T>
> > -static py::object valueOrTuple(const ControlValue &cv)
> > -{
> > - if (cv.isArray()) {
> > - const T *v = reinterpret_cast<const T *>(cv.data().data());
> > - auto t = py::tuple(cv.numElements());
> > -
> > - for (size_t i = 0; i < cv.numElements(); ++i)
> > - t[i] = v[i];
> > -
> > - return std::move(t);
> > - }
> > -
> > - return py::cast(cv.get<T>());
> > -}
> > -
> > -static py::object controlValueToPy(const ControlValue &cv)
> > -{
> > - switch (cv.type()) {
> > - case ControlTypeBool:
> > - return valueOrTuple<bool>(cv);
> > - case ControlTypeByte:
> > - return valueOrTuple<uint8_t>(cv);
> > - case ControlTypeInteger32:
> > - return valueOrTuple<int32_t>(cv);
> > - case ControlTypeInteger64:
> > - return valueOrTuple<int64_t>(cv);
> > - case ControlTypeFloat:
> > - return valueOrTuple<float>(cv);
> > - case ControlTypeString:
> > - return py::cast(cv.get<std::string>());
> > - case ControlTypeRectangle: {
> > - const Rectangle *v = reinterpret_cast<const Rectangle *>(cv.data().data());
> > - return py::cast(v);
> > - }
> > - case ControlTypeSize: {
> > - const Size *v = reinterpret_cast<const Size *>(cv.data().data());
> > - return py::cast(v);
> > - }
> > - case ControlTypeNone:
> > - default:
> > - throw std::runtime_error("Unsupported ControlValue type");
> > - }
> > -}
> > -
> > -template<typename T>
> > -static ControlValue controlValueMaybeArray(const py::object &ob)
> > -{
> > - if (py::isinstance<py::list>(ob) || py::isinstance<py::tuple>(ob)) {
> > - std::vector<T> vec = ob.cast<std::vector<T>>();
> > - return ControlValue(Span<const T>(vec));
> > - }
> > -
> > - return ControlValue(ob.cast<T>());
> > -}
> > -
> > -static ControlValue pyToControlValue(const py::object &ob, ControlType type)
> > -{
> > - switch (type) {
> > - case ControlTypeBool:
> > - return ControlValue(ob.cast<bool>());
> > - case ControlTypeByte:
> > - return controlValueMaybeArray<uint8_t>(ob);
> > - case ControlTypeInteger32:
> > - return controlValueMaybeArray<int32_t>(ob);
> > - case ControlTypeInteger64:
> > - return controlValueMaybeArray<int64_t>(ob);
> > - case ControlTypeFloat:
> > - return controlValueMaybeArray<float>(ob);
> > - case ControlTypeString:
> > - return ControlValue(ob.cast<std::string>());
> > - case ControlTypeRectangle:
> > - return ControlValue(ob.cast<Rectangle>());
> > - case ControlTypeSize:
> > - return ControlValue(ob.cast<Size>());
> > - case ControlTypeNone:
> > - default:
> > - throw std::runtime_error("Control type not implemented");
> > - }
> > -}
> > -
> > static std::weak_ptr<CameraManager> gCameraManager;
> > static int gEventfd;
> > static std::mutex gReqlistMutex;
--
Regards,
Laurent Pinchart
More information about the libcamera-devel
mailing list