diff --git a/girs/GstAudio-1.0.gir b/girs/GstAudio-1.0.gir index 94e1db365f..4aade83bc5 100644 --- a/girs/GstAudio-1.0.gir +++ b/girs/GstAudio-1.0.gir @@ -8165,6 +8165,21 @@ be called in when the ringbuffer is acquired. + + Mark the ringbuffer as errored after it has started. + +MT safe. + + + + + + + the #GstAudioRingBuffer that has encountered an error + + + + Set the ringbuffer to flushing mode or normal mode. diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesrc.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesrc.c index 0dd7654e03..04916f36fd 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesrc.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiobasesrc.c @@ -1229,7 +1229,7 @@ gst_audio_base_src_post_message (GstElement * element, GstMessage * message) * flow error message */ ret = GST_ELEMENT_CLASS (parent_class)->post_message (element, message); - g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_ERROR); + gst_audio_ring_buffer_set_errored (ringbuffer); GST_AUDIO_RING_BUFFER_SIGNAL (ringbuffer); gst_object_unref (ringbuffer); } else { diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.c index c231910584..0685896ff4 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.c @@ -82,7 +82,7 @@ gst_audio_ring_buffer_init (GstAudioRingBuffer * ringbuffer) { ringbuffer->open = FALSE; ringbuffer->acquired = FALSE; - ringbuffer->state = GST_AUDIO_RING_BUFFER_STATE_STOPPED; + g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_STOPPED); g_cond_init (&ringbuffer->cond); ringbuffer->waiting = 0; ringbuffer->empty_seg = NULL; @@ -1066,7 +1066,7 @@ gst_audio_ring_buffer_start (GstAudioRingBuffer * buf) } if (G_UNLIKELY (!res)) { - buf->state = GST_AUDIO_RING_BUFFER_STATE_PAUSED; + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_PAUSED); GST_DEBUG_OBJECT (buf, "failed to start"); } else { GST_DEBUG_OBJECT (buf, "started"); @@ -1097,6 +1097,38 @@ may_not_start: } } +/** + * gst_audio_ring_buffer_set_errored: + * @buf: the #GstAudioRingBuffer that has encountered an error + * + * Mark the ringbuffer as errored after it has started. + * + * MT safe. + + * Since: 1.24 + */ +void +gst_audio_ring_buffer_set_errored (GstAudioRingBuffer * buf) +{ + gboolean res; + + /* If started set to errored */ + res = g_atomic_int_compare_and_exchange (&buf->state, + GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_ERROR); + if (!res) { + GST_DEBUG_OBJECT (buf, "ringbuffer was not started, checking paused"); + res = g_atomic_int_compare_and_exchange (&buf->state, + GST_AUDIO_RING_BUFFER_STATE_PAUSED, GST_AUDIO_RING_BUFFER_STATE_ERROR); + } + if (res) { + GST_DEBUG_OBJECT (buf, "ringbuffer is errored"); + } else { + GST_DEBUG_OBJECT (buf, + "Could not mark ringbuffer as errored. It must have been stopped or already errored (was state %d)", + g_atomic_int_get (&buf->state)); + } +} + static gboolean gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf) { @@ -1121,7 +1153,8 @@ gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf) res = rclass->pause (buf); if (G_UNLIKELY (!res)) { - buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED; + /* Restore started state */ + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED); GST_DEBUG_OBJECT (buf, "failed to pause"); } else { GST_DEBUG_OBJECT (buf, "paused"); @@ -1132,7 +1165,7 @@ gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf) not_started: { /* was not started */ - GST_DEBUG_OBJECT (buf, "was not started"); + GST_DEBUG_OBJECT (buf, "was not started (state %d)", buf->state); return TRUE; } } @@ -1214,9 +1247,16 @@ gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf) GST_AUDIO_RING_BUFFER_STATE_PAUSED, GST_AUDIO_RING_BUFFER_STATE_STOPPED); if (!res) { - /* was not paused either, must have been stopped then */ + GST_DEBUG_OBJECT (buf, "was not paused, try errored"); + res = g_atomic_int_compare_and_exchange (&buf->state, + GST_AUDIO_RING_BUFFER_STATE_ERROR, + GST_AUDIO_RING_BUFFER_STATE_STOPPED); + } + if (!res) { + /* was not paused or stopped either, must have been stopped then */ res = TRUE; - GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped"); + GST_DEBUG_OBJECT (buf, + "was not paused or errored, must have been stopped"); goto done; } } @@ -1230,7 +1270,7 @@ gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf) res = rclass->stop (buf); if (G_UNLIKELY (!res)) { - buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED; + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED); GST_DEBUG_OBJECT (buf, "failed to stop"); } else { GST_DEBUG_OBJECT (buf, "stopped"); diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.h b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.h index cde57cb457..e188636145 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.h +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudioringbuffer.h @@ -379,6 +379,9 @@ gboolean gst_audio_ring_buffer_pause (GstAudioRingBuffer *buf); GST_AUDIO_API gboolean gst_audio_ring_buffer_stop (GstAudioRingBuffer *buf); +GST_AUDIO_API +void gst_audio_ring_buffer_set_errored (GstAudioRingBuffer *buf); + /* get status */ GST_AUDIO_API