summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Desmottes <guillaume.desmottes@collabora.co.uk>2018-08-22 15:56:18 +0200
committerNicolas Dufresne <nicolas.dufresne@collabora.com>2018-08-29 12:20:01 -0400
commitba3f947f57bd203e4eaaa8193b5ef51d7b495e4b (patch)
treeac3bc3085bbb6e4db70a14e1fef60e01a3d974c2
parent2b7ad7f2fe1157c508e3bf6f66be447e3a38d137 (diff)
downloadgst-omx-ba3f947f57bd203e4eaaa8193b5ef51d7b495e4b.tar.gz
omx: wait for flush complete and buffers being released when flushing
When flusing we should wait for OMX to send the flush command complete event AND all ports being released. We were stopping as soon as one of those condition was met. Fix a race between FillThisBufferDone/EmptyBufferDone and the flush EventCmdComplete messages. The OMX implementation is supposed to release its buffers before posting the EventCmdComplete event but the ordering isn't guaranteed as the FillThisBufferDone/EmptyBufferDone and EventHandler callbacks can be called from different threads (cf 2.7 'Thread Safety' in the spec). Only wait for buffers currently used by OMX as some buffers may not be in the pending queue because they are held downstream. https://bugzilla.gnome.org/show_bug.cgi?id=789475
-rw-r--r--omx/gstomx.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/omx/gstomx.c b/omx/gstomx.c
index ac6d4eb..d7181bf 100644
--- a/omx/gstomx.c
+++ b/omx/gstomx.c
@@ -1569,17 +1569,27 @@ done:
return err;
}
+/* NOTE: Must be called while holding comp->lock */
static gboolean
should_wait_until_flushed (GstOMXPort * port)
{
- if (port->flushed)
- return FALSE;
+ if (!port->flushed)
+ /* Flush command hasn't been completed yet by OMX */
+ return TRUE;
- if (port->buffers
- && port->buffers->len == g_queue_get_length (&port->pending_buffers))
- return FALSE;
+ if (port->buffers) {
+ guint i;
- return TRUE;
+ /* Wait for all the buffers used by OMX to be released */
+ for (i = 0; i < port->buffers->len; i++) {
+ GstOMXBuffer *buf = g_ptr_array_index (port->buffers, i);
+
+ if (buf->used)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
}
/* NOTE: Uses comp->lock and comp->messages_lock */