mirror of
https://github.com/utmapp/UTM.git
synced 2026-10-12 02:24:01 +00:00
226 lines
8.8 KiB
Diff
226 lines
8.8 KiB
Diff
From 638a01381ea5ba8348138476bc88b338234cd858 Mon Sep 17 00:00:00 2001
|
|
From: osy <[email protected]>
|
|
Date: Mon, 1 Aug 2022 13:20:20 -0700
|
|
Subject: [PATCH] gstaudiobasesrc: reset clock when caps change
|
|
|
|
This follows similar code from gstaudiobasesink. When the caps change, we
|
|
need to reset the clock, otherwise a long period of silence will be
|
|
recorded.
|
|
---
|
|
gst-libs/gst/audio/gstaudiobasesrc.c | 21 +++++++++++++++------
|
|
1 file changed, 15 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/gst-libs/gst/audio/gstaudiobasesrc.c b/gst-libs/gst/audio/gstaudiobasesrc.c
|
|
index a384e8eb3..6977f11e4 100644
|
|
--- a/gst-libs/gst/audio/gstaudiobasesrc.c
|
|
+++ b/gst-libs/gst/audio/gstaudiobasesrc.c
|
|
@@ -299,6 +299,14 @@ clock_disabled:
|
|
}
|
|
}
|
|
|
|
+static gboolean
|
|
+gst_audio_base_src_is_self_provided_clock (GstAudioBaseSrc * sink)
|
|
+{
|
|
+ return (sink->clock && GST_IS_AUDIO_CLOCK (sink->clock) &&
|
|
+ GST_AUDIO_CLOCK_CAST (sink->clock)->func ==
|
|
+ (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time);
|
|
+}
|
|
+
|
|
static GstClockTime
|
|
gst_audio_base_src_get_time (GstClock * clock, GstAudioBaseSrc * src)
|
|
{
|
|
@@ -555,6 +563,11 @@ gst_audio_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
|
|
if (!gst_audio_ring_buffer_acquire (src->ringbuffer, spec))
|
|
goto acquire_error;
|
|
|
|
+ /* If we use our own clock, we need to adjust the offset since it will now
|
|
+ * restart from zero */
|
|
+ if (gst_audio_base_src_is_self_provided_clock (src))
|
|
+ gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
|
|
+
|
|
/* calculate actual latency and buffer times */
|
|
spec->latency_time = spec->segsize * GST_MSECOND / (rate * bpf);
|
|
spec->buffer_time =
|
|
@@ -1142,9 +1155,7 @@ gst_audio_base_src_change_state (GstElement * element,
|
|
/* Only post clock-provide messages if this is the clock that
|
|
* we've created. If the subclass has overridden it the subclass
|
|
* should post this messages whenever necessary */
|
|
- if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
|
|
- GST_AUDIO_CLOCK_CAST (src->clock)->func ==
|
|
- (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
|
|
+ if (gst_audio_base_src_is_self_provided_clock (src))
|
|
gst_element_post_message (element,
|
|
gst_message_new_clock_provide (GST_OBJECT_CAST (element),
|
|
src->clock, TRUE));
|
|
@@ -1163,9 +1174,7 @@ gst_audio_base_src_change_state (GstElement * element,
|
|
/* Only post clock-lost messages if this is the clock that
|
|
* we've created. If the subclass has overridden it the subclass
|
|
* should post this messages whenever necessary */
|
|
- if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
|
|
- GST_AUDIO_CLOCK_CAST (src->clock)->func ==
|
|
- (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
|
|
+ if (gst_audio_base_src_is_self_provided_clock (src))
|
|
gst_element_post_message (element,
|
|
gst_message_new_clock_lost (GST_OBJECT_CAST (element), src->clock));
|
|
gst_audio_ring_buffer_set_flushing (src->ringbuffer, TRUE);
|
|
--
|
|
2.28.0
|
|
|
|
From 63a3609a1b668e5bdab0a0b052bb8a6b1b7f62b8 Mon Sep 17 00:00:00 2001
|
|
From: Jan Schmidt <[email protected]>
|
|
Date: Sat, 19 Aug 2023 01:00:16 +1000
|
|
Subject: [PATCH] audio: Make sure to stop ringbuffer on error
|
|
|
|
Add gst_audio_ring_buffer_set_errored() that will mark the
|
|
ringbuffer as errored only if it is currently started or paused,
|
|
so gst_audio_ringbuffer_stop() can be sure that the error
|
|
state means that the ringbuffer was started and needs stop called.
|
|
|
|
Fixes a crash with osxaudiosrc if the source element posts
|
|
an error, because the ringbuffer would not get stopped and CoreAudio
|
|
would continue trying to do callbacks.
|
|
|
|
Also, anywhere that modifies the ringbuffer state, make sure to
|
|
use atomic operations, to guarantee their visibility
|
|
---
|
|
girs/GstAudio-1.0.gir | 15 ++++++
|
|
.../gst-libs/gst/audio/gstaudiobasesrc.c | 2 +-
|
|
.../gst-libs/gst/audio/gstaudioringbuffer.c | 50 ++++++++++++++++---
|
|
.../gst-libs/gst/audio/gstaudioringbuffer.h | 3 ++
|
|
4 files changed, 62 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/gst-libs/gst/audio/gstaudiobasesrc.c b/gst-libs/gst/audio/gstaudiobasesrc.c
|
|
index 0dd7654e036..04916f36fdd 100644
|
|
--- a/gst-libs/gst/audio/gstaudiobasesrc.c
|
|
+++ b/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/gst-libs/gst/audio/gstaudioringbuffer.c b/gst-libs/gst/audio/gstaudioringbuffer.c
|
|
index c2319105840..a567f72af0f 100644
|
|
--- a/gst-libs/gst/audio/gstaudioringbuffer.c
|
|
+++ b/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,34 @@ 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");
|
|
+ }
|
|
+}
|
|
+
|
|
static gboolean
|
|
gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
|
|
{
|
|
@@ -1121,7 +1149,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 +1161,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 +1243,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 +1266,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/gst-libs/gst/audio/gstaudioringbuffer.h b/gst-libs/gst/audio/gstaudioringbuffer.h
|
|
index cde57cb457a..e188636145b 100644
|
|
--- a/gst-libs/gst/audio/gstaudioringbuffer.h
|
|
+++ b/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
|
|
--
|
|
GitLab
|
|
|