summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline_handler.cpp
diff options
context:
space:
mode:
authorNiklas Söderlund <niklas.soderlund@ragnatech.se>2019-01-22 16:47:40 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-01-25 01:59:28 +0200
commit607a9d7f5698fa514b66b0f0a53393fb8435ed12 (patch)
tree9d9ee3d111f0d877c9ca08c9a19a2abd5f8e45cf /src/libcamera/pipeline_handler.cpp
parent889726097613ae5ed4d83a6fd0cc3b0b562f8659 (diff)
libcamera: pipeline_handler: Add camera disconnection support
Pipeline handlers are responsible for creating camera instances, but also for destroying them when devices are unplugged. As camera objects are reference-counted this isn't a straightforward operation and involves the camera manager and camera object itself. Add two helper methods in the PipelineHandler base class to register a camera and to register a media device with the pipeline handler. When registering a camera, the registerCamera() helper method will add it to the camera manager. When registering a media device, the registerMediaDevice() helper method will listen to device disconnection events, and disconnect all cameras created by the pipeline handler as a response. Under the hood the PipelineHandler class needs to keep track of registered cameras in order to handle disconnection. They can't be stored as shared pointers as this would create a circular dependency (the Camera class owns a shared pointer to the pipeline handler). Store them as weak pointers instead. This is safe as a reference to the camera is stored in the camera manager, and doesn't get removed until the camera is unregistered from the manager by the PipelineHandler. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/pipeline_handler.cpp')
-rw-r--r--src/libcamera/pipeline_handler.cpp71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index 3850ea8f..23631314 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -5,7 +5,11 @@
* pipeline_handler.cpp - Pipeline handler infrastructure
*/
+#include <libcamera/camera.h>
+#include <libcamera/camera_manager.h>
+
#include "log.h"
+#include "media_device.h"
#include "pipeline_handler.h"
/**
@@ -98,6 +102,73 @@ PipelineHandler::~PipelineHandler()
*/
/**
+ * \brief Register a camera to the camera manager and pipeline handler
+ * \param[in] camera The camera to be added
+ *
+ * This function is called by pipeline handlers to register the cameras they
+ * handle with the camera manager.
+ */
+void PipelineHandler::registerCamera(std::shared_ptr<Camera> camera)
+{
+ cameras_.push_back(camera);
+ manager_->addCamera(std::move(camera));
+}
+
+/**
+ * \brief Enable hotplug handling for a media device
+ * \param[in] media The media device
+ *
+ * This function enables hotplug handling, and especially hot-unplug handling,
+ * of the \a media device. It shall be called by pipeline handlers for all the
+ * media devices that can be disconnected.
+ *
+ * When a media device passed to this function is later unplugged, the pipeline
+ * handler gets notified and automatically disconnects all the cameras it has
+ * registered without requiring any manual intervention.
+ */
+void PipelineHandler::hotplugMediaDevice(MediaDevice *media)
+{
+ media->disconnected.connect(this, &PipelineHandler::mediaDeviceDisconnected);
+}
+
+/**
+ * \brief Device disconnection handler
+ *
+ * This virtual function is called to notify the pipeline handler that the
+ * device it handles has been disconnected. It notifies all cameras created by
+ * the pipeline handler that they have been disconnected, and unregisters them
+ * from the camera manager.
+ *
+ * The function can be overloaded by pipeline handlers to perform custom
+ * operations at disconnection time. Any overloaded version shall call the
+ * PipelineHandler::disconnect() base function for proper hot-unplug operation.
+ */
+void PipelineHandler::disconnect()
+{
+ for (std::weak_ptr<Camera> ptr : cameras_) {
+ std::shared_ptr<Camera> camera = ptr.lock();
+ if (!camera)
+ continue;
+
+ camera->disconnect();
+ manager_->removeCamera(camera.get());
+ }
+
+ cameras_.clear();
+}
+
+/**
+ * \brief Slot for the MediaDevice disconnected signal
+ */
+void PipelineHandler::mediaDeviceDisconnected(MediaDevice *media)
+{
+ if (cameras_.empty())
+ return;
+
+ disconnect();
+}
+
+/**
* \class PipelineHandlerFactory
* \brief Registration of PipelineHandler classes and creation of instances
*