[PATCH 3/5] pipeline_handler: Add acquireDevice() method to mirror existing releaseDevice()
Hans de Goede
hdegoede at redhat.com
Tue Aug 27 16:11:47 CEST 2024
Hi,
On 8/21/24 6:55 PM, Cheng-Hao Yang wrote:
> Hi Hans,
>
> Thanks for the patch. Actually in mtkisp7, we did something very similar [1].
> (And I just caught a bug by checking your changes. Thanks :)
>
> [1]: https://chromium-review.googlesource.com/c/chromiumos/third_party/libcamera/+/5525900 <https://chromium-review.googlesource.com/c/chromiumos/third_party/libcamera/+/5525900>
>
> On Tue, Aug 20, 2024 at 9:50 PM Hans de Goede <hdegoede at redhat.com <mailto:hdegoede at redhat.com>> wrote:
>
> ATM libcamera always keeps all /dev/video# and /dev/v4l2_subdev# nodes
> for a pipeline open after enumerating the camera.
>
> This is a problem for uvcvideo and atomisp /dev/video# nodes as well as
> for VCM /dev/v4l2_subdev# nodes. Keeping these open stops the underlying
> hw-devices from being able to enter runtime-suspend causing significant
> unnecessary power-usage.
>
> Add a stub acquireDevice() method to the PipelineHandler class which
> pipeline handlers can override to delay opening /dev nodes until
> the camera is acquired.
>
> Note pipeline handlers typically also will need access to /dev nodes
> for their CameraConfig::validate() implementation for tryFormat() calls.
> Making sure that /dev nodes are opened as necessary from validate() is
> left up to the pipeline handler implementation.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com <mailto:hdegoede at redhat.com>>
> ---
> include/libcamera/internal/pipeline_handler.h | 3 +-
> src/libcamera/camera.cpp | 2 +-
> src/libcamera/pipeline_handler.cpp | 43 +++++++++++++++----
> 3 files changed, 37 insertions(+), 11 deletions(-)
>
> diff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h
> index cad5812f..597f7c3e 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,
> @@ -79,6 +79,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 382a68f7..4e393f89 100644
> --- a/src/libcamera/camera.cpp
> +++ b/src/libcamera/camera.cpp
> @@ -995,7 +995,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 1fc22d6a..e1342306 100644
> --- a/src/libcamera/pipeline_handler.cpp
> +++ b/src/libcamera/pipeline_handler.cpp
> @@ -163,20 +163,22 @@ MediaDevice *PipelineHandler::acquireMediaDevice(DeviceEnumerator *enumerator,
> * has already acquired it
> * \sa release()
> */
> -bool PipelineHandler::acquire()
> +bool PipelineHandler::acquire(Camera *camera)
> {
> MutexLocker locker(lock_);
>
> - if (useCount_) {
> - ++useCount_;
> - return true;
> + if (useCount_ == 0) {
> + for (std::shared_ptr<MediaDevice> &media : mediaDevices_) {
> + if (!media->lock()) {
> + unlockMediaDevices();
> + return false;
> + }
> + }
> }
>
> - for (std::shared_ptr<MediaDevice> &media : mediaDevices_) {
> - if (!media->lock()) {
> - unlockMediaDevices();
> - return false;
> - }
> + if (!acquireDevice(camera)) {
> + unlockMediaDevices();
>
>
> I think we should only unlock media devices if it's the first acquire
> being called, as there might be other ongoing usages on other
> cameras [2]. Therefore:
> ```
> if (useCount_ == 0)
> unlockMediaDevices();
> ```
Good point, fixed for v2.
Regards,
Hans
More information about the libcamera-devel
mailing list