diff options
-rw-r--r-- | drivers/media/v4l2-core/videobuf2-core.c | 15 | ||||
-rw-r--r-- | include/media/videobuf2-core.h | 4 |
2 files changed, 17 insertions, 2 deletions
diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index dcdceae30ab0..a946523772d6 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -967,6 +967,7 @@ static int __reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) * to the userspace. */ req->count = allocated_buffers; + q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type); return 0; } @@ -1014,6 +1015,7 @@ static int __create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create memset(q->plane_sizes, 0, sizeof(q->plane_sizes)); memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); q->memory = create->memory; + q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type); } num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers); @@ -1812,6 +1814,7 @@ static int vb2_internal_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) */ list_add_tail(&vb->queued_entry, &q->queued_list); q->queued_count++; + q->waiting_for_buffers = false; vb->state = VB2_BUF_STATE_QUEUED; if (V4L2_TYPE_IS_OUTPUT(q->type)) { /* @@ -2244,6 +2247,7 @@ static int vb2_internal_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) * their normal dequeued state. */ __vb2_queue_cancel(q); + q->waiting_for_buffers = !V4L2_TYPE_IS_OUTPUT(q->type); dprintk(3, "successful\n"); return 0; @@ -2562,9 +2566,16 @@ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) } /* - * There is nothing to wait for if no buffers have already been queued. + * There is nothing to wait for if the queue isn't streaming. */ - if (list_empty(&q->queued_list)) + if (!vb2_is_streaming(q)) + return res | POLLERR; + /* + * For compatibility with vb1: if QBUF hasn't been called yet, then + * return POLLERR as well. This only affects capture queues, output + * queues will always initialize waiting_for_buffers to false. + */ + if (q->waiting_for_buffers) return res | POLLERR; if (list_empty(&q->done_list)) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 8fab6fa0dbfb..d6f010c17f4a 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -375,6 +375,9 @@ struct v4l2_fh; * @streaming: current streaming state * @start_streaming_called: start_streaming() was called successfully and we * started streaming. + * @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. * @fileio: file io emulator internal data, used only if emulator is active * @threadio: thread io internal data, used only if thread is active */ @@ -411,6 +414,7 @@ struct vb2_queue { unsigned int streaming:1; unsigned int start_streaming_called:1; + unsigned int waiting_for_buffers:1; struct vb2_fileio_data *fileio; struct vb2_threadio_data *threadio; |