libcamera: pipeline_handler: add PipelineHandler class
Provide a PipelineHandler which represents a handler for one or more media devices and provides one or more cameras. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
This commit is contained in:
parent
01107c2490
commit
7f8ef1bb99
3 changed files with 206 additions and 0 deletions
62
src/libcamera/include/pipeline_handler.h
Normal file
62
src/libcamera/include/pipeline_handler.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2018, Google Inc.
|
||||
*
|
||||
* pipeline_handler.h - Pipeline handler infrastructure
|
||||
*/
|
||||
#ifndef __LIBCAMERA_PIPELINE_HANDLER_H__
|
||||
#define __LIBCAMERA_PIPELINE_HANDLER_H__
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <libcamera/camera.h>
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
class DeviceEnumerator;
|
||||
class PipelineHandlerFactory;
|
||||
|
||||
class PipelineHandler
|
||||
{
|
||||
public:
|
||||
virtual ~PipelineHandler() { };
|
||||
|
||||
virtual bool match(DeviceEnumerator *enumerator) = 0;
|
||||
|
||||
virtual unsigned int count() = 0;
|
||||
virtual Camera *camera(unsigned int id) = 0;
|
||||
};
|
||||
|
||||
class PipelineHandlerFactory
|
||||
{
|
||||
public:
|
||||
virtual ~PipelineHandlerFactory() { };
|
||||
|
||||
virtual PipelineHandler *create() = 0;
|
||||
|
||||
static void registerType(const std::string &name, PipelineHandlerFactory *factory);
|
||||
static PipelineHandler *create(const std::string &name, DeviceEnumerator *enumerator);
|
||||
static std::vector<std::string> handlers();
|
||||
|
||||
private:
|
||||
static std::map<std::string, PipelineHandlerFactory *> ®istry();
|
||||
};
|
||||
|
||||
#define REGISTER_PIPELINE_HANDLER(handler) \
|
||||
class handler##Factory : public PipelineHandlerFactory { \
|
||||
public: \
|
||||
handler##Factory() \
|
||||
{ \
|
||||
PipelineHandlerFactory::registerType(#handler, this); \
|
||||
} \
|
||||
virtual PipelineHandler *create() { \
|
||||
return new handler(); \
|
||||
} \
|
||||
}; \
|
||||
static handler##Factory global_##handler##Factory;
|
||||
|
||||
} /* namespace libcamera */
|
||||
|
||||
#endif /* __LIBCAMERA_PIPELINE_HANDLER_H__ */
|
|
@ -3,11 +3,13 @@ libcamera_sources = files([
|
|||
'device_enumerator.cpp',
|
||||
'log.cpp',
|
||||
'main.cpp',
|
||||
'pipeline_handler.cpp',
|
||||
])
|
||||
|
||||
libcamera_headers = files([
|
||||
'include/device_enumerator.h',
|
||||
'include/log.h',
|
||||
'include/pipeline_handler.h',
|
||||
'include/utils.h',
|
||||
])
|
||||
|
||||
|
|
142
src/libcamera/pipeline_handler.cpp
Normal file
142
src/libcamera/pipeline_handler.cpp
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
/*
|
||||
* Copyright (C) 2018, Google Inc.
|
||||
*
|
||||
* pipeline_handler.cpp - Pipeline handler infrastructure
|
||||
*/
|
||||
|
||||
#include "device_enumerator.h"
|
||||
#include "log.h"
|
||||
#include "pipeline_handler.h"
|
||||
|
||||
/**
|
||||
* \file pipeline_handler.h
|
||||
* \brief Create pipelines and cameras from one or more media devices
|
||||
*
|
||||
* Each pipeline supported by libcamera needs to be backed by a pipeline
|
||||
* handler implementation which describes the one or many media devices
|
||||
* needed for a pipeline to function properly.
|
||||
*
|
||||
* The pipeline handler is responsible for providing a description of the
|
||||
* media devices it requires to operate. Once all media devices can be
|
||||
* provided the pipeline handler can acquire them and create camera
|
||||
* devices that utilize the acquired media devices.
|
||||
*
|
||||
* To make it a bit less bit complicated to write pipe line handlers a
|
||||
* macro REGISTER_PIPELINE_HANDLER() is provided which allows a pipeline
|
||||
* handler implementation to register itself with the library with ease.
|
||||
*/
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
/**
|
||||
* \class PipelineHandler
|
||||
* \brief Find a set of media devices and provide cameras
|
||||
*
|
||||
* The responsibility of a PipelineHandler is to describe all media
|
||||
* devices it would need in order to provide cameras to the system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \class PipelineHandlerFactory
|
||||
* \brief Keep a registry and create instances of available pipeline handlers
|
||||
*
|
||||
* The responsibility of the PipelineHandlerFactory is to keep a list
|
||||
* of all pipelines in the system. Each pipeline handler should register
|
||||
* it self with the factory using the REGISTER_PIPELINE_HANDLER() macro.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Add a pipeline handler to the global list
|
||||
*
|
||||
* \param[in] name Name of the pipeline handler to add
|
||||
* \param[in] factory Factory to use to construct the pipeline
|
||||
*
|
||||
* The caller is responsible to guarantee the uniqueness of the pipeline name.
|
||||
*/
|
||||
void PipelineHandlerFactory::registerType(const std::string &name,
|
||||
PipelineHandlerFactory *factory)
|
||||
{
|
||||
std::map<std::string, PipelineHandlerFactory *> &factories = registry();
|
||||
|
||||
if (factories.count(name)) {
|
||||
LOG(Error) << "Registering '" << name << "' pipeline twice";
|
||||
return;
|
||||
}
|
||||
|
||||
factories[name] = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Create a new pipeline handler and try to match the media devices it requires
|
||||
*
|
||||
* \param[in] name Name of the pipeline handler to try
|
||||
* \param[in] enumerator Device enumerator to search for a match for the handler
|
||||
*
|
||||
* Try to match the media devices pipeline \a name requires against the ones
|
||||
* registered in \a enumerator.
|
||||
*
|
||||
* \return Pipeline handler if a match was found, nullptr otherwise
|
||||
*/
|
||||
PipelineHandler *PipelineHandlerFactory::create(const std::string &name,
|
||||
DeviceEnumerator *enumerator)
|
||||
{
|
||||
std::map<std::string, PipelineHandlerFactory *> &factories = registry();
|
||||
|
||||
auto it = factories.find(name);
|
||||
if (it == factories.end()) {
|
||||
LOG(Error) << "Trying to create non-existing pipeline handler "
|
||||
<< name;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PipelineHandler *pipe = it->second->create();
|
||||
|
||||
if (pipe->match(enumerator))
|
||||
return pipe;
|
||||
|
||||
delete pipe;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief List all names of piepline handlers from the global list
|
||||
*
|
||||
* \return List of registerd pipeline handler names
|
||||
*/
|
||||
std::vector<std::string> PipelineHandlerFactory::handlers()
|
||||
{
|
||||
std::map<std::string, PipelineHandlerFactory *> &factories = registry();
|
||||
std::vector<std::string> handlers;
|
||||
|
||||
for (auto const &handler : factories)
|
||||
handlers.push_back(handler.first);
|
||||
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Static global list of pipeline handlers
|
||||
*
|
||||
* The static factories map is defined inside the function to ensures it gets
|
||||
* initialized on first use, without any dependency on link order.
|
||||
*
|
||||
* \return Global list of pipeline handlers
|
||||
*/
|
||||
std::map<std::string, PipelineHandlerFactory *> &PipelineHandlerFactory::registry()
|
||||
{
|
||||
static std::map<std::string, PipelineHandlerFactory *> factories;
|
||||
return factories;
|
||||
}
|
||||
|
||||
/**
|
||||
* \def REGISTER_PIPELINE_HANDLER
|
||||
* \brief Register a pipeline handler with the global list
|
||||
*
|
||||
* \param[in] handler Class name of PipelineHandler derived class to register
|
||||
*
|
||||
* Register a specific pipeline handler with the global list and make it
|
||||
* available to try and match devices.
|
||||
*/
|
||||
|
||||
} /* namespace libcamera */
|
Loading…
Add table
Add a link
Reference in a new issue