From 8fc50891b11829e2efd8ac22c2ecc62e46f98252 Mon Sep 17 00:00:00 2001 From: =?utf8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Tue, 17 Nov 2020 13:18:37 +0100 Subject: [PATCH] va: allocator: broadcast when flushing This patch handles when the bufferpool request a new buffer while flushing. Also fixes the usage of g_cond_wait(), which demands to be used inside a loop to avoid spurious wakeups. Part-of: --- sys/va/gstvaallocator.c | 27 +++++++++++++++++++++++---- sys/va/gstvapool.c | 2 +- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/sys/va/gstvaallocator.c b/sys/va/gstvaallocator.c index de18e01..18dc452 100644 --- a/sys/va/gstvaallocator.c +++ b/sys/va/gstvaallocator.c @@ -407,6 +407,8 @@ struct _GstVaDmabufAllocator GstVideoInfo info; guint usage_hint; + + gboolean flushing; }; #define gst_va_dmabuf_allocator_parent_class dmabuf_parent_class @@ -659,9 +661,14 @@ gst_va_dmabuf_allocator_prepare_buffer (GstAllocator * allocator, GST_OBJECT_LOCK (self); /* if available mems, use them */ - if (gst_atomic_queue_length (self->available_mems) == 0) + while (gst_atomic_queue_length (self->available_mems) == 0 && !self->flushing) g_cond_wait (&self->buffer_cond, GST_OBJECT_GET_LOCK (self)); + if (self->flushing) { + GST_OBJECT_UNLOCK (self); + return FALSE; + } + mem[0] = gst_atomic_queue_pop (self->available_mems); surface = gst_va_memory_get_surface (mem[0]); @@ -696,9 +703,11 @@ gst_va_dmabuf_allocator_flush (GstAllocator * allocator) GstVaDmabufAllocator *self = GST_VA_DMABUF_ALLOCATOR (allocator); GST_OBJECT_LOCK (self); + self->flushing = TRUE; _available_mems_flush (self->display, self->available_mems, &self->surface_count); - g_cond_signal (&self->buffer_cond); + self->flushing = FALSE; + g_cond_broadcast (&self->buffer_cond); GST_OBJECT_UNLOCK (self); } @@ -862,6 +871,8 @@ struct _GstVaAllocator GstVideoInfo info; guint usage_hint; + + gboolean flushing; }; typedef struct _GstVaMemory GstVaMemory; @@ -1293,8 +1304,14 @@ gst_va_allocator_prepare_buffer (GstAllocator * allocator, GstBuffer * buffer) VASurfaceID surface; GST_OBJECT_LOCK (self); + + if (self->flushing) { + GST_OBJECT_UNLOCK (self); + return FALSE; + } + /* if available mems, use them */ - if (gst_atomic_queue_length (self->available_mems) == 0) + while (gst_atomic_queue_length (self->available_mems) == 0) g_cond_wait (&self->buffer_cond, GST_OBJECT_GET_LOCK (self)); mem = gst_atomic_queue_pop (self->available_mems); @@ -1315,9 +1332,11 @@ gst_va_allocator_flush (GstAllocator * allocator) GstVaAllocator *self = GST_VA_ALLOCATOR (allocator); GST_OBJECT_LOCK (self); + self->flushing = TRUE; _available_mems_flush (self->display, self->available_mems, &self->surface_count); - g_cond_signal (&self->buffer_cond); + self->flushing = FALSE; + g_cond_broadcast (&self->buffer_cond); GST_OBJECT_UNLOCK (self); } diff --git a/sys/va/gstvapool.c b/sys/va/gstvapool.c index 6253235..2a54701 100644 --- a/sys/va/gstvapool.c +++ b/sys/va/gstvapool.c @@ -315,7 +315,7 @@ gst_va_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer, } gst_buffer_replace (buffer, NULL); - return GST_FLOW_ERROR; + return GST_FLOW_FLUSHING; } static void -- 2.7.4