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);
return -EIO;
}
+ if (q->last_buffer_dequeued) {
+ dprintk(3, "last buffer dequeued already, will not wait for buffers\n");
+ return -EPIPE;
+ }
+
if (!list_empty(&q->done_list)) {
/*
* Found a buffer that we were waiting for.
/* 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);
*/
__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;
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 (q->last_buffer_dequeued)
+ return res | POLLIN | POLLRDNORM;
+
poll_wait(file, &q->done_wq, wait);
+ }
/*
* Take first buffer available for dequeuing.
* @waiting_for_buffers: used in poll() to check if vb2 is still waiting for
* buffers. Only set for capture queues if qbuf has not yet been
* called since poll() needs to return POLLERR in that situation.
+ * @last_buffer_dequeued: used in poll() and DQBUF to immediately return if the
+ * last decoded buffer was already dequeued. Set for capture queues
+ * when a buffer with the V4L2_BUF_FLAG_LAST is dequeued.
* @fileio: file io emulator internal data, used only if emulator is active
* @threadio: thread io internal data, used only if thread is active
*/
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;
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,