switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
GST_MANIFEST_LOCK (demux);
+ demux->running = FALSE;
gst_adaptive_demux_reset (demux);
GST_MANIFEST_UNLOCK (demux);
break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ GST_MANIFEST_LOCK (demux);
+ demux->running = TRUE;
+ GST_MANIFEST_UNLOCK (demux);
+ break;
default:
break;
}
demux->streams = demux->next_streams;
demux->next_streams = NULL;
- /* First ensure all on-going downloads are finished or cancelled */
- GST_MANIFEST_UNLOCK (demux);
- for (iter = old_streams; iter; iter = g_list_next (iter)) {
- GstAdaptiveDemuxStream *stream = iter->data;
- g_mutex_lock (&stream->fragment_download_lock);
- while (!stream->cancelled && !stream->download_finished) {
- GST_DEBUG_OBJECT (stream->pad,
- "Waiting for download on active stream to finish");
- g_cond_wait (&stream->fragment_download_cond,
- &stream->fragment_download_lock);
- }
- g_mutex_unlock (&stream->fragment_download_lock);
+ if (!demux->running) {
+ GST_DEBUG_OBJECT (demux, "Not exposing pads due to shutdown");
+ return TRUE;
}
- GST_MANIFEST_LOCK (demux);
for (iter = demux->streams; iter; iter = g_list_next (iter)) {
GstAdaptiveDemuxStream *stream = iter->data;
if (stream->src) {
GST_MANIFEST_UNLOCK (demux);
+ gst_element_set_locked_state (stream->src, TRUE);
gst_element_set_state (stream->src, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (demux), stream->src);
stream->src = NULL;
stream = gst_adaptive_demux_find_stream_for_pad (demux, pad);
if (stream) {
- if (stream->last_ret == GST_FLOW_NOT_LINKED) {
+ if (!stream->cancelled && demux->running &&
+ stream->last_ret == GST_FLOW_NOT_LINKED) {
stream->last_ret = GST_FLOW_OK;
stream->restart_download = TRUE;
stream->need_header = TRUE;
{
GList *iter;
+ if (!demux->running) {
+ GST_DEBUG_OBJECT (demux, "Not starting tasks due to shutdown");
+ return;
+ }
+
GST_INFO_OBJECT (demux, "Starting streams' tasks");
for (iter = demux->streams; iter; iter = g_list_next (iter)) {
GstAdaptiveDemuxStream *stream = iter->data;
GST_MANIFEST_UNLOCK (demux);
if (src) {
+ gst_element_set_locked_state (stream->src, TRUE);
gst_element_set_state (src, GST_STATE_READY);
}
if (!g_str_equal (old_protocol, new_protocol)) {
gst_object_unref (stream->src_srcpad);
+ gst_element_set_locked_state (stream->src, TRUE);
gst_element_set_state (stream->src, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (demux), stream->src);
stream->src = NULL;
err->message);
g_clear_error (&err);
gst_object_unref (stream->src_srcpad);
+ gst_element_set_locked_state (stream->src, TRUE);
gst_element_set_state (stream->src, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (demux), stream->src);
stream->src = NULL;
return TRUE;
}
+
+static GstPadProbeReturn
+gst_ad_stream_src_to_ready_cb (GstPad * pad, GstPadProbeInfo * info,
+ gpointer user_data)
+{
+ GstAdaptiveDemuxStream *stream = user_data;
+
+ /* The source's src pad is IDLE so now set the state to READY */
+ g_mutex_lock (&stream->fragment_download_lock);
+ stream->src_at_ready = TRUE;
+ g_cond_signal (&stream->fragment_download_cond);
+ g_mutex_unlock (&stream->fragment_download_lock);
+
+ return GST_PAD_PROBE_OK;
+}
+
/* must be called with manifest_lock taken.
* Can temporarily release manifest_lock
*/
return ret;
}
+ gst_element_set_locked_state (stream->src, TRUE);
+
if (gst_element_set_state (stream->src,
GST_STATE_READY) != GST_STATE_CHANGE_FAILURE) {
if (start != 0 || end != -1) {
"Waiting for fragment download to finish: %s", uri);
g_mutex_lock (&stream->fragment_download_lock);
+ stream->src_at_ready = FALSE;
if (G_UNLIKELY (stream->cancelled)) {
g_mutex_unlock (&stream->fragment_download_lock);
GST_MANIFEST_LOCK (demux);
*/
GST_MANIFEST_UNLOCK (demux);
- /* FIXME: Wait until the src pad is IDLE, as it might be blocked
- * downstream indefinitely here */
+ stream->src_at_ready = FALSE;
+
+ gst_element_set_locked_state (stream->src, TRUE);
+ gst_pad_add_probe (stream->src_srcpad, GST_PAD_PROBE_TYPE_IDLE,
+ gst_ad_stream_src_to_ready_cb, stream, NULL);
+
+ g_mutex_lock (&stream->fragment_download_lock);
+ while (!stream->src_at_ready) {
+ g_cond_wait (&stream->fragment_download_cond,
+ &stream->fragment_download_lock);
+ }
+ g_mutex_unlock (&stream->fragment_download_lock);
+
gst_element_set_state (stream->src, GST_STATE_READY);
+ /* Need to drop the fragment_download_lock to get the MANIFEST lock */
GST_MANIFEST_LOCK (demux);
g_mutex_lock (&stream->fragment_download_lock);
if (G_UNLIKELY (stream->cancelled)) {
gst_task_stop (stream->download_task);
if (stream->src) {
+ gst_element_set_locked_state (stream->src, TRUE);
gst_element_set_state (stream->src, GST_STATE_NULL);
gst_bin_remove (GST_BIN_CAST (demux), stream->src);
stream->src = NULL;