diff options
-rw-r--r-- | src/gstreamer/gstlibcamera-utils.cpp | 24 | ||||
-rw-r--r-- | src/gstreamer/gstlibcamera-utils.h | 6 | ||||
-rw-r--r-- | src/gstreamer/gstlibcameraprovider.cpp | 22 | ||||
-rw-r--r-- | src/gstreamer/gstlibcamerasrc.cpp | 11 |
4 files changed, 35 insertions, 28 deletions
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp index 61370d5f..f7e0e1c8 100644 --- a/src/gstreamer/gstlibcamera-utils.cpp +++ b/src/gstreamer/gstlibcamera-utils.cpp @@ -178,3 +178,27 @@ gst_libcamera_resume_task(GstTask *task) GST_TASK_SIGNAL(task); } } + +G_LOCK_DEFINE_STATIC(cm_singleton_lock); +std::weak_ptr<CameraManager> cm_singleton_ptr; + +std::shared_ptr<CameraManager> +gst_libcamera_get_camera_mananger(int &ret) +{ + std::shared_ptr<CameraManager> cm; + + G_LOCK(cm_singleton_lock); + + cm = cm_singleton_ptr.lock(); + if (!cm) { + cm = std::make_shared<CameraManager>(); + cm_singleton_ptr = cm; + ret = cm->start(); + } else { + ret = 0; + } + + G_UNLOCK(cm_singleton_lock); + + return cm; +} diff --git a/src/gstreamer/gstlibcamera-utils.h b/src/gstreamer/gstlibcamera-utils.h index 2b3f26b6..67a06db3 100644 --- a/src/gstreamer/gstlibcamera-utils.h +++ b/src/gstreamer/gstlibcamera-utils.h @@ -9,16 +9,18 @@ #ifndef __GST_LIBCAMERA_UTILS_H__ #define __GST_LIBCAMERA_UTILS_H__ +#include <libcamera/camera_manager.h> +#include <libcamera/stream.h> + #include <gst/gst.h> #include <gst/video/video.h> -#include <libcamera/stream.h> - GstCaps *gst_libcamera_stream_formats_to_caps(const libcamera::StreamFormats &formats); GstCaps *gst_libcamera_stream_configuration_to_caps(const libcamera::StreamConfiguration &stream_cfg); void gst_libcamera_configure_stream_from_caps(libcamera::StreamConfiguration &stream_cfg, GstCaps *caps); void gst_libcamera_resume_task(GstTask *task); +std::shared_ptr<libcamera::CameraManager> gst_libcamera_get_camera_mananger(int &ret); /** * \class GLibLocker diff --git a/src/gstreamer/gstlibcameraprovider.cpp b/src/gstreamer/gstlibcameraprovider.cpp index 29da6c32..948ba0d1 100644 --- a/src/gstreamer/gstlibcameraprovider.cpp +++ b/src/gstreamer/gstlibcameraprovider.cpp @@ -158,7 +158,6 @@ gst_libcamera_device_new(const std::shared_ptr<Camera> &camera) struct _GstLibcameraProvider { GstDeviceProvider parent; - CameraManager *cm; }; G_DEFINE_TYPE_WITH_CODE(GstLibcameraProvider, gst_libcamera_provider, @@ -170,7 +169,7 @@ static GList * gst_libcamera_provider_probe(GstDeviceProvider *provider) { GstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(provider); - CameraManager *cm = self->cm; + std::shared_ptr<CameraManager> cm; GList *devices = nullptr; gint ret; @@ -181,7 +180,7 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider) * gains monitoring support. Meanwhile we need to cycle start()/stop() * to ensure every probe() calls return the latest list. */ - ret = cm->start(); + cm = gst_libcamera_get_camera_mananger(ret); if (ret) { GST_ERROR_OBJECT(self, "Failed to retrieve device list: %s", g_strerror(-ret)); @@ -194,8 +193,6 @@ gst_libcamera_provider_probe(GstDeviceProvider *provider) g_object_ref_sink(gst_libcamera_device_new(camera))); } - cm->stop(); - return devices; } @@ -204,31 +201,16 @@ gst_libcamera_provider_init(GstLibcameraProvider *self) { GstDeviceProvider *provider = GST_DEVICE_PROVIDER(self); - self->cm = new CameraManager(); - /* Avoid devices being duplicated. */ gst_device_provider_hide_provider(provider, "v4l2deviceprovider"); } static void -gst_libcamera_provider_finalize(GObject *object) -{ - GstLibcameraProvider *self = GST_LIBCAMERA_PROVIDER(object); - gpointer klass = gst_libcamera_provider_parent_class; - - delete self->cm; - - return G_OBJECT_CLASS(klass)->finalize(object); -} - -static void gst_libcamera_provider_class_init(GstLibcameraProviderClass *klass) { GstDeviceProviderClass *provider_class = GST_DEVICE_PROVIDER_CLASS(klass); - GObjectClass *object_class = G_OBJECT_CLASS(klass); provider_class->probe = gst_libcamera_provider_probe; - object_class->finalize = gst_libcamera_provider_finalize; gst_device_provider_class_set_metadata(provider_class, "libcamera Device Provider", diff --git a/src/gstreamer/gstlibcamerasrc.cpp b/src/gstreamer/gstlibcamerasrc.cpp index b243aeb3..512fbbc1 100644 --- a/src/gstreamer/gstlibcamerasrc.cpp +++ b/src/gstreamer/gstlibcamerasrc.cpp @@ -108,7 +108,7 @@ GstBuffer *RequestWrap::detachBuffer(Stream *stream) struct GstLibcameraSrcState { GstLibcameraSrc *src_; - std::unique_ptr<CameraManager> cm_; + std::shared_ptr<CameraManager> cm_; std::shared_ptr<Camera> cam_; std::unique_ptr<CameraConfiguration> config_; std::vector<GstPad *> srcpads_; @@ -202,13 +202,13 @@ GstLibcameraSrcState::requestCompleted(Request *request) static bool gst_libcamera_src_open(GstLibcameraSrc *self) { - std::unique_ptr<CameraManager> cm = std::make_unique<CameraManager>(); + std::shared_ptr<CameraManager> cm; std::shared_ptr<Camera> cam; - gint ret = 0; + gint ret; GST_DEBUG_OBJECT(self, "Opening camera device ..."); - ret = cm->start(); + cm = gst_libcamera_get_camera_mananger(ret); if (ret) { GST_ELEMENT_ERROR(self, LIBRARY, INIT, ("Failed listing cameras."), @@ -254,7 +254,7 @@ gst_libcamera_src_open(GstLibcameraSrc *self) cam->requestCompleted.connect(self->state, &GstLibcameraSrcState::requestCompleted); /* No need to lock here, we didn't start our threads yet. */ - self->state->cm_ = std::move(cm); + self->state->cm_ = cm; self->state->cam_ = cam; return true; @@ -521,7 +521,6 @@ gst_libcamera_src_close(GstLibcameraSrc *self) } state->cam_.reset(); - state->cm_->stop(); state->cm_.reset(); } |