diff --git a/ChangeLog b/ChangeLog index 02ecf27cf2..e4d9304ee4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2006-03-17 Wim Taymans + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_change_state): + * gst-libs/gst/audio/gstringbuffer.c: (wait_segment), + (gst_ring_buffer_may_start): + * gst-libs/gst/audio/gstringbuffer.h: + Only start playback if we are playing. + should fix #330748. + 2006-03-17 Jan Schmidt * ext/alsa/gstalsasink.c: (gst_alsasink_getcaps): diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 26026cb901..fdbd951a48 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -707,14 +707,17 @@ gst_base_audio_sink_change_state (GstElement * element, goto open_failed; break; case GST_STATE_CHANGE_READY_TO_PAUSED: - gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE); sink->next_sample = -1; + gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE); + gst_ring_buffer_may_start (sink->ringbuffer, FALSE); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: { GstClock *clock; GstClockTime time, base; + gst_ring_buffer_may_start (sink->ringbuffer, TRUE); + GST_OBJECT_LOCK (sink); clock = GST_ELEMENT_CLOCK (sink); if (clock == NULL) @@ -746,6 +749,8 @@ gst_base_audio_sink_change_state (GstElement * element, break; } case GST_STATE_CHANGE_PLAYING_TO_PAUSED: + /* ringbuffer cannot start anymore */ + gst_ring_buffer_may_start (sink->ringbuffer, FALSE); gst_ring_buffer_pause (sink->ringbuffer); break; case GST_STATE_CHANGE_PAUSED_TO_READY: diff --git a/gst-libs/gst/audio/gstringbuffer.c b/gst-libs/gst/audio/gstringbuffer.c index 5e71269deb..5abede7ef3 100644 --- a/gst-libs/gst/audio/gstringbuffer.c +++ b/gst-libs/gst/audio/gstringbuffer.c @@ -1077,6 +1077,10 @@ wait_segment (GstRingBuffer * buf) /* buffer must be started now or we deadlock since nobody is reading */ if (G_UNLIKELY (g_atomic_int_get (&buf->state) != GST_RING_BUFFER_STATE_STARTED)) { + /* see if we are allowed to start it */ + if (G_UNLIKELY (g_atomic_int_get (&buf->abidata.ABI.may_start) == FALSE)) + goto no_start; + GST_DEBUG_OBJECT (buf, "start!"); gst_ring_buffer_start (buf); } @@ -1120,6 +1124,11 @@ flushing: GST_OBJECT_UNLOCK (buf); return FALSE; } +no_start: + { + GST_DEBUG_OBJECT (buf, "not allowed to start"); + return FALSE; + } } /** @@ -1455,3 +1464,22 @@ gst_ring_buffer_clear (GstRingBuffer * buf, gint segment) memcpy (data, buf->empty_seg, buf->spec.segsize); } + +/** + * gst_ring_buffer_may_start: + * @buf: the #GstRingBuffer + * @allowed: the new value + * + * Tell the ringbuffer that it is allowed to start playback when + * the ringbuffer is filled with samples. + * + * Since: 0.10.6 + * + * MT safe. + */ +void +gst_ring_buffer_may_start (GstRingBuffer * buf, gboolean allowed) +{ + GST_LOG_OBJECT (buf, "may start: %d", allowed); + gst_atomic_int_set (&buf->abidata.ABI.may_start, allowed); +} diff --git a/gst-libs/gst/audio/gstringbuffer.h b/gst-libs/gst/audio/gstringbuffer.h index b0040b5386..9fd5aeffd5 100644 --- a/gst-libs/gst/audio/gstringbuffer.h +++ b/gst-libs/gst/audio/gstringbuffer.h @@ -243,6 +243,8 @@ struct _GstRingBuffer { union { struct { gboolean flushing; + /* ATOMIC */ + gint may_start; } ABI; /* adding + 0 to mark ABI change to be undone later */ gpointer _gst_reserved[GST_PADDING + 0]; @@ -335,6 +337,9 @@ gboolean gst_ring_buffer_prepare_read (GstRingBuffer *buf, gint *segme void gst_ring_buffer_clear (GstRingBuffer *buf, gint segment); void gst_ring_buffer_advance (GstRingBuffer *buf, guint advance); +void gst_ring_buffer_may_start (GstRingBuffer *buf, gboolean allowed); + + G_END_DECLS #endif /* __GST_RING_BUFFER_H__ */