diff options
-rw-r--r-- | ext/hls/gsthlsdemux.c | 52 | ||||
-rw-r--r-- | ext/hls/gsthlsdemux.h | 1 |
2 files changed, 39 insertions, 14 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index b835acb78..bbd6bdd76 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -144,6 +144,11 @@ gst_hls_demux_dispose (GObject * obj) gst_hls_demux_reset (demux, TRUE); + if (demux->src_srcpad) { + gst_object_unref (demux->src_srcpad); + demux->src_srcpad = NULL; + } + g_mutex_clear (&demux->download_lock); g_cond_clear (&demux->download_cond); g_mutex_clear (&demux->updates_timed_lock); @@ -1011,13 +1016,11 @@ switch_pads (GstHLSDemux * demux) GstEvent *event; gchar *stream_id; gchar *name; - GstPad *target; GstPadTemplate *tmpl; GstProxyPad *internal_pad; GST_DEBUG_OBJECT (demux, "Switching pad (oldpad:%p)", oldpad); - target = gst_element_get_static_pad (demux->src, "src"); if (oldpad) { gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (oldpad), NULL); } @@ -1025,10 +1028,10 @@ switch_pads (GstHLSDemux * demux) /* First create and activate new pad */ name = g_strdup_printf ("src_%u", demux->srcpad_counter++); tmpl = gst_static_pad_template_get (&srctemplate); - demux->srcpad = gst_ghost_pad_new_from_template (name, target, tmpl); + demux->srcpad = + gst_ghost_pad_new_from_template (name, demux->src_srcpad, tmpl); gst_object_unref (tmpl); g_free (name); - gst_object_unref (target); /* set up our internal pad to drop all events from * the http src we don't care about. On the chain function @@ -1799,9 +1802,11 @@ gst_hls_demux_update_source (GstHLSDemux * demux, const gchar * uri, new_protocol = gst_uri_get_protocol (uri); if (!g_str_equal (old_protocol, new_protocol)) { + gst_object_unref (demux->src_srcpad); gst_element_set_state (demux->src, GST_STATE_NULL); gst_bin_remove (GST_BIN_CAST (demux), demux->src); demux->src = NULL; + demux->src_srcpad = NULL; GST_DEBUG_OBJECT (demux, "Can't re-use old source element"); } else { GError *err = NULL; @@ -1852,6 +1857,7 @@ gst_hls_demux_update_source (GstHLSDemux * demux, const gchar * uri, gst_element_set_locked_state (demux->src, TRUE); gst_bin_add (GST_BIN_CAST (demux), demux->src); + demux->src_srcpad = gst_element_get_static_pad (demux->src, "src"); } return TRUE; } @@ -1902,16 +1908,33 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux, if (gst_element_set_state (demux->src, GST_STATE_READY) != GST_STATE_CHANGE_FAILURE) { - gst_element_send_event (demux->src, gst_event_new_seek (1.0, - GST_FORMAT_BYTES, (GstSeekFlags) GST_SEEK_FLAG_FLUSH, - GST_SEEK_TYPE_SET, range_start, GST_SEEK_TYPE_SET, range_end)); + if (range_start != 0 || range_end != -1) { + if (!gst_element_send_event (demux->src, gst_event_new_seek (1.0, + GST_FORMAT_BYTES, (GstSeekFlags) GST_SEEK_FLAG_FLUSH, + GST_SEEK_TYPE_SET, range_start, GST_SEEK_TYPE_SET, + range_end))) { + + /* looks like the source can't handle seeks in READY */ + *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_NOT_IMPLEMENTED, + "Source element can't handle range requests"); + demux->last_ret = GST_FLOW_ERROR; + } + } + + if (G_LIKELY (demux->last_ret == GST_FLOW_OK)) { + /* flush the proxypads so that the EOS state is reset */ + gst_pad_push_event (demux->src_srcpad, gst_event_new_flush_start ()); + gst_pad_push_event (demux->src_srcpad, gst_event_new_flush_stop (TRUE)); - demux->download_start_time = g_get_monotonic_time (); - gst_element_sync_state_with_parent (demux->src); + demux->download_start_time = g_get_monotonic_time (); + gst_element_sync_state_with_parent (demux->src); - /* wait for the fragment to be completely downloaded */ - g_cond_wait (&demux->fragment_download_cond, - &demux->fragment_download_lock); + /* wait for the fragment to be completely downloaded */ + GST_DEBUG_OBJECT (demux, "Waiting for fragment download to finish: %s", + next_fragment_uri); + g_cond_wait (&demux->fragment_download_cond, + &demux->fragment_download_lock); + } } else { demux->last_ret = GST_FLOW_CUSTOM_ERROR; } @@ -1919,8 +1942,9 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux, if (demux->last_ret != GST_FLOW_OK) { gst_element_set_state (demux->src, GST_STATE_NULL); - *err = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED, - "Failed to download fragment"); + if (*err == NULL) + *err = g_error_new (GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_FAILED, + "Failed to download fragment"); } else { gst_element_set_state (demux->src, GST_STATE_READY); if (demux->segment.rate > 0) diff --git a/ext/hls/gsthlsdemux.h b/ext/hls/gsthlsdemux.h index 98daec948..988965c40 100644 --- a/ext/hls/gsthlsdemux.h +++ b/ext/hls/gsthlsdemux.h @@ -115,6 +115,7 @@ struct _GstHLSDemux /* fragment download tooling */ GstElement *src; + GstPad *src_srcpad; /* handy link to src's src pad */ GMutex fragment_download_lock; GCond fragment_download_cond; GstClockTime current_timestamp; |