mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 07:19:45 +03:00
pipeline_handler: Add acquireDevice() function to mirror releaseDevice()
libcamera always keeps all /dev/video# and /dev/v4l2_subdev# nodes for a pipeline open after enumerating the camera. This is a problem for the uvcvideo pipeline handler. Keeping /dev/video# open stops the UVC USB device from being able to enter runtime-suspend causing significant unnecessary power-usage. Add a stub acquireDevice() function to the PipelineHandler class which pipeline handlers can override. The uvcvideo pipeline handler will use this to delay opening /dev/video# until the device is acquired. This is a special case because the kernel uvcvideo driver powers on the USB device as soon as /dev/video# is opened. This behavior should *not* be copied by other pipeline handlers. Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Harvey Yang <chenghaoyang@chromium.org> Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
9020c2eec9
commit
c05e45ac77
3 changed files with 43 additions and 10 deletions
|
@ -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_;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -163,21 +163,25 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!acquireDevice(camera)) {
|
||||
if (useCount_ == 0)
|
||||
unlockMediaDevices();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
++useCount_;
|
||||
return true;
|
||||
|
@ -213,12 +217,40 @@ void PipelineHandler::release(Camera *camera)
|
|||
--useCount_;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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 get resources such as opening
|
||||
* devices and allocating buffers when a camera is acquired.
|
||||
*
|
||||
* This is used by the uvcvideo pipeline handler to delay opening /dev/video#
|
||||
* until the camera is acquired to avoid excess power consumption. The delayed
|
||||
* opening of /dev/video# is a special case because the kernel uvcvideo driver
|
||||
* powers on the USB device as soon as /dev/video# is opened. This behavior
|
||||
* should *not* be copied by other pipeline handlers.
|
||||
*
|
||||
* \return True on success, false on failure
|
||||
* \sa releaseDevice()
|
||||
*/
|
||||
bool PipelineHandler::acquireDevice([[maybe_unused]] Camera *camera)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Release resources associated with this camera
|
||||
* \param[in] camera The camera for which to release resources
|
||||
*
|
||||
* Pipeline handlers may override this in order to perform cleanup operations
|
||||
* when a camera is released, such as freeing memory.
|
||||
*
|
||||
* This is called once for every camera that is released. If there are resources
|
||||
* shared by multiple cameras then the pipeline handler must take care to not
|
||||
* release them until releaseDevice() has been called for all previously
|
||||
* acquired cameras.
|
||||
*
|
||||
* \sa acquireDevice()
|
||||
*/
|
||||
void PipelineHandler::releaseDevice([[maybe_unused]] Camera *camera)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue