@@ -44,7 +44,7 @@ public:
return configuration_;
}
- IPAManager *ipaManager() const { return ipaManager_.get(); }
+ IPAManager *ipaManager();
protected:
void run() override;
@@ -91,11 +91,25 @@ void CameraManager::Private::run()
cleanup();
}
-int CameraManager::Private::init()
+/*
+ * Retrieve the IPA manager, constructing it on first use. IPA modules are
+ * only needed once a camera is initialised, so this defers the module scan
+ * until that point.
+ */
+IPAManager *CameraManager::Private::ipaManager()
{
- CameraManager *const o = LIBCAMERA_O_PTR();
- ipaManager_ = std::make_unique<IPAManager>(*o);
+ ASSERT(Thread::current() == this);
+
+ if (!ipaManager_) {
+ CameraManager *const o = LIBCAMERA_O_PTR();
+ ipaManager_ = std::make_unique<IPAManager>(*o);
+ }
+ return ipaManager_.get();
+}
+
+int CameraManager::Private::init()
+{
enumerator_ = DeviceEnumerator::create();
if (!enumerator_ || enumerator_->enumerate())
return -ENODEV;
@@ -270,8 +284,8 @@ void CameraManager::Private::removeCamera(std::shared_ptr<Camera> camera)
/**
* \fn CameraManager::Private::ipaManager() const
- * \brief Retrieve the IPAManager
- * \context This function is \threadsafe.
+ * \brief Retrieve the IPAManager, constructing it on first use
+ * \context This function shall be called from the CameraManager thread.
* \return The IPAManager for this CameraManager
*/
#endif /* __DOXYGEN_PUBLIC__ */
The IPAManager scans, loads and validates every IPA module on disk, but none of that work is needed until a pipeline handler creates an IPA for a camera. Construct the IPAManager lazily on first access instead of unconditionally during camera manager initialisation. Access is done exclusively through the camera manager thread, so no additional locking is required. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> --- include/libcamera/internal/camera_manager.h | 2 +- src/libcamera/camera_manager.cpp | 24 ++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-)