From: Philipp Zabel <p.zabel@pengutronix.de>
To: linux-media@vger.kernel.org
Cc: Hans Verkuil <hverkuil@xs4all.nl>,
Pawel Osciak <pawel@osciak.com>,
Kamil Debski <k.debski@samsung.com>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Nicolas Dufresne <nicolas.dufresne@collabora.com>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
kernel@pengutronix.de, Philipp Zabel <p.zabel@pengutronix.de>
Subject: [PATCH v3 2/5] [media] videobuf2: return -EPIPE from DQBUF after the last buffer
Date: Fri, 6 Mar 2015 11:18:27 +0100 [thread overview]
Message-ID: <1425637110-12100-3-git-send-email-p.zabel@pengutronix.de> (raw)
In-Reply-To: <1425637110-12100-1-git-send-email-p.zabel@pengutronix.de>
If the last buffer was dequeued from a capture queue, let poll return
immediately and let DQBUF return -EPIPE to signal there will no more
buffers to dequeue until STREAMOFF.
The driver signals the last buffer by setting the V4L2_BUF_FLAG_LAST.
To reenable dequeuing on the capture queue, the driver must explicitly
call vb2_clear_last_buffer_queued. The last buffer queued flag is
cleared automatically during STREAMOFF.
Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
Documentation/DocBook/media/v4l/vidioc-qbuf.xml | 8 ++++++++
drivers/media/v4l2-core/v4l2-mem2mem.c | 10 +++++++++-
drivers/media/v4l2-core/videobuf2-core.c | 18 +++++++++++++++++-
include/media/videobuf2-core.h | 10 ++++++++++
4 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
index 3504a7f..6cfc53b 100644
--- a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml
@@ -186,6 +186,14 @@ In that case the application should be able to safely reuse the buffer and
continue streaming.
</para>
</listitem>
+ <term><errorcode>EPIPE</errorcode></term>
+ <listitem>
+ <para><constant>VIDIOC_DQBUF</constant> returns this on an empty
+capture queue for mem2mem codecs if a buffer with the
+<constant>V4L2_BUF_FLAG_LAST</constant> was already dequeued and no new buffers
+are expected to become available.
+ </para>
+ </listitem>
</varlistentry>
</variablelist>
</refsect1>
diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c
index 80c588f..1b5b432 100644
--- a/drivers/media/v4l2-core/v4l2-mem2mem.c
+++ b/drivers/media/v4l2-core/v4l2-mem2mem.c
@@ -564,8 +564,16 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
if (list_empty(&src_q->done_list))
poll_wait(file, &src_q->done_wq, wait);
- if (list_empty(&dst_q->done_list))
+ if (list_empty(&dst_q->done_list)) {
+ /*
+ * If the last buffer was dequeued from the capture queue,
+ * return immediately. DQBUF will return -EPIPE.
+ */
+ if (dst_q->last_buffer_dequeued)
+ return rc | POLLIN | POLLRDNORM;
+
poll_wait(file, &dst_q->done_wq, wait);
+ }
if (m2m_ctx->m2m_dev->m2m_ops->lock)
m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c
index bc08a82..a0b9946 100644
--- a/drivers/media/v4l2-core/videobuf2-core.c
+++ b/drivers/media/v4l2-core/videobuf2-core.c
@@ -2046,6 +2046,10 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
struct vb2_buffer *vb = NULL;
int ret;
+ if (q->last_buffer_dequeued) {
+ dprintk(3, "last buffer dequeued already\n");
+ return -EPIPE;
+ }
if (b->type != q->type) {
dprintk(1, "invalid buffer type\n");
return -EINVAL;
@@ -2073,6 +2077,9 @@ static int vb2_internal_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool n
/* Remove from videobuf queue */
list_del(&vb->queued_entry);
q->queued_count--;
+ if (!V4L2_TYPE_IS_OUTPUT(q->type) &&
+ vb->v4l2_buf.flags & V4L2_BUF_FLAG_LAST)
+ q->last_buffer_dequeued = true;
/* go back to dequeued state */
__vb2_dqbuf(vb);
@@ -2286,6 +2293,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
*/
__vb2_queue_cancel(q);
q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type);
+ q->last_buffer_dequeued = false;
dprintk(3, "successful\n");
return 0;
@@ -2628,8 +2636,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
if (V4L2_TYPE_IS_OUTPUT(q->type) && q->queued_count < q->num_buffers)
return res | POLLOUT | POLLWRNORM;
- if (list_empty(&q->done_list))
+ if (list_empty(&q->done_list)) {
+ /*
+ * If the last buffer was dequeued from a capture queue,
+ * return immediately. DQBUF will return -EPIPE.
+ */
+ if (!V4L2_TYPE_IS_OUTPUT(q->type) && q->last_buffer_dequeued)
+ return res | POLLIN | POLLRDNORM;
+
poll_wait(file, &q->done_wq, wait);
+ }
/*
* Take first buffer available for dequeuing.
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
index bd2cec2..863a8bb 100644
--- a/include/media/videobuf2-core.h
+++ b/include/media/videobuf2-core.h
@@ -429,6 +429,7 @@ struct vb2_queue {
unsigned int start_streaming_called:1;
unsigned int error:1;
unsigned int waiting_for_buffers:1;
+ unsigned int last_buffer_dequeued:1;
struct vb2_fileio_data *fileio;
struct vb2_threadio_data *threadio;
@@ -609,6 +610,15 @@ static inline bool vb2_start_streaming_called(struct vb2_queue *q)
return q->start_streaming_called;
}
+/**
+ * vb2_clear_last_buffer_dequeued() - clear last buffer dequeued flag of queue
+ * @q: videobuf queue
+ */
+static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q)
+{
+ q->last_buffer_dequeued = false;
+}
+
/*
* The following functions are not part of the vb2 core API, but are simple
* helper functions that you can use in your struct v4l2_file_operations,
--
2.1.4
next prev parent reply other threads:[~2015-03-06 10:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-06 10:18 [PATCH v3 0/5] Signalling last decoded frame by V4L2_BUF_FLAG_LAST and -EPIPE Philipp Zabel
2015-03-06 10:18 ` [PATCH v3 1/5] [media] videodev2: Add V4L2_BUF_FLAG_LAST Philipp Zabel
2015-03-06 10:18 ` Philipp Zabel [this message]
2015-03-06 10:18 ` [PATCH v3 3/5] [media] coda: Set last buffer flag and fix EOS event Philipp Zabel
2015-03-06 10:18 ` [PATCH v3 4/5] [media] s5p-mfc: Set last buffer flag Philipp Zabel
2015-03-06 10:18 ` [PATCH v3 5/5] [media] DocBooc: mention mem2mem codecs for encoder/decoder commands Philipp Zabel
2015-03-17 10:46 ` [PATCH v3 0/5] Signalling last decoded frame by V4L2_BUF_FLAG_LAST and -EPIPE Philipp Zabel
2015-03-17 16:09 ` Hans Verkuil
2015-03-18 16:20 ` Kamil Debski
2015-03-18 16:27 ` Philipp Zabel
2015-04-07 14:44 ` Kamil Debski
2015-04-08 10:09 ` Hans Verkuil
2015-04-08 10:19 ` Pawel Osciak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1425637110-12100-3-git-send-email-p.zabel@pengutronix.de \
--to=p.zabel@pengutronix.de \
--cc=hverkuil@xs4all.nl \
--cc=k.debski@samsung.com \
--cc=kernel@pengutronix.de \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=nicolas.dufresne@collabora.com \
--cc=pawel@osciak.com \
--cc=sakari.ailus@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).