+diff --git a/gst/hls/gsthlsdemux.c b/gst/hls/gsthlsdemux.c
+index 3308a29..09acee1 100644
+--- a/gst/hls/gsthlsdemux.c
++++ b/gst/hls/gsthlsdemux.c
+@@ -315,14 +315,6 @@ gst_hls_demux_change_state (GstElement * element, GstStateChange transition)
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ gst_hls_demux_reset (demux, FALSE);
+ break;
+- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+- /* Start the streaming loop in paused only if we already received
+- the main playlist. It might have been stopped if we were in PAUSED
+- state and we filled our queue with enough cached fragments
+- */
+- if (gst_m3u8_client_get_uri (demux->client)[0] != '\0')
+- gst_task_start (demux->updates_task);
+- break;
+ default:
+ break;
+ }
+@@ -330,17 +322,6 @@ gst_hls_demux_change_state (GstElement * element, GstStateChange transition)
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+
+ switch (transition) {
+- case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
+- demux->cancelled = TRUE;
+- gst_uri_downloader_cancel (demux->downloader);
+- gst_task_stop (demux->updates_task);
+- g_mutex_lock (demux->updates_timed_lock);
+- GST_TASK_SIGNAL (demux->updates_task);
+- g_mutex_unlock (demux->updates_timed_lock);
+- g_static_rec_mutex_lock (&demux->updates_lock);
+- g_static_rec_mutex_unlock (&demux->updates_lock);
+- demux->cancelled = FALSE;
+- break;
+ case GST_STATE_CHANGE_PAUSED_TO_READY:
+ demux->cancelled = TRUE;
+ gst_hls_demux_stop (demux);
+@@ -718,14 +699,14 @@ gst_hls_demux_stream_loop (GstHLSDemux * demux)
+ * cache the first fragments and then it waits until it has more data in the
+ * queue. This task is woken up when we push a new fragment to the queue or
+ * when we reached the end of the playlist */
++ GST_DEBUG_OBJECT (demux, "Enter task");
+
+ if (G_UNLIKELY (demux->need_cache)) {
+ if (!gst_hls_demux_cache_fragments (demux))
+ goto cache_error;
+
+ /* we can start now the updates thread (only if on playing) */
+- if (GST_STATE (demux) == GST_STATE_PLAYING)
+- gst_task_start (demux->updates_task);
++ gst_task_start (demux->updates_task);
+ GST_INFO_OBJECT (demux, "First fragments cached successfully");
+ }
+
+@@ -765,10 +746,14 @@ gst_hls_demux_stream_loop (GstHLSDemux * demux)
+ demux->position_shift = 0;
+ }
+
++ GST_DEBUG_OBJECT (demux, "Pushing buffer %p", buf);
++
+ ret = gst_pad_push_list (demux->srcpad, buffer_list);
+ if (ret != GST_FLOW_OK)
+ goto error_pushing;
+
++ GST_DEBUG_OBJECT (demux, "Pushed buffer");
++
+ return;
+
+ end_of_playlist:
+@@ -806,6 +791,7 @@ error_pushing:
+
+ pause_task:
+ {
++ GST_DEBUG_OBJECT (demux, "Pause task");
+ gst_task_pause (demux->stream_task);
+ return;
+ }
+@@ -877,10 +863,13 @@ gst_hls_demux_updates_loop (GstHLSDemux * demux)
+ gst_hls_demux_schedule (demux);
+
+ /* block until the next scheduled update or the signal to quit this thread */
++ GST_DEBUG_OBJECT (demux, "Waiting");
+ if (g_cond_timed_wait (GST_TASK_GET_COND (demux->updates_task),
+ demux->updates_timed_lock, &demux->next_update)) {
++ GST_DEBUG_OBJECT (demux, "Unlocked");
+ goto quit;
+ }
++ GST_DEBUG_OBJECT (demux, "Continue");
+
+ if (demux->cancelled)
+ goto quit;
+@@ -918,6 +907,7 @@ gst_hls_demux_updates_loop (GstHLSDemux * demux)
+
+ /* fetch the next fragment */
+ if (g_queue_is_empty (demux->queue)) {
++ GST_DEBUG_OBJECT (demux, "queue empty, get next fragment");
+ if (!gst_hls_demux_get_next_fragment (demux, FALSE)) {
+ if (demux->cancelled) {
+ goto quit;
+@@ -1289,6 +1279,7 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux, gboolean caching)
+ GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+ }
+
++ GST_DEBUG_OBJECT (demux, "Pushing fragment in queue");
+ g_queue_push_tail (demux->queue, download);
+ gst_buffer_list_unref (buffer_list);
+ if (!caching) {
+diff --git a/gst/hls/m3u8.c b/gst/hls/m3u8.c
+index 65afa8b..b6c04a8 100644
+--- a/gst/hls/m3u8.c
++++ b/gst/hls/m3u8.c
+@@ -37,6 +37,7 @@ static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data,
+ static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
+ gchar * title, GstClockTime duration, guint sequence);
+ static void gst_m3u8_media_file_free (GstM3U8MediaFile * self);
++gchar *uri_join (const gchar * uri, const gchar * path);
+
+ static GstM3U8 *
+ gst_m3u8_new (void)
+@@ -270,24 +271,9 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
+ goto next_line;
+ }
+
+- if (!gst_uri_is_valid (data)) {
+- gchar *slash;
+- if (!self->uri) {
+- GST_WARNING ("uri not set, can't build a valid uri");
+- goto next_line;
+- }
+- slash = g_utf8_strrchr (self->uri, -1, '/');
+- if (!slash) {
+- GST_WARNING ("Can't build a valid uri");
+- goto next_line;
+- }
+-
+- *slash = '\0';
+- data = g_strdup_printf ("%s/%s", self->uri, data);
+- *slash = '/';
+- } else {
+- data = g_strdup (data);
+- }
++ data = uri_join (self->uri, data);
++ if (data == NULL)
++ goto next_line;
+
+ r = g_utf8_strchr (data, -1, '\r');
+ if (r)
+@@ -674,3 +660,51 @@ gst_m3u8_client_get_playlist_for_bitrate (GstM3U8Client * client, guint bitrate)
+
+ return current_variant;
+ }
++
++gchar *
++uri_join (const gchar * uri1, const gchar * uri2)
++{
++ gchar *uri_copy, *tmp, *ret = NULL;
++
++ if (gst_uri_is_valid (uri2))
++ return g_strdup (uri2);
++
++ uri_copy = g_strdup (uri1);
++ if (uri2[0] != '/') {
++ /* uri2 is a relative uri2 */
++ tmp = g_utf8_strrchr (uri_copy, -1, '/');
++ if (!tmp) {
++ GST_WARNING ("Can't build a valid uri_copy");
++ goto out;
++ }
++
++ *tmp = '\0';
++ ret = g_strdup_printf ("%s/%s", uri_copy, uri2);
++ } else {
++ /* uri2 is an absolute uri2 */
++ char *scheme, *hostname;
++
++ scheme = uri_copy;
++ /* find the : in <scheme>:// */
++ tmp = g_utf8_strchr (uri_copy, -1, ':');
++ if (!tmp) {
++ GST_WARNING ("Can't build a valid uri_copy");
++ goto out;
++ }
++
++ *tmp = '\0';
++
++ /* skip :// */
++ hostname = tmp + 3;
++
++ tmp = g_utf8_strchr (hostname, -1, '/');
++ if (tmp)
++ *tmp = '\0';
++
++ ret = g_strdup_printf ("%s://%s%s", scheme, hostname, uri2);
++ }
++
++out:
++ g_free (uri_copy);
++ return ret;
++}