gst-plugins-base-1.19.1.patch 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. From 638a01381ea5ba8348138476bc88b338234cd858 Mon Sep 17 00:00:00 2001
  2. From: osy <osy@turing.llc>
  3. Date: Mon, 1 Aug 2022 13:20:20 -0700
  4. Subject: [PATCH] gstaudiobasesrc: reset clock when caps change
  5. This follows similar code from gstaudiobasesink. When the caps change, we
  6. need to reset the clock, otherwise a long period of silence will be
  7. recorded.
  8. ---
  9. gst-libs/gst/audio/gstaudiobasesrc.c | 21 +++++++++++++++------
  10. 1 file changed, 15 insertions(+), 6 deletions(-)
  11. diff --git a/gst-libs/gst/audio/gstaudiobasesrc.c b/gst-libs/gst/audio/gstaudiobasesrc.c
  12. index a384e8eb3..6977f11e4 100644
  13. --- a/gst-libs/gst/audio/gstaudiobasesrc.c
  14. +++ b/gst-libs/gst/audio/gstaudiobasesrc.c
  15. @@ -299,6 +299,14 @@ clock_disabled:
  16. }
  17. }
  18. +static gboolean
  19. +gst_audio_base_src_is_self_provided_clock (GstAudioBaseSrc * sink)
  20. +{
  21. + return (sink->clock && GST_IS_AUDIO_CLOCK (sink->clock) &&
  22. + GST_AUDIO_CLOCK_CAST (sink->clock)->func ==
  23. + (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time);
  24. +}
  25. +
  26. static GstClockTime
  27. gst_audio_base_src_get_time (GstClock * clock, GstAudioBaseSrc * src)
  28. {
  29. @@ -555,6 +563,11 @@ gst_audio_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
  30. if (!gst_audio_ring_buffer_acquire (src->ringbuffer, spec))
  31. goto acquire_error;
  32. + /* If we use our own clock, we need to adjust the offset since it will now
  33. + * restart from zero */
  34. + if (gst_audio_base_src_is_self_provided_clock (src))
  35. + gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0);
  36. +
  37. /* calculate actual latency and buffer times */
  38. spec->latency_time = spec->segsize * GST_MSECOND / (rate * bpf);
  39. spec->buffer_time =
  40. @@ -1142,9 +1155,7 @@ gst_audio_base_src_change_state (GstElement * element,
  41. /* Only post clock-provide messages if this is the clock that
  42. * we've created. If the subclass has overridden it the subclass
  43. * should post this messages whenever necessary */
  44. - if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
  45. - GST_AUDIO_CLOCK_CAST (src->clock)->func ==
  46. - (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
  47. + if (gst_audio_base_src_is_self_provided_clock (src))
  48. gst_element_post_message (element,
  49. gst_message_new_clock_provide (GST_OBJECT_CAST (element),
  50. src->clock, TRUE));
  51. @@ -1163,9 +1174,7 @@ gst_audio_base_src_change_state (GstElement * element,
  52. /* Only post clock-lost messages if this is the clock that
  53. * we've created. If the subclass has overridden it the subclass
  54. * should post this messages whenever necessary */
  55. - if (src->clock && GST_IS_AUDIO_CLOCK (src->clock) &&
  56. - GST_AUDIO_CLOCK_CAST (src->clock)->func ==
  57. - (GstAudioClockGetTimeFunc) gst_audio_base_src_get_time)
  58. + if (gst_audio_base_src_is_self_provided_clock (src))
  59. gst_element_post_message (element,
  60. gst_message_new_clock_lost (GST_OBJECT_CAST (element), src->clock));
  61. gst_audio_ring_buffer_set_flushing (src->ringbuffer, TRUE);
  62. --
  63. 2.28.0
  64. From 63a3609a1b668e5bdab0a0b052bb8a6b1b7f62b8 Mon Sep 17 00:00:00 2001
  65. From: Jan Schmidt <jan@centricular.com>
  66. Date: Sat, 19 Aug 2023 01:00:16 +1000
  67. Subject: [PATCH] audio: Make sure to stop ringbuffer on error
  68. Add gst_audio_ring_buffer_set_errored() that will mark the
  69. ringbuffer as errored only if it is currently started or paused,
  70. so gst_audio_ringbuffer_stop() can be sure that the error
  71. state means that the ringbuffer was started and needs stop called.
  72. Fixes a crash with osxaudiosrc if the source element posts
  73. an error, because the ringbuffer would not get stopped and CoreAudio
  74. would continue trying to do callbacks.
  75. Also, anywhere that modifies the ringbuffer state, make sure to
  76. use atomic operations, to guarantee their visibility
  77. ---
  78. girs/GstAudio-1.0.gir | 15 ++++++
  79. .../gst-libs/gst/audio/gstaudiobasesrc.c | 2 +-
  80. .../gst-libs/gst/audio/gstaudioringbuffer.c | 50 ++++++++++++++++---
  81. .../gst-libs/gst/audio/gstaudioringbuffer.h | 3 ++
  82. 4 files changed, 62 insertions(+), 8 deletions(-)
  83. diff --git a/gst-libs/gst/audio/gstaudiobasesrc.c b/gst-libs/gst/audio/gstaudiobasesrc.c
  84. index 0dd7654e036..04916f36fdd 100644
  85. --- a/gst-libs/gst/audio/gstaudiobasesrc.c
  86. +++ b/gst-libs/gst/audio/gstaudiobasesrc.c
  87. @@ -1229,7 +1229,7 @@ gst_audio_base_src_post_message (GstElement * element, GstMessage * message)
  88. * flow error message */
  89. ret = GST_ELEMENT_CLASS (parent_class)->post_message (element, message);
  90. - g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_ERROR);
  91. + gst_audio_ring_buffer_set_errored (ringbuffer);
  92. GST_AUDIO_RING_BUFFER_SIGNAL (ringbuffer);
  93. gst_object_unref (ringbuffer);
  94. } else {
  95. diff --git a/gst-libs/gst/audio/gstaudioringbuffer.c b/gst-libs/gst/audio/gstaudioringbuffer.c
  96. index c2319105840..a567f72af0f 100644
  97. --- a/gst-libs/gst/audio/gstaudioringbuffer.c
  98. +++ b/gst-libs/gst/audio/gstaudioringbuffer.c
  99. @@ -82,7 +82,7 @@ gst_audio_ring_buffer_init (GstAudioRingBuffer * ringbuffer)
  100. {
  101. ringbuffer->open = FALSE;
  102. ringbuffer->acquired = FALSE;
  103. - ringbuffer->state = GST_AUDIO_RING_BUFFER_STATE_STOPPED;
  104. + g_atomic_int_set (&ringbuffer->state, GST_AUDIO_RING_BUFFER_STATE_STOPPED);
  105. g_cond_init (&ringbuffer->cond);
  106. ringbuffer->waiting = 0;
  107. ringbuffer->empty_seg = NULL;
  108. @@ -1066,7 +1066,7 @@ gst_audio_ring_buffer_start (GstAudioRingBuffer * buf)
  109. }
  110. if (G_UNLIKELY (!res)) {
  111. - buf->state = GST_AUDIO_RING_BUFFER_STATE_PAUSED;
  112. + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_PAUSED);
  113. GST_DEBUG_OBJECT (buf, "failed to start");
  114. } else {
  115. GST_DEBUG_OBJECT (buf, "started");
  116. @@ -1097,6 +1097,34 @@ may_not_start:
  117. }
  118. }
  119. +/**
  120. + * gst_audio_ring_buffer_set_errored:
  121. + * @buf: the #GstAudioRingBuffer that has encountered an error
  122. + *
  123. + * Mark the ringbuffer as errored after it has started.
  124. + *
  125. + * MT safe.
  126. +
  127. + * Since: 1.24
  128. + */
  129. +void
  130. +gst_audio_ring_buffer_set_errored (GstAudioRingBuffer * buf)
  131. +{
  132. + gboolean res;
  133. +
  134. + /* If started set to errored */
  135. + res = g_atomic_int_compare_and_exchange (&buf->state,
  136. + GST_AUDIO_RING_BUFFER_STATE_STARTED, GST_AUDIO_RING_BUFFER_STATE_ERROR);
  137. + if (!res) {
  138. + GST_DEBUG_OBJECT (buf, "ringbuffer was not started, checking paused");
  139. + res = g_atomic_int_compare_and_exchange (&buf->state,
  140. + GST_AUDIO_RING_BUFFER_STATE_PAUSED, GST_AUDIO_RING_BUFFER_STATE_ERROR);
  141. + }
  142. + if (res) {
  143. + GST_DEBUG_OBJECT (buf, "ringbuffer is errored");
  144. + }
  145. +}
  146. +
  147. static gboolean
  148. gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
  149. {
  150. @@ -1121,7 +1149,8 @@ gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
  151. res = rclass->pause (buf);
  152. if (G_UNLIKELY (!res)) {
  153. - buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
  154. + /* Restore started state */
  155. + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED);
  156. GST_DEBUG_OBJECT (buf, "failed to pause");
  157. } else {
  158. GST_DEBUG_OBJECT (buf, "paused");
  159. @@ -1132,7 +1161,7 @@ gst_audio_ring_buffer_pause_unlocked (GstAudioRingBuffer * buf)
  160. not_started:
  161. {
  162. /* was not started */
  163. - GST_DEBUG_OBJECT (buf, "was not started");
  164. + GST_DEBUG_OBJECT (buf, "was not started (state %d)", buf->state);
  165. return TRUE;
  166. }
  167. }
  168. @@ -1214,9 +1243,16 @@ gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf)
  169. GST_AUDIO_RING_BUFFER_STATE_PAUSED,
  170. GST_AUDIO_RING_BUFFER_STATE_STOPPED);
  171. if (!res) {
  172. - /* was not paused either, must have been stopped then */
  173. + GST_DEBUG_OBJECT (buf, "was not paused, try errored");
  174. + res = g_atomic_int_compare_and_exchange (&buf->state,
  175. + GST_AUDIO_RING_BUFFER_STATE_ERROR,
  176. + GST_AUDIO_RING_BUFFER_STATE_STOPPED);
  177. + }
  178. + if (!res) {
  179. + /* was not paused or stopped either, must have been stopped then */
  180. res = TRUE;
  181. - GST_DEBUG_OBJECT (buf, "was not paused, must have been stopped");
  182. + GST_DEBUG_OBJECT (buf,
  183. + "was not paused or errored, must have been stopped");
  184. goto done;
  185. }
  186. }
  187. @@ -1230,7 +1266,7 @@ gst_audio_ring_buffer_stop (GstAudioRingBuffer * buf)
  188. res = rclass->stop (buf);
  189. if (G_UNLIKELY (!res)) {
  190. - buf->state = GST_AUDIO_RING_BUFFER_STATE_STARTED;
  191. + g_atomic_int_set (&buf->state, GST_AUDIO_RING_BUFFER_STATE_STARTED);
  192. GST_DEBUG_OBJECT (buf, "failed to stop");
  193. } else {
  194. GST_DEBUG_OBJECT (buf, "stopped");
  195. diff --git a/gst-libs/gst/audio/gstaudioringbuffer.h b/gst-libs/gst/audio/gstaudioringbuffer.h
  196. index cde57cb457a..e188636145b 100644
  197. --- a/gst-libs/gst/audio/gstaudioringbuffer.h
  198. +++ b/gst-libs/gst/audio/gstaudioringbuffer.h
  199. @@ -379,6 +379,9 @@ gboolean gst_audio_ring_buffer_pause (GstAudioRingBuffer *buf);
  200. GST_AUDIO_API
  201. gboolean gst_audio_ring_buffer_stop (GstAudioRingBuffer *buf);
  202. +GST_AUDIO_API
  203. +void gst_audio_ring_buffer_set_errored (GstAudioRingBuffer *buf);
  204. +
  205. /* get status */
  206. GST_AUDIO_API
  207. --
  208. GitLab