@@ -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_;
@@ -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;
@@ -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
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(-)