From d258025da7d7d555f9aa11dba700cf52409b6759 Mon Sep 17 00:00:00 2001 From: Julien Vuillaumier Date: Fri, 3 May 2024 16:49:19 +0200 Subject: 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="[,[,...]]]" Example: LIBCAMERA_PIPELINES_MATCH_LIST="rkisp1,simple" Signed-off-by: Julien Vuillaumier Reviewed-by: Jacopo Mondi Reviewed-by: Kieran Bingham Signed-off-by: Kieran Bingham --- Documentation/environment_variables.rst | 8 +++++ include/libcamera/internal/camera_manager.h | 1 + src/libcamera/camera_manager.cpp | 53 ++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/Documentation/environment_variables.rst b/Documentation/environment_variables.rst index a9b230bc..4e9fbb27 100644 --- a/Documentation/environment_variables.rst +++ b/Documentation/environment_variables.rst @@ -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. diff --git a/include/libcamera/internal/camera_manager.h b/include/libcamera/internal/camera_manager.h index 7debed25..af9ed60a 100644 --- a/include/libcamera/internal/camera_manager.h +++ b/include/libcamera/internal/camera_manager.h @@ -44,6 +44,7 @@ protected: private: int init(); void createPipelineHandlers(); + void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory); void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_); /* diff --git a/src/libcamera/camera_manager.cpp b/src/libcamera/camera_manager.cpp index 8837e6f8..95a9e326 100644 --- a/src/libcamera/camera_manager.cpp +++ b/src/libcamera/camera_manager.cpp @@ -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 &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 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 pipe = factory->create(o); + if (!pipe->match(enumerator_.get())) + break; + + LOG(Camera, Debug) + << "Pipeline handler \"" << factory->name() + << "\" matched"; } } -- cgit v1.2.1