libcamera: camera_manager: Add environment variable to order pipelines match

To match the enumerated media devices, each registered pipeline handler
is used in no specific order. It is a limitation when several pipelines
can match the devices, and user has to select a specific pipeline.

For this purpose, environment variable LIBCAMERA_PIPELINES_MATCH_LIST is
created to give the option to define an ordered list of pipelines to
match on.

LIBCAMERA_PIPELINES_MATCH_LIST="<name1>[,<name2>[,<name3>...]]]"

Example:
LIBCAMERA_PIPELINES_MATCH_LIST="rkisp1,simple"

Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Julien Vuillaumier 2024-05-03 16:49:19 +02:00 committed by Kieran Bingham
parent 353ccef143
commit d258025da7
3 changed files with 50 additions and 12 deletions

View file

@ -37,6 +37,14 @@ LIBCAMERA_IPA_MODULE_PATH
Example value: ``${HOME}/.libcamera/lib:/opt/libcamera/vendor/lib``
LIBCAMERA_PIPELINES_MATCH_LIST
Define an ordered list of pipeline names to be used to match the media
devices in the system. The pipeline handler names used to populate the
variable are the ones passed to the REGISTER_PIPELINE_HANDLER() macro in the
source code.
Example value: ``rkisp1,simple``
LIBCAMERA_RPI_CONFIG_FILE
Define a custom configuration file to use in the Raspberry Pi pipeline handler.

View file

@ -44,6 +44,7 @@ protected:
private:
int init();
void createPipelineHandlers();
void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory);
void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_);
/*

View file

@ -99,16 +99,37 @@ int CameraManager::Private::init()
void CameraManager::Private::createPipelineHandlers()
{
CameraManager *const o = LIBCAMERA_O_PTR();
/*
* \todo Try to read handlers and order from configuration
* file and only fallback on all handlers if there is no
* configuration file.
* file and only fallback on environment variable or all handlers, if
* there is no configuration file.
*/
const char *pipesList =
utils::secure_getenv("LIBCAMERA_PIPELINES_MATCH_LIST");
if (pipesList) {
/*
* When a list of preferred pipelines is defined, iterate
* through the ordered list to match the enumerated devices.
*/
for (const auto &pipeName : utils::split(pipesList, ",")) {
const PipelineHandlerFactoryBase *factory;
factory = PipelineHandlerFactoryBase::getFactoryByName(pipeName);
if (!factory)
continue;
LOG(Camera, Debug)
<< "Found listed pipeline handler '"
<< pipeName << "'";
pipelineFactoryMatch(factory);
}
return;
}
const std::vector<PipelineHandlerFactoryBase *> &factories =
PipelineHandlerFactoryBase::factories();
/* Match all the registered pipeline handlers. */
for (const PipelineHandlerFactoryBase *factory : factories) {
LOG(Camera, Debug)
<< "Found registered pipeline handler '"
@ -117,15 +138,23 @@ void CameraManager::Private::createPipelineHandlers()
* Try each pipeline handler until it exhaust
* all pipelines it can provide.
*/
while (1) {
std::shared_ptr<PipelineHandler> pipe = factory->create(o);
if (!pipe->match(enumerator_.get()))
break;
pipelineFactoryMatch(factory);
}
}
LOG(Camera, Debug)
<< "Pipeline handler \"" << factory->name()
<< "\" matched";
}
void CameraManager::Private::pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory)
{
CameraManager *const o = LIBCAMERA_O_PTR();
/* Provide as many matching pipelines as possible. */
while (1) {
std::shared_ptr<PipelineHandler> pipe = factory->create(o);
if (!pipe->match(enumerator_.get()))
break;
LOG(Camera, Debug)
<< "Pipeline handler \"" << factory->name()
<< "\" matched";
}
}