On Mon May 26 19:28:39 2025 -0400, Richard Acayan wrote:
> The libcamera plugin for Pipewire may keep an open file descriptor to
> the video device, even while streaming. This simplifies its operation,
> as it only needs to keep track of a number instead of a file path. When
> the video device is open but not streaming, the pipeline can be powered
> off. Move the pipeline power management to the prepare_streaming and
> unprepare_streaming functions.
> 
> Signed-off-by: Richard Acayan <mailingrad...@gmail.com>
> Reviewed-by: Bryan O'Donoghue <bryan.odonog...@linaro.org>
> Tested-by: Bryan O'Donoghue <bryan.odonog...@linaro.org>
> Reviewed-by: Vladimir Zapolskiy <vladimir.zapols...@linaro.org>
> Signed-off-by: Bryan O'Donoghue <b...@kernel.org>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/qcom/camss/camss-video.c | 39 ++++++++++++++++---------
 1 file changed, 25 insertions(+), 14 deletions(-)

---

diff --git a/drivers/media/platform/qcom/camss/camss-video.c 
b/drivers/media/platform/qcom/camss/camss-video.c
index aa021fd5e123..8d05802d1735 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -225,6 +225,21 @@ static int video_check_format(struct camss_video *video)
        return 0;
 }
 
+static int video_prepare_streaming(struct vb2_queue *q)
+{
+       struct camss_video *video = vb2_get_drv_priv(q);
+       struct video_device *vdev = &video->vdev;
+       int ret;
+
+       ret = v4l2_pipeline_pm_get(&vdev->entity);
+       if (ret < 0) {
+               dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
+                       ret);
+       }
+
+       return ret;
+}
+
 static int video_start_streaming(struct vb2_queue *q, unsigned int count)
 {
        struct camss_video *video = vb2_get_drv_priv(q);
@@ -308,13 +323,23 @@ static void video_stop_streaming(struct vb2_queue *q)
        video->ops->flush_buffers(video, VB2_BUF_STATE_ERROR);
 }
 
+static void video_unprepare_streaming(struct vb2_queue *q)
+{
+       struct camss_video *video = vb2_get_drv_priv(q);
+       struct video_device *vdev = &video->vdev;
+
+       v4l2_pipeline_pm_put(&vdev->entity);
+}
+
 static const struct vb2_ops msm_video_vb2_q_ops = {
        .queue_setup     = video_queue_setup,
        .buf_init        = video_buf_init,
        .buf_prepare     = video_buf_prepare,
        .buf_queue       = video_buf_queue,
+       .prepare_streaming = video_prepare_streaming,
        .start_streaming = video_start_streaming,
        .stop_streaming  = video_stop_streaming,
+       .unprepare_streaming = video_unprepare_streaming,
 };
 
 /* 
-----------------------------------------------------------------------------
@@ -599,20 +624,10 @@ static int video_open(struct file *file)
 
        file->private_data = vfh;
 
-       ret = v4l2_pipeline_pm_get(&vdev->entity);
-       if (ret < 0) {
-               dev_err(video->camss->dev, "Failed to power up pipeline: %d\n",
-                       ret);
-               goto error_pm_use;
-       }
-
        mutex_unlock(&video->lock);
 
        return 0;
 
-error_pm_use:
-       v4l2_fh_release(file);
-
 error_alloc:
        mutex_unlock(&video->lock);
 
@@ -621,12 +636,8 @@ error_alloc:
 
 static int video_release(struct file *file)
 {
-       struct video_device *vdev = video_devdata(file);
-
        vb2_fop_release(file);
 
-       v4l2_pipeline_pm_put(&vdev->entity);
-
        file->private_data = NULL;
 
        return 0;

Reply via email to