libcamera: camera: Associate cameras with their pipeline handler
The PipelineHandler which creates a Camera is responsible for serving any operation requested by the user. In order forward the public API calls, the camera needs to store a reference to its pipeline handler. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- Changes since v1: - Create pipeline handlers is shared pointers, make them inherit from std::enable_shared_from_this<> and stored them in shared pointers.
This commit is contained in:
parent
a29b7fc7d5
commit
5b02e03199
9 changed files with 44 additions and 31 deletions
|
@ -12,10 +12,13 @@
|
|||
|
||||
namespace libcamera {
|
||||
|
||||
class PipelineHandler;
|
||||
|
||||
class Camera final
|
||||
{
|
||||
public:
|
||||
static std::shared_ptr<Camera> create(const std::string &name);
|
||||
static std::shared_ptr<Camera> create(PipelineHandler *pipe,
|
||||
const std::string &name);
|
||||
|
||||
Camera(const Camera &) = delete;
|
||||
void operator=(const Camera &) = delete;
|
||||
|
@ -23,9 +26,10 @@ public:
|
|||
const std::string &name() const;
|
||||
|
||||
private:
|
||||
explicit Camera(const std::string &name);
|
||||
Camera(PipelineHandler *pipe, const std::string &name);
|
||||
~Camera();
|
||||
|
||||
std::shared_ptr<PipelineHandler> pipe_;
|
||||
std::string name_;
|
||||
};
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ private:
|
|||
~CameraManager();
|
||||
|
||||
std::unique_ptr<DeviceEnumerator> enumerator_;
|
||||
std::vector<PipelineHandler *> pipes_;
|
||||
std::vector<std::shared_ptr<PipelineHandler>> pipes_;
|
||||
std::vector<std::shared_ptr<Camera>> cameras_;
|
||||
|
||||
std::unique_ptr<EventDispatcher> dispatcher_;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <libcamera/camera.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "pipeline_handler.h"
|
||||
|
||||
/**
|
||||
* \file camera.h
|
||||
|
@ -52,17 +53,20 @@ namespace libcamera {
|
|||
/**
|
||||
* \brief Create a camera instance
|
||||
* \param[in] name The name of the camera device
|
||||
* \param[in] pipe The pipeline handler responsible for the camera device
|
||||
*
|
||||
* The caller is responsible for guaranteeing unicity of the camera name.
|
||||
*
|
||||
* \return A shared pointer to the newly created camera object
|
||||
*/
|
||||
std::shared_ptr<Camera> Camera::create(const std::string &name)
|
||||
std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
|
||||
const std::string &name)
|
||||
{
|
||||
struct Allocator : std::allocator<Camera> {
|
||||
void construct(void *p, const std::string &name)
|
||||
void construct(void *p, PipelineHandler *pipe,
|
||||
const std::string &name)
|
||||
{
|
||||
::new(p) Camera(name);
|
||||
::new(p) Camera(pipe, name);
|
||||
}
|
||||
void destroy(Camera *p)
|
||||
{
|
||||
|
@ -70,7 +74,7 @@ std::shared_ptr<Camera> Camera::create(const std::string &name)
|
|||
}
|
||||
};
|
||||
|
||||
return std::allocate_shared<Camera>(Allocator(), name);
|
||||
return std::allocate_shared<Camera>(Allocator(), pipe, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,8 +87,8 @@ const std::string &Camera::name() const
|
|||
return name_;
|
||||
}
|
||||
|
||||
Camera::Camera(const std::string &name)
|
||||
: name_(name)
|
||||
Camera::Camera(PipelineHandler *pipe, const std::string &name)
|
||||
: pipe_(pipe->shared_from_this()), name_(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -98,16 +98,14 @@ int CameraManager::start()
|
|||
* all pipelines it can provide.
|
||||
*/
|
||||
while (1) {
|
||||
PipelineHandler *pipe = factory->create(this);
|
||||
if (!pipe->match(enumerator_.get())) {
|
||||
delete pipe;
|
||||
std::shared_ptr<PipelineHandler> pipe = factory->create(this);
|
||||
if (!pipe->match(enumerator_.get()))
|
||||
break;
|
||||
}
|
||||
|
||||
LOG(Camera, Debug)
|
||||
<< "Pipeline handler \"" << factory->name()
|
||||
<< "\" matched";
|
||||
pipes_.push_back(pipe);
|
||||
pipes_.push_back(std::move(pipe));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,10 +128,13 @@ void CameraManager::stop()
|
|||
{
|
||||
/* TODO: unregister hot-plug callback here */
|
||||
|
||||
for (PipelineHandler *pipe : pipes_)
|
||||
delete pipe;
|
||||
|
||||
/*
|
||||
* Release all references to cameras and pipeline handlers to ensure
|
||||
* they all get destroyed before the device enumerator deletes the
|
||||
* media devices.
|
||||
*/
|
||||
pipes_.clear();
|
||||
cameras_.clear();
|
||||
|
||||
enumerator_.reset(nullptr);
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define __LIBCAMERA_PIPELINE_HANDLER_H__
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -16,7 +17,7 @@ namespace libcamera {
|
|||
class CameraManager;
|
||||
class DeviceEnumerator;
|
||||
|
||||
class PipelineHandler
|
||||
class PipelineHandler : public std::enable_shared_from_this<PipelineHandler>
|
||||
{
|
||||
public:
|
||||
PipelineHandler(CameraManager *manager);
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
PipelineHandlerFactory(const char *name);
|
||||
virtual ~PipelineHandlerFactory() { };
|
||||
|
||||
virtual PipelineHandler *create(CameraManager *manager) = 0;
|
||||
virtual std::shared_ptr<PipelineHandler> create(CameraManager *manager) = 0;
|
||||
|
||||
const std::string &name() const { return name_; }
|
||||
|
||||
|
@ -50,9 +51,9 @@ class handler##Factory final : public PipelineHandlerFactory \
|
|||
{ \
|
||||
public: \
|
||||
handler##Factory() : PipelineHandlerFactory(#handler) {} \
|
||||
PipelineHandler *create(CameraManager *manager) \
|
||||
std::shared_ptr<PipelineHandler> create(CameraManager *manager) \
|
||||
{ \
|
||||
return new handler(manager); \
|
||||
return std::make_shared<handler>(manager); \
|
||||
} \
|
||||
}; \
|
||||
static handler##Factory global_##handler##Factory;
|
||||
|
|
|
@ -171,7 +171,7 @@ void PipelineHandlerIPU3::registerCameras()
|
|||
continue;
|
||||
|
||||
std::string cameraName = sensor->name() + " " + std::to_string(id);
|
||||
std::shared_ptr<Camera> camera = Camera::create(cameraName);
|
||||
std::shared_ptr<Camera> camera = Camera::create(this, cameraName);
|
||||
manager_->addCamera(std::move(camera));
|
||||
|
||||
LOG(IPU3, Info)
|
||||
|
|
|
@ -48,7 +48,7 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
|
|||
|
||||
dev_->acquire();
|
||||
|
||||
std::shared_ptr<Camera> camera = Camera::create(dev_->model());
|
||||
std::shared_ptr<Camera> camera = Camera::create(this, dev_->model());
|
||||
manager_->addCamera(std::move(camera));
|
||||
|
||||
return true;
|
||||
|
|
|
@ -57,14 +57,7 @@ bool PipeHandlerVimc::match(DeviceEnumerator *enumerator)
|
|||
|
||||
dev_->acquire();
|
||||
|
||||
/*
|
||||
* NOTE: A more complete Camera implementation could
|
||||
* be passed the MediaDevice(s) it controls here or
|
||||
* a reference to the PipelineHandler. Which method
|
||||
* will be chosen depends on how the Camera
|
||||
* object is modeled.
|
||||
*/
|
||||
std::shared_ptr<Camera> camera = Camera::create("Dummy VIMC Camera");
|
||||
std::shared_ptr<Camera> camera = Camera::create(this, "Dummy VIMC Camera");
|
||||
manager_->addCamera(std::move(camera));
|
||||
|
||||
return true;
|
||||
|
|
|
@ -32,11 +32,21 @@ LOG_DEFINE_CATEGORY(Pipeline)
|
|||
*
|
||||
* The PipelineHandler matches the media devices provided by a DeviceEnumerator
|
||||
* with the pipelines it supports and creates corresponding Camera devices.
|
||||
*
|
||||
* Pipeline handler instances are reference-counted through std::shared_ptr<>.
|
||||
* They implement std::enable_shared_from_this<> in order to create new
|
||||
* std::shared_ptr<> in code paths originating from member functions of the
|
||||
* PipelineHandler class where only the 'this' pointer is available.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Construct a PipelineHandler instance
|
||||
* \param[in] manager The camera manager
|
||||
*
|
||||
* In order to honour the std::enable_shared_from_this<> contract,
|
||||
* PipelineHandler instances shall never be constructed manually, but always
|
||||
* through the PipelineHandlerFactory::create() method implemented by the
|
||||
* respective factories.
|
||||
*/
|
||||
PipelineHandler::PipelineHandler(CameraManager *manager)
|
||||
: manager_(manager)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue