diff --git a/gst-libs/gst/audio/gstaudiobasesrc.c b/gst-libs/gst/audio/gstaudiobasesrc.c index 99d5827670..820e0f9c0f 100644 --- a/gst-libs/gst/audio/gstaudiobasesrc.c +++ b/gst-libs/gst/audio/gstaudiobasesrc.c @@ -130,7 +130,8 @@ static void gst_audio_base_src_dispose (GObject * object); static GstStateChangeReturn gst_audio_base_src_change_state (GstElement * element, GstStateChange transition); - +static gboolean gst_audio_base_src_post_message (GstElement * element, + GstMessage * message); static GstClock *gst_audio_base_src_provide_clock (GstElement * elem); static GstClockTime gst_audio_base_src_get_time (GstClock * clock, GstAudioBaseSrc * src); @@ -215,6 +216,8 @@ gst_audio_base_src_class_init (GstAudioBaseSrcClass * klass) GST_DEBUG_FUNCPTR (gst_audio_base_src_change_state); gstelement_class->provide_clock = GST_DEBUG_FUNCPTR (gst_audio_base_src_provide_clock); + gstelement_class->post_message = + GST_DEBUG_FUNCPTR (gst_audio_base_src_post_message); gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_audio_base_src_setcaps); gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_audio_base_src_event); @@ -825,6 +828,10 @@ gst_audio_base_src_create (GstBaseSrc * bsrc, guint64 offset, guint length, if (read == samples) break; + if (g_atomic_int_get (&ringbuffer->state) == + GST_AUDIO_RING_BUFFER_STATE_ERROR) + goto got_error; + /* else something interrupted us and we wait for playing again. */ GST_DEBUG_OBJECT (src, "wait playing"); if (gst_base_src_wait_playing (bsrc) != GST_FLOW_OK) @@ -1063,6 +1070,12 @@ stopped: GST_DEBUG_OBJECT (src, "ringbuffer stopped"); return GST_FLOW_FLUSHING; } +got_error: + { + gst_buffer_unref (buf); + GST_DEBUG_OBJECT (src, "ringbuffer was in error state, bailing out"); + return GST_FLOW_ERROR; + } } /** @@ -1180,3 +1193,30 @@ open_failed: } } + +static gboolean +gst_audio_base_src_post_message (GstElement * element, GstMessage * message) +{ + GstAudioBaseSrc *src = GST_AUDIO_BASE_SRC (element); + gboolean ret; + + if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) { + GstAudioRingBuffer *ringbuffer; + + GST_INFO_OBJECT (element, "subclass posted error"); + + ringbuffer = gst_object_ref (src->ringbuffer); + + /* post message first before signalling the error to the ringbuffer, to + * make sure it ends up on the bus before the generic basesrc internal + * 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_SIGNAL (ringbuffer); + gst_object_unref (ringbuffer); + } else { + ret = GST_ELEMENT_CLASS (parent_class)->post_message (element, message); + } + return ret; +}