[libcamera-devel,09/15] v4l2: v4l2_cammera_proxy: Reset buffer flags on streamoff when already off

Message ID 20200616131244.70308-10-paul.elder@ideasonboard.com
State Superseded
Headers show
Series
  • Support v4l2-compliance
Related show

Commit Message

Paul Elder June 16, 2020, 1:12 p.m. UTC
If VIDIOC_STREAMOFF is called when the stream is already off, just reset
the buffer status flags and return. Add a streaming flag to
V4L2CameraProxy to track the streaming status.

Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
---
 src/v4l2/v4l2_camera_proxy.cpp | 18 +++++++++++++++++-
 src/v4l2/v4l2_camera_proxy.h   |  1 +
 2 files changed, 18 insertions(+), 1 deletion(-)

Comments

Jacopo Mondi June 17, 2020, 3:07 p.m. UTC | #1
Hi Paul,

On Tue, Jun 16, 2020 at 10:12:38PM +0900, Paul Elder wrote:
> If VIDIOC_STREAMOFF is called when the stream is already off, just reset
> the buffer status flags and return. Add a streaming flag to
> V4L2CameraProxy to track the streaming status.
>
> Signed-off-by: Paul Elder <paul.elder@ideasonboard.com>
> ---
>  src/v4l2/v4l2_camera_proxy.cpp | 18 +++++++++++++++++-
>  src/v4l2/v4l2_camera_proxy.h   |  1 +
>  2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
> index fd2785f..63b4124 100644
> --- a/src/v4l2/v4l2_camera_proxy.cpp
> +++ b/src/v4l2/v4l2_camera_proxy.cpp
> @@ -34,7 +34,8 @@ V4L2CameraProxy::V4L2CameraProxy(unsigned int index,
>  				 std::shared_ptr<Camera> camera)
>  	: refcount_(0), index_(index), bufferCount_(0), currentBuf_(0),
>  	  vcam_(std::make_unique<V4L2Camera>(camera)), efd_(-1),
> -	  v4l2RecordPriorityFd_(-1), acquiredFd_(-1), initialized_(false)
> +	  v4l2RecordPriorityFd_(-1), acquiredFd_(-1), initialized_(false),
> +	  streaming_(false)
>  {
>  	querycap(camera);
>  }
> @@ -628,6 +629,9 @@ int V4L2CameraProxy::vidioc_dqbuf(int fd, struct v4l2_buffer *arg)
>  	if (arg == nullptr)
>  		return -EFAULT;
>
> +	if (!streaming_)

Doesn't this flag replicate the same information stored in
V4L2Camera::isRuning_ ? Why keep two status flags for the same purpose ?

> +		return -EINVAL;
> +
>  	int ret = lock(fd);
>  	if (ret < 0)
>  		return ret;
> @@ -666,6 +670,9 @@ int V4L2CameraProxy::vidioc_streamon(int fd, int *arg)
>  	if (arg == nullptr)
>  		return -EFAULT;
>
> +	if (streaming_)
> +		return 0;
> +
>  	int ret = lock(fd);
>  	if (ret < 0)
>  		return ret;
> @@ -674,6 +681,7 @@ int V4L2CameraProxy::vidioc_streamon(int fd, int *arg)
>  		return -EINVAL;
>
>  	currentBuf_ = 0;
> +	streaming_ = true;
>
>  	return vcam_->streamOn();
>  }
> @@ -685,6 +693,12 @@ int V4L2CameraProxy::vidioc_streamoff(int fd, int *arg)
>  	if (arg == nullptr)
>  		return -EFAULT;
>
> +	if (!streaming_) {
> +		for (unsigned int i = 0; i < bufferCount_; i++)
> +			buffers_[i].flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE);
> +		return 0;
> +	}

Shouldn't this come after the buffer type validation ?
V4L2Camera::streamOff() is already a no-op if isRunning_, so I think
this hunk is not needed.

What's left is preventing calling a few ioctls (dqbuf, streamon) when
the camera is not running. Something which could be done V4L2Camera,
or here by adding an isRunning() function to V4L2Camera.

Thanks
  j

> +
>  	int ret = lock(fd);
>  	if (ret < 0)
>  		return ret;
> @@ -697,6 +711,8 @@ int V4L2CameraProxy::vidioc_streamoff(int fd, int *arg)
>  	for (struct v4l2_buffer &buf : buffers_)
>  		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE);
>
> +	streaming_ = false;
> +
>  	return ret;
>  }
>
> diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
> index 2ff9571..28b2fa0 100644
> --- a/src/v4l2/v4l2_camera_proxy.h
> +++ b/src/v4l2/v4l2_camera_proxy.h
> @@ -103,6 +103,7 @@ private:
>  	int acquiredFd_;
>
>  	bool initialized_;
> +	bool streaming_;
>  };
>
>  #endif /* __V4L2_CAMERA_PROXY_H__ */
> --
> 2.27.0
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/v4l2/v4l2_camera_proxy.cpp b/src/v4l2/v4l2_camera_proxy.cpp
index fd2785f..63b4124 100644
--- a/src/v4l2/v4l2_camera_proxy.cpp
+++ b/src/v4l2/v4l2_camera_proxy.cpp
@@ -34,7 +34,8 @@  V4L2CameraProxy::V4L2CameraProxy(unsigned int index,
 				 std::shared_ptr<Camera> camera)
 	: refcount_(0), index_(index), bufferCount_(0), currentBuf_(0),
 	  vcam_(std::make_unique<V4L2Camera>(camera)), efd_(-1),
-	  v4l2RecordPriorityFd_(-1), acquiredFd_(-1), initialized_(false)
+	  v4l2RecordPriorityFd_(-1), acquiredFd_(-1), initialized_(false),
+	  streaming_(false)
 {
 	querycap(camera);
 }
@@ -628,6 +629,9 @@  int V4L2CameraProxy::vidioc_dqbuf(int fd, struct v4l2_buffer *arg)
 	if (arg == nullptr)
 		return -EFAULT;
 
+	if (!streaming_)
+		return -EINVAL;
+
 	int ret = lock(fd);
 	if (ret < 0)
 		return ret;
@@ -666,6 +670,9 @@  int V4L2CameraProxy::vidioc_streamon(int fd, int *arg)
 	if (arg == nullptr)
 		return -EFAULT;
 
+	if (streaming_)
+		return 0;
+
 	int ret = lock(fd);
 	if (ret < 0)
 		return ret;
@@ -674,6 +681,7 @@  int V4L2CameraProxy::vidioc_streamon(int fd, int *arg)
 		return -EINVAL;
 
 	currentBuf_ = 0;
+	streaming_ = true;
 
 	return vcam_->streamOn();
 }
@@ -685,6 +693,12 @@  int V4L2CameraProxy::vidioc_streamoff(int fd, int *arg)
 	if (arg == nullptr)
 		return -EFAULT;
 
+	if (!streaming_) {
+		for (unsigned int i = 0; i < bufferCount_; i++)
+			buffers_[i].flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE);
+		return 0;
+	}
+
 	int ret = lock(fd);
 	if (ret < 0)
 		return ret;
@@ -697,6 +711,8 @@  int V4L2CameraProxy::vidioc_streamoff(int fd, int *arg)
 	for (struct v4l2_buffer &buf : buffers_)
 		buf.flags &= ~(V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE);
 
+	streaming_ = false;
+
 	return ret;
 }
 
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index 2ff9571..28b2fa0 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -103,6 +103,7 @@  private:
 	int acquiredFd_;
 
 	bool initialized_;
+	bool streaming_;
 };
 
 #endif /* __V4L2_CAMERA_PROXY_H__ */