[libcamera-devel] [RFC v1 3/7] py: Move ControlValue helpers to py_helpers.cpp
Kieran Bingham
kieran.bingham at ideasonboard.com
Fri Jun 24 10:22:17 CEST 2022
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>
> +#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;
> --
> 2.34.1
>
More information about the libcamera-devel
mailing list