[libcamera-devel,1/2] libcamera: pipeline: Add an acquireDevice method
diff mbox series

Message ID 20221116001724.3938045-2-kieran.bingham@ideasonboard.com
State New
Headers show
Series
  • Support resource acquisition at 'acquire()'
Related show

Commit Message

Kieran Bingham Nov. 16, 2022, 12:17 a.m. UTC
Cameras may need to acquire resources such as video device nodes before
they can be configured. Acquisition of these resources can prevent power
saving operations from being handled for instance in the event that a
camera daemon such as Pipewire keeps unacquired devices held at runtime.

Provide a method to allow pipeline handlers to implement resource
acquisition operations during the acquire phase of the Camera state
machine.

Any resources acquired during acquireDevice() must be released as part
of the corresponding releaseDevice() implementation.

Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 include/libcamera/internal/pipeline_handler.h |  3 ++-
 src/libcamera/camera.cpp                      |  2 +-
 src/libcamera/pipeline_handler.cpp            | 23 ++++++++++++++++++-
 3 files changed, 25 insertions(+), 3 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
index ec4f662d7399..483553b0d027 100644
--- a/include/libcamera/internal/pipeline_handler.h
+++ b/include/libcamera/internal/pipeline_handler.h
@@ -45,7 +45,7 @@  public:
 	MediaDevice *acquireMediaDevice(DeviceEnumerator *enumerator,
 					const DeviceMatch &dm);
 
-	bool acquire();
+	bool acquire(Camera *camera);
 	void release(Camera *camera);
 
 	virtual std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
@@ -74,6 +74,7 @@  protected:
 	virtual int queueRequestDevice(Camera *camera, Request *request) = 0;
 	virtual void stopDevice(Camera *camera) = 0;
 
+	virtual bool acquireDevice(Camera *camera);
 	virtual void releaseDevice(Camera *camera);
 
 	CameraManager *manager_;
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 2d947a442bff..4e0a6584a673 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -835,7 +835,7 @@  int Camera::acquire()
 	if (ret < 0)
 		return ret == -EACCES ? -EBUSY : ret;
 
-	if (!d->pipe_->acquire()) {
+	if (!d->pipe_->acquire(this)) {
 		LOG(Camera, Info)
 			<< "Pipeline handler in use by another process";
 		return -EBUSY;
diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp
index cfade4908118..4303a5893a4d 100644
--- a/src/libcamera/pipeline_handler.cpp
+++ b/src/libcamera/pipeline_handler.cpp
@@ -143,6 +143,7 @@  MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,
 
 /**
  * \brief Acquire exclusive access to the pipeline handler for the process
+ * \param[in] camera The camera which is being acquired
  *
  * This function locks all the media devices used by the pipeline to ensure
  * that no other process can access them concurrently.
@@ -155,13 +156,16 @@  MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,
  * Pipeline handlers shall not call this function directly as the Camera class
  * handles access internally.
  *
+ * Any resources acquired during an overridden acquireDevice() must be released
+ * by a corresponding override of releaseDevice().
+ *
  * \context This function is \threadsafe.
  *
  * \return True if the pipeline handler was acquired, false if another process
  * has already acquired it
  * \sa release()
  */
-bool PipelineHandler::acquire()
+bool PipelineHandler::acquire(Camera *camera)
 {
 	MutexLocker locker(lock_);
 
@@ -177,10 +181,27 @@  bool PipelineHandler::acquire()
 		}
 	}
 
+	if (!acquireDevice(camera)) {
+		unlockMediaDevices();
+		return false;
+	}
+
 	++useCount_;
 	return true;
 }
 
+/**
+ * \brief Acquire resources associated with this camera
+ * \param[in] camera The camera for which to acquire resources
+ *
+ * Pipeline handlers may override this in order to perform resource acquisition
+ * operations when a camera is acquired, such as opening device nodes.
+ */
+bool PipelineHandler::acquireDevice([[maybe_unused]] Camera *camera)
+{
+	return true;
+}
+
 /**
  * \brief Release exclusive access to the pipeline handler
  * \param[in] camera The camera for which to release data