Skip to content

Commit

Permalink
[media] vb2: Only requeue buffers immediately once streaming is started
Browse files Browse the repository at this point in the history
Buffers can be returned back to videobuf2 in driver's streamon handler. In
this case vb2_buffer_done() with buffer state VB2_BUF_STATE_QUEUED will
cause the driver's buf_queue vb2 operation to be called, queueing the same
buffer again only to be returned to videobuf2 using vb2_buffer_done() and so
on.

Add a new buffer state VB2_BUF_STATE_REQUEUEING which, when used as the
state argument to vb2_buffer_done(), will result in buffers queued to the
driver. Using VB2_BUF_STATE_QUEUED will leave the buffer to videobuf2, as it
was before "[media] vb2: allow requeuing buffers while streaming".

Fixes: ce0eff0 ("[media] vb2: allow requeuing buffers while streaming")

[mchehab@osg.samsung.com: fix warning: enumeration value 'VB2_BUF_STATE_REQUEUEING' not handled in switch]

Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Cc: stable@vger.kernel.org # for v4.1
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
  • Loading branch information
Sakari Ailus authored and Mauro Carvalho Chehab committed Jul 17, 2015
1 parent 5bab862 commit 6d058c5
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 9 deletions.
2 changes: 1 addition & 1 deletion drivers/media/pci/cobalt/cobalt-irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static void cobalt_dma_stream_queue_handler(struct cobalt_stream *s)
also know about dropped frames. */
cb->vb.v4l2_buf.sequence = s->sequence++;
vb2_buffer_done(&cb->vb, (skip || s->unstable_frame) ?
VB2_BUF_STATE_QUEUED : VB2_BUF_STATE_DONE);
VB2_BUF_STATE_REQUEUEING : VB2_BUF_STATE_DONE);
}

irqreturn_t cobalt_irq_handler(int irq, void *dev_id)
Expand Down
26 changes: 18 additions & 8 deletions drivers/media/v4l2-core/videobuf2-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
break;
case VB2_BUF_STATE_PREPARING:
case VB2_BUF_STATE_DEQUEUED:
case VB2_BUF_STATE_REQUEUEING:
/* nothing */
break;
}
Expand Down Expand Up @@ -1182,7 +1183,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)

if (WARN_ON(state != VB2_BUF_STATE_DONE &&
state != VB2_BUF_STATE_ERROR &&
state != VB2_BUF_STATE_QUEUED))
state != VB2_BUF_STATE_QUEUED &&
state != VB2_BUF_STATE_REQUEUEING))
state = VB2_BUF_STATE_ERROR;

#ifdef CONFIG_VIDEO_ADV_DEBUG
Expand All @@ -1199,22 +1201,30 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
for (plane = 0; plane < vb->num_planes; ++plane)
call_void_memop(vb, finish, vb->planes[plane].mem_priv);

/* Add the buffer to the done buffers list */
spin_lock_irqsave(&q->done_lock, flags);
vb->state = state;
if (state != VB2_BUF_STATE_QUEUED)
if (state == VB2_BUF_STATE_QUEUED ||
state == VB2_BUF_STATE_REQUEUEING) {
vb->state = VB2_BUF_STATE_QUEUED;
} else {
/* Add the buffer to the done buffers list */
list_add_tail(&vb->done_entry, &q->done_list);
vb->state = state;
}
atomic_dec(&q->owned_by_drv_count);
spin_unlock_irqrestore(&q->done_lock, flags);

if (state == VB2_BUF_STATE_QUEUED) {
switch (state) {
case VB2_BUF_STATE_QUEUED:
return;
case VB2_BUF_STATE_REQUEUEING:
if (q->start_streaming_called)
__enqueue_in_driver(vb);
return;
default:
/* Inform any processes that may be waiting for buffers */
wake_up(&q->done_wq);
break;
}

/* Inform any processes that may be waiting for buffers */
wake_up(&q->done_wq);
}
EXPORT_SYMBOL_GPL(vb2_buffer_done);

Expand Down
2 changes: 2 additions & 0 deletions include/media/videobuf2-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ enum vb2_io_modes {
* @VB2_BUF_STATE_PREPARING: buffer is being prepared in videobuf
* @VB2_BUF_STATE_PREPARED: buffer prepared in videobuf and by the driver
* @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
* @VB2_BUF_STATE_REQUEUEING: re-queue a buffer to the driver
* @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
* in a hardware operation
* @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but
Expand All @@ -152,6 +153,7 @@ enum vb2_buffer_state {
VB2_BUF_STATE_PREPARING,
VB2_BUF_STATE_PREPARED,
VB2_BUF_STATE_QUEUED,
VB2_BUF_STATE_REQUEUEING,
VB2_BUF_STATE_ACTIVE,
VB2_BUF_STATE_DONE,
VB2_BUF_STATE_ERROR,
Expand Down

0 comments on commit 6d058c5

Please sign in to comment.