libcamera/src/libcamera/pipeline/uvcvideo.cpp
Niklas Söderlund 607a9d7f56 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>
2019-01-25 01:59:28 +02:00

58 lines
1.1 KiB
C++

/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019, Google Inc.
*
* uvcvideo.cpp - Pipeline handler for uvcvideo devices
*/
#include <libcamera/camera.h>
#include "device_enumerator.h"
#include "media_device.h"
#include "pipeline_handler.h"
namespace libcamera {
class PipelineHandlerUVC : public PipelineHandler
{
public:
PipelineHandlerUVC(CameraManager *manager);
~PipelineHandlerUVC();
bool match(DeviceEnumerator *enumerator);
private:
std::shared_ptr<MediaDevice> dev_;
};
PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)
: PipelineHandler(manager), dev_(nullptr)
{
}
PipelineHandlerUVC::~PipelineHandlerUVC()
{
if (dev_)
dev_->release();
}
bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
{
DeviceMatch dm("uvcvideo");
dev_ = std::move(enumerator->search(dm));
if (!dev_)
return false;
dev_->acquire();
std::shared_ptr<Camera> camera = Camera::create(this, dev_->model());
registerCamera(std::move(camera));
return true;
}
REGISTER_PIPELINE_HANDLER(PipelineHandlerUVC);
} /* namespace libcamera */