diff options
Diffstat (limited to 'src/py/libcamera/py_main.cpp')
-rw-r--r-- | src/py/libcamera/py_main.cpp | 120 |
1 files changed, 26 insertions, 94 deletions
diff --git a/src/py/libcamera/py_main.cpp b/src/py/libcamera/py_main.cpp index e652837f..7e613a3f 100644 --- a/src/py/libcamera/py_main.cpp +++ b/src/py/libcamera/py_main.cpp @@ -7,10 +7,10 @@ #include "py_main.h" -#include <mutex> +#include <memory> #include <stdexcept> -#include <sys/eventfd.h> -#include <unistd.h> +#include <string> +#include <vector> #include <libcamera/base/log.h> @@ -21,6 +21,7 @@ #include <pybind11/stl.h> #include <pybind11/stl_bind.h> +#include "py_camera_manager.h" #include "py_helpers.h" namespace py = pybind11; @@ -33,27 +34,11 @@ LOG_DEFINE_CATEGORY(Python) } -static std::weak_ptr<CameraManager> gCameraManager; -static int gEventfd; -static std::mutex gReqlistMutex; -static std::vector<Request *> gReqList; - -static void handleRequestCompleted(Request *req) -{ - { - std::lock_guard guard(gReqlistMutex); - gReqList.push_back(req); - } - - uint64_t v = 1; - size_t s = write(gEventfd, &v, 8); - /* - * We should never fail, and have no simple means to manage the error, - * so let's log a fatal error. - */ - if (s != 8) - LOG(Python, Fatal) << "Unable to write to eventfd"; -} +/* + * Note: global C++ destructors can be ran on this before the py module is + * destructed. + */ +static std::weak_ptr<PyCameraManager> gCameraManager; void init_py_enums(py::module &m); void init_py_controls_generated(py::module &m); @@ -76,7 +61,7 @@ PYBIND11_MODULE(_libcamera, m) * https://pybind11.readthedocs.io/en/latest/advanced/misc.html#avoiding-c-types-in-docstrings */ - auto pyCameraManager = py::class_<CameraManager>(m, "CameraManager"); + auto pyCameraManager = py::class_<PyCameraManager>(m, "CameraManager"); auto pyCamera = py::class_<Camera>(m, "Camera"); auto pyCameraConfiguration = py::class_<CameraConfiguration>(m, "CameraConfiguration"); auto pyCameraConfigurationStatus = py::enum_<CameraConfiguration::Status>(pyCameraConfiguration, "Status"); @@ -110,78 +95,22 @@ PYBIND11_MODULE(_libcamera, m) /* Classes */ pyCameraManager .def_static("singleton", []() { - std::shared_ptr<CameraManager> cm = gCameraManager.lock(); - if (cm) - return cm; - - int fd = eventfd(0, 0); - if (fd == -1) - throw std::system_error(errno, std::generic_category(), - "Failed to create eventfd"); - - cm = std::shared_ptr<CameraManager>(new CameraManager, [](auto p) { - close(gEventfd); - gEventfd = -1; - delete p; - }); - - gEventfd = fd; - gCameraManager = cm; - - int ret = cm->start(); - if (ret) - throw std::system_error(-ret, std::generic_category(), - "Failed to start CameraManager"); - - return cm; - }) - - .def_property_readonly("version", &CameraManager::version) + std::shared_ptr<PyCameraManager> cm = gCameraManager.lock(); - .def_property_readonly("event_fd", [](CameraManager &) { - return gEventfd; - }) - - .def("get_ready_requests", [](CameraManager &) { - uint8_t buf[8]; - - if (read(gEventfd, buf, 8) != 8) - throw std::system_error(errno, std::generic_category()); - - std::vector<Request *> v; - - { - std::lock_guard guard(gReqlistMutex); - swap(v, gReqList); + if (!cm) { + cm = std::make_shared<PyCameraManager>(); + gCameraManager = cm; } - std::vector<py::object> ret; - - for (Request *req : v) { - py::object o = py::cast(req); - /* Decrease the ref increased in Camera.queue_request() */ - o.dec_ref(); - ret.push_back(o); - } - - return ret; + return cm; }) - .def("get", py::overload_cast<const std::string &>(&CameraManager::get), py::keep_alive<0, 1>()) - - /* Create a list of Cameras, where each camera has a keep-alive to CameraManager */ - .def_property_readonly("cameras", [](CameraManager &self) { - py::list l; - - for (auto &c : self.cameras()) { - py::object py_cm = py::cast(self); - py::object py_cam = py::cast(c); - py::detail::keep_alive_impl(py_cam, py_cm); - l.append(py_cam); - } + .def_property_readonly("version", &PyCameraManager::version) + .def("get", &PyCameraManager::get, py::keep_alive<0, 1>()) + .def_property_readonly("cameras", &PyCameraManager::cameras) - return l; - }); + .def_property_readonly("event_fd", &PyCameraManager::eventFd) + .def("get_ready_requests", &PyCameraManager::getReadyRequests); pyCamera .def_property_readonly("id", &Camera::id) @@ -191,7 +120,10 @@ PYBIND11_MODULE(_libcamera, m) const std::unordered_map<const ControlId *, py::object> &controls) { /* \todo What happens if someone calls start() multiple times? */ - self.requestCompleted.connect(handleRequestCompleted); + auto cm = gCameraManager.lock(); + ASSERT(cm); + + self.requestCompleted.connect(cm.get(), &PyCameraManager::handleRequestCompleted); ControlList controlList(self.controls()); @@ -202,7 +134,7 @@ PYBIND11_MODULE(_libcamera, m) int ret = self.start(&controlList); if (ret) { - self.requestCompleted.disconnect(handleRequestCompleted); + self.requestCompleted.disconnect(); return ret; } @@ -214,7 +146,7 @@ PYBIND11_MODULE(_libcamera, m) if (ret) return ret; - self.requestCompleted.disconnect(handleRequestCompleted); + self.requestCompleted.disconnect(); return 0; }) |