GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
gboolean ret;
- if (pool->orphaned)
- return gst_v4l2_buffer_pool_vallocator_stop (pool);
-
GST_DEBUG_OBJECT (pool, "stopping pool");
if (pool->group_released_handler > 0) {
pool->other_pool = NULL;
}
- gst_v4l2_buffer_pool_streamoff (pool);
+ if (!pool->orphaned)
+ gst_v4l2_buffer_pool_streamoff (pool);
ret = GST_BUFFER_POOL_CLASS (parent_class)->stop (bpool);
GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (*bpool);
gboolean ret;
+ g_return_val_if_fail (pool->orphaned == FALSE, FALSE);
+
if (!GST_V4L2_ALLOCATOR_CAN_ORPHAN_BUFS (pool->vallocator))
return FALSE;
return FALSE;
GST_DEBUG_OBJECT (pool, "orphaning pool");
-
gst_buffer_pool_set_active (*bpool, FALSE);
- /*
- * If the buffer pool has outstanding buffers, it will not be stopped
- * by the base class when set inactive. Stop it manually and mark it
- * as orphaned
- */
- ret = gst_v4l2_buffer_pool_stop (*bpool);
- if (!ret)
- ret = gst_v4l2_allocator_orphan (pool->vallocator);
- if (!ret)
- goto orphan_failed;
+ /* We lock to prevent racing with a return buffer in QBuf, and has a
+ * workaround of not being able to use the pool hidden activation lock. */
+ GST_OBJECT_LOCK (pool);
+
+ gst_v4l2_buffer_pool_streamoff (pool);
+ ret = gst_v4l2_allocator_orphan (pool->vallocator);
+ if (ret)
+ pool->orphaned = TRUE;
+
+ GST_OBJECT_UNLOCK (pool);
- pool->orphaned = TRUE;
- gst_object_unref (*bpool);
- *bpool = NULL;
+ if (ret) {
+ gst_object_unref (*bpool);
+ *bpool = NULL;
+ }
-orphan_failed:
return ret;
}
}
GST_OBJECT_LOCK (pool);
+
+ /* 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
+ * orphaning. */
+ if (pool->orphaned)
+ goto was_orphaned;
+
g_atomic_int_inc (&pool->num_queued);
pool->buffers[index] = buf;
GST_ERROR_OBJECT (pool, "the buffer %i was already queued", index);
return GST_FLOW_ERROR;
}
+was_orphaned:
+ {
+ GST_DEBUG_OBJECT (pool, "pool was orphaned, not queuing back buffer.");
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_TAG_MEMORY);
+ GST_OBJECT_UNLOCK (pool);
+ return GST_FLOW_FLUSHING;
+ }
queue_failed:
{
GST_ERROR_OBJECT (pool, "could not queue a buffer %i", index);
GST_DEBUG_OBJECT (pool, "release buffer %p", buffer);
- /* If the buffer's pool has been orphaned, dispose of it so that
- * the pool resources can be freed */
- if (pool->orphaned) {
- GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
- pclass->release_buffer (bpool, buffer);
- return;
- }
-
switch (obj->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: