mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
v4l2bufferpool: add lock as atomic operation for seek
When seek flush, gst v4l2 buffer pool flush is not atomic which will lead double enqueue buffer (qbuf) issue, and v4l2 buffer pool qbuf is also not atomic which will lead no free buffer found in the pool. 1. add lock for calculate enqueue number in streamon function 2. add lock for v4l2 capture end streamoff in pool flush function 3. lock the whole funciton of v4l2 buffer pool qbuf, then the buffer pool index and qbuf operation are atomic Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5695>
This commit is contained in:
parent
d809406dfc
commit
390d43dcde
1 changed files with 7 additions and 2 deletions
|
@ -682,9 +682,11 @@ gst_v4l2_buffer_pool_streamon (GstV4l2BufferPool * pool)
|
||||||
guint num_queued;
|
guint num_queued;
|
||||||
guint i, n = 0;
|
guint i, n = 0;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (pool);
|
||||||
num_queued = g_atomic_int_get (&pool->num_queued);
|
num_queued = g_atomic_int_get (&pool->num_queued);
|
||||||
if (num_queued < pool->num_allocated)
|
if (num_queued < pool->num_allocated)
|
||||||
n = pool->num_allocated - num_queued;
|
n = pool->num_allocated - num_queued;
|
||||||
|
GST_OBJECT_UNLOCK (pool);
|
||||||
|
|
||||||
/* For captures, we need to enqueue buffers before we start streaming,
|
/* For captures, we need to enqueue buffers before we start streaming,
|
||||||
* so the driver don't underflow immediately. As we have put then back
|
* so the driver don't underflow immediately. As we have put then back
|
||||||
|
@ -1147,6 +1149,8 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf,
|
||||||
gint old_buffer_state;
|
gint old_buffer_state;
|
||||||
gint index;
|
gint index;
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (pool);
|
||||||
|
|
||||||
index = group->buffer.index;
|
index = group->buffer.index;
|
||||||
|
|
||||||
old_buffer_state =
|
old_buffer_state =
|
||||||
|
@ -1182,8 +1186,6 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_OBJECT_LOCK (pool);
|
|
||||||
|
|
||||||
/* If the pool was orphaned, don't try to queue any returned buffers.
|
/* If the pool was orphaned, don't try to queue any returned buffers.
|
||||||
* This is done with the objet lock in order to synchronize with
|
* This is done with the objet lock in order to synchronize with
|
||||||
* orphaning. */
|
* orphaning. */
|
||||||
|
@ -1205,6 +1207,7 @@ gst_v4l2_buffer_pool_qbuf (GstV4l2BufferPool * pool, GstBuffer * buf,
|
||||||
already_queued:
|
already_queued:
|
||||||
{
|
{
|
||||||
GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
|
GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
|
||||||
|
GST_OBJECT_UNLOCK (pool);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
was_orphaned:
|
was_orphaned:
|
||||||
|
@ -2281,7 +2284,9 @@ gst_v4l2_buffer_pool_flush (GstV4l2Object * v4l2object)
|
||||||
|
|
||||||
pool = GST_V4L2_BUFFER_POOL (bpool);
|
pool = GST_V4L2_BUFFER_POOL (bpool);
|
||||||
|
|
||||||
|
GST_OBJECT_LOCK (pool);
|
||||||
gst_v4l2_buffer_pool_streamoff (pool);
|
gst_v4l2_buffer_pool_streamoff (pool);
|
||||||
|
GST_OBJECT_UNLOCK (pool);
|
||||||
|
|
||||||
if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
|
if (!V4L2_TYPE_IS_OUTPUT (pool->obj->type)) {
|
||||||
ret = gst_v4l2_buffer_pool_flush_events (v4l2object);
|
ret = gst_v4l2_buffer_pool_flush_events (v4l2object);
|
||||||
|
|
Loading…
Reference in a new issue