diff mbox

[REVIEWv2,12/15] vb2: properly clean up PREPARED and QUEUED buffers

Message ID 1393332775-44067-13-git-send-email-hverkuil@xs4all.nl (mailing list archive)
State New, archived
Headers show

Commit Message

Hans Verkuil Feb. 25, 2014, 12:52 p.m. UTC
From: Hans Verkuil <hans.verkuil@cisco.com>

In __vb2_dqbuf we need to call the finish memop for any pending
buffers in the PREPARED or QUEUED state. This can happen if PREPARE_BUF
or QBUF was called without ever calling STREAMON.

In that case, when either REQBUFS(0) is called or the filehandle is
closed __vb2_queue_cancel needs to handle such buffers correctly.

For the same reason a call to __vb2_queue_cancel was added in __reqbufs
so that these buffers are cleaned up there as well.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 drivers/media/v4l2-core/videobuf2-core.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
diff mbox

Patch

diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index f156475..3815f9c 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -96,6 +96,8 @@  module_param(debug, int, 0644);
 				 V4L2_BUF_FLAG_PREPARED | \
 				 V4L2_BUF_FLAG_TIMESTAMP_MASK)
 
+static void __vb2_queue_cancel(struct vb2_queue *q);
+
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
  */
@@ -789,6 +791,12 @@  static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
 			return -EBUSY;
 		}
 
+		/*
+		 * Call queue_cancel to clean up any buffers in the PREPARED or
+		 * QUEUED state which is possible if buffers were prepared or
+		 * queued without ever calling STREAMON.
+		 */
+		__vb2_queue_cancel(q);
 		ret = __vb2_queue_free(q, q->num_buffers);
 		if (ret)
 			return ret;
@@ -1839,12 +1847,23 @@  EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
 static void __vb2_dqbuf(struct vb2_buffer *vb)
 {
 	struct vb2_queue *q = vb->vb2_queue;
+	unsigned int plane;
 	unsigned int i;
 
 	/* nothing to do if the buffer is already dequeued */
 	if (vb->state == VB2_BUF_STATE_DEQUEUED)
 		return;
 
+	/*
+	 * If it is prepared or queued the we 'finish' the buffer.
+	 * This can happen if buffers were prepared or queued without STREAMON
+	 * being called, and we are called by __vb2_queue_cancel.
+	 */
+	if (vb->state == VB2_BUF_STATE_PREPARED ||
+	    vb->state == VB2_BUF_STATE_QUEUED)
+		for (plane = 0; plane < vb->num_planes; ++plane)
+			call_memop(vb, finish, vb->planes[plane].mem_priv);
+
 	call_vb_qop(vb, buf_finish, vb);
 
 	vb->state = VB2_BUF_STATE_DEQUEUED;