mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
audiobasesrc: bail out if subclass posts an error
Use new ringbuffer ERROR state to make all the various threads bail out correctly when the subclass posts an error. It's a bit iffy to communicate this properly between the different bits of code. https://bugzilla.gnome.org/show_bug.cgi?id=690197
This commit is contained in:
parent
4f49c7a33b
commit
68f366a8d3
1 changed files with 41 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue