@@ -26,6 +26,8 @@ namespace libcamera {
class Camera;
class DeviceEnumerator;
class IPAManager;
+class MediaDevice;
+class PipelineHandler;
class PipelineHandlerFactoryBase;
class CameraManager::Private : public Extensible::Private, public Thread
@@ -53,6 +55,7 @@ private:
int init();
void createPipelineHandlers();
void pipelineFactoryMatch(const PipelineHandlerFactoryBase *factory);
+ std::shared_ptr<PipelineHandler> findMatchingHandler(const MediaDevice *media);
void cleanup() LIBCAMERA_TSA_EXCLUDES(mutex_);
/*
@@ -70,6 +73,12 @@ private:
std::unique_ptr<DeviceEnumerator> enumerator_;
+ /*
+ * Active pipeline handler instances, accessed from the CameraManager
+ * thread only.
+ */
+ std::vector<std::weak_ptr<PipelineHandler>> pipes_;
+
std::unique_ptr<IPAManager> ipaManager_;
const GlobalConfiguration configuration_;
@@ -178,7 +178,37 @@ void CameraManager::Private::pipelineFactoryMatch(const PipelineHandlerFactoryBa
LOG(Camera, Debug)
<< "Pipeline handler \"" << factory->name()
<< "\" matched";
+
+ pipes_.push_back(pipe);
+ }
+}
+
+/*
+ * Find the active pipeline handler instance that has acquired the media device,
+ * if any. Expired entries are pruned from the registry as a side effect. Called
+ * from the CameraManager thread only.
+ */
+std::shared_ptr<PipelineHandler>
+CameraManager::Private::findMatchingHandler(const MediaDevice *media)
+{
+ ASSERT(Thread::current() == this);
+
+ std::shared_ptr<PipelineHandler> match;
+
+ for (auto it = pipes_.begin(); it != pipes_.end();) {
+ std::shared_ptr<PipelineHandler> pipe = it->lock();
+ if (!pipe) {
+ it = pipes_.erase(it);
+ continue;
+ }
+
+ if (!match && pipe->usesMediaDevice(media))
+ match = std::move(pipe);
+
+ ++it;
}
+
+ return match;
}
void CameraManager::Private::cleanup()
The camera manager drops its reference to a pipeline handler as soon as match() returns, leaving the instance owned solely by the Camera object. Store a vector of weak references to matched pipeline handler instances. This will allow camera initialisation from a descriptor to link to an existing pipeline handler instance rather than creating a second instance for media devices that are already acquired. Weak references leave the existing ownership and lifetime model unchanged. Add a findMatchingHandler() helper that returns the active pipeline handler instance that has acquired a given media device, pruning expired references as it goes. This will be used in a future commit. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> --- include/libcamera/internal/camera_manager.h | 9 +++++++ src/libcamera/camera_manager.cpp | 30 +++++++++++++++++++++ 2 files changed, 39 insertions(+)