After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 753344 - hlsdemux: Fix playback of live streams
hlsdemux: Fix playback of live streams
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gst-plugins-bad
1.5.2
Other Mac OS
: Normal normal
: 1.5.91
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2015-08-07 07:51 UTC by alexvrs
Modified: 2015-08-28 18:28 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Patch for fix from ruDREAM for problem playing live HLS stream (3.31 KB, application/zip)
2015-08-07 07:51 UTC, alexvrs
  Details
fix_hlsdemux_hls_live.patch (1.17 KB, patch)
2015-08-07 08:07 UTC, Sebastian Dröge (slomo)
reviewed Details | Review
hlsdemux: select correct position for live streams that don't remove fragments (1.88 KB, patch)
2015-08-07 10:20 UTC, Athanasios Oikonomou
none Details | Review
hlsdemux: select correct position for live streams that don't remove fragments (1.88 KB, patch)
2015-08-07 10:28 UTC, Athanasios Oikonomou
committed Details | Review

Description alexvrs 2015-08-07 07:51:56 UTC
Created attachment 308878 [details]
Patch for fix from ruDREAM for problem playing live HLS stream

diff -u --recursive --new-file original/ext/hls/m3u8.c new/ext/hls/m3u8.c
--- original/ext/hls/m3u8.c	2015-06-07 10:04:45.000000000 +0300
+++ new/ext/hls/m3u8.c	2015-08-06 23:41:02.348000058 +0300
@@ -850,7 +850,6 @@
   }
 
   if (m3u8->files && self->sequence == -1) {
-    self->current_file = g_list_first (m3u8->files);
     if (GST_M3U8_CLIENT_IS_LIVE (self)) {
       /* for live streams, start GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE from
          the end of the playlist. See section 6.3.3 of HLS draft */
@@ -859,8 +858,10 @@
       self->sequence =
           GST_M3U8_MEDIA_FILE (g_list_nth_data (m3u8->files,
               pos >= 0 ? pos : 0))->sequence;
-    } else
+    } else {
+      self->current_file = g_list_first (m3u8->files);
       self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
+    }
     self->sequence_position = 0;
     GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
   }
Comment 1 Sebastian Dröge (slomo) 2015-08-07 08:07:46 UTC
Created attachment 308879 [details] [review]
fix_hlsdemux_hls_live.patch

Patch from the attached zip file.

Can you explain what this fixes and why this fix is correct?
Comment 2 Sebastian Dröge (slomo) 2015-08-07 08:27:52 UTC
Some more info from IRC earlier:

<gstreamer984> Hi
<gstreamer984> Hls has a bug on live streams from youtube, it goes 4 hours back instead going live. Here is a fix http://forums.openpli.org/topic/38572-problem-playing-live-hls-stream-with-gstreamer/#entry500444
<gstreamer984> Also maybe self->current_file should be g_list_nth_data (m3u8->files,  pos >= 0 ? pos : 0)) when live?
Comment 3 Athanasios Oikonomou 2015-08-07 08:39:32 UTC
I added the info on IRC, but better to add info here.

The current_file should point to file where sequence is, right? 

Currenlty it points to first file for live and vod. Maybe something like the following required. 

if(live)
 self->current_file = g_list_nth_data (m3u8->files, pos >= 0 ? pos : 0)
else
 self->current_file = g_list_first (m3u8->files);

Because using above patch current_file has no value when live.
Comment 4 alexvrs 2015-08-07 08:56:13 UTC
For those who do not understand that the changes the patch:

Otherwise after using GST_M3U8_CLIENT_IS_LIVE = True:
Setting first sequence from the END of the playlist,
in gst_m3u8_client_has_next_fragment function in code:

   if (! client-> current_file) {
     client-> current_file =
         find_next_fragment (client, client-> current-> files, forward);
   }
The following function is not executed:
find_next_fragment (client-> current_file has already been appointed)
as well as the following code not executed too:

client-> sequence = file-> sequence;
And setting up again the:
Setting first sequence from the TOP of the playlist
Comment 5 alexvrs 2015-08-07 08:57:25 UTC
Debug log do fix:

0:00:12.421533696   987   0x74b1b0 DEBUG             fragmented m3u8.c:865:gst_m3u8_client_update: Setting first sequence at 2194818
0:00:12.449049215   987   0x74b1b0 DEBUG             fragmented m3u8.c:1021:gst_m3u8_client_get_next_fragment: Looking for fragment 2194818
0:00:12.449157733   987   0x74b1b0 DEBUG             fragmented m3u8.c:1038:gst_m3u8_client_get_next_fragment: Got fragment with sequence 2191939 (client sequence 2194818) #ERROR Lowered sequence, but should be increased
0:00:12.452527585   987   0x691800 DEBUG             fragmented m3u8.c:1021:gst_m3u8_client_get_next_fragment: Looking for fragment 2191939
0:00:12.452665474   987   0x691800 DEBUG             fragmented m3u8.c:1038:gst_m3u8_client_get_next_fragment: Got fragment with sequence 2191939 (client sequence 2191939)
0:00:22.092428876   987   0x5c9920 DEBUG             fragmented m3u8.c:1148:gst_m3u8_client_advance_fragment: Advancing from sequence 2191939


Debug log after fix:

0:00:14.934132806  1827   0x79a7b0 DEBUG             fragmented m3u8.c:867:gst_m3u8_client_update: Setting first sequence at 2198075
0:00:14.960840954  1827   0x79a7b0 DEBUG             fragmented m3u8.c:1028:gst_m3u8_client_get_next_fragment: Looking for fragment 2198075
0:00:15.328647991  1827   0x6e1200 DEBUG             fragmented m3u8.c:1047:gst_m3u8_client_get_next_fragment: Got fragment with sequence 2198075 (client sequence 2198075) #OK
0:00:23.860507431  1827   0x61a920 DEBUG             fragmented m3u8.c:1163:gst_m3u8_client_advance_fragment: Advancing from sequence 2198075 #OK
0:00:23.891802171  1827   0x6e1200 DEBUG             fragmented m3u8.c:1028:gst_m3u8_client_get_next_fragment: Looking for fragment 2198076 #OK sequence increased 
0:00:23.891868542  1827   0x6e1200 DEBUG             fragmented m3u8.c:1047:gst_m3u8_client_get_next_fragment: Got fragment with sequence 2198076 (client sequence 2198076) forward #OK
Comment 6 Athanasios Oikonomou 2015-08-07 09:05:42 UTC
@alexvrs, Could you please try one also? 

diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index 5e78d94..4ca761c 100755
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -850,17 +850,20 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
   }
 
   if (m3u8->files && self->sequence == -1) {
-    self->current_file = g_list_first (m3u8->files);
     if (GST_M3U8_CLIENT_IS_LIVE (self)) {
       /* for live streams, start GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE from
          the end of the playlist. See section 6.3.3 of HLS draft */
       gint pos =
           g_list_length (m3u8->files) - GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE;
+      self->current_file = g_list_nth (m3u8->files,
+              pos >= 0 ? pos : 0)
       self->sequence =
           GST_M3U8_MEDIA_FILE (g_list_nth_data (m3u8->files,
               pos >= 0 ? pos : 0))->sequence;
-    } else
+    } else {
+      self->current_file = g_list_first (m3u8->files);
       self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
+    }
     self->sequence_position = 0;
     GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
   }


The only difference is that will set current_file to the same file that sequence points. So it will use the last 3 segments from list and then will request the next segment.
Comment 7 Athanasios Oikonomou 2015-08-07 09:14:15 UTC
@alexvrs, here is a a simplified version (it will set the sequence using current_file).

diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index 5e78d94..c080a95 100755
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -850,17 +850,16 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
   }
 
   if (m3u8->files && self->sequence == -1) {
-    self->current_file = g_list_first (m3u8->files);
     if (GST_M3U8_CLIENT_IS_LIVE (self)) {
       /* for live streams, start GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE from
          the end of the playlist. See section 6.3.3 of HLS draft */
       gint pos =
           g_list_length (m3u8->files) - GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE;
-      self->sequence =
-          GST_M3U8_MEDIA_FILE (g_list_nth_data (m3u8->files,
-              pos >= 0 ? pos : 0))->sequence;
+      self->current_file = g_list_nth (m3u8->files,
+              pos >= 0 ? pos : 0)
     } else
-      self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
+      self->current_file = g_list_first (m3u8->files);
+    self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
     self->sequence_position = 0;
     GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
   }
Comment 8 alexvrs 2015-08-07 09:21:56 UTC
@Athanasios Oikonomou

Nice
Comment 9 Sebastian Dröge (slomo) 2015-08-07 09:32:39 UTC
Can you attach as a git format-patch style format, explain the actual problem and what the fix is (in the commit message)?
Comment 10 alexvrs 2015-08-07 09:55:03 UTC
@Athanasios Oikonomou

small syntax fix:

diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index 5e78d94..c080a95 100755
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -850,17 +850,16 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
   }
 
   if (m3u8->files && self->sequence == -1) {
-    self->current_file = g_list_first (m3u8->files);
     if (GST_M3U8_CLIENT_IS_LIVE (self)) {
       /* for live streams, start GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE from
          the end of the playlist. See section 6.3.3 of HLS draft */
       gint pos =
           g_list_length (m3u8->files) - GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE;
-      self->sequence =
-          GST_M3U8_MEDIA_FILE (g_list_nth_data (m3u8->files,
-              pos >= 0 ? pos : 0))->sequence;
+      self->current_file = g_list_nth (m3u8->files,
+              pos >= 0 ? pos : 0);
     } else
-      self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
+      self->current_file = g_list_first (m3u8->files);
+    self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
     self->sequence_position = 0;
     GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
   }
Comment 11 Athanasios Oikonomou 2015-08-07 10:20:53 UTC
Created attachment 308887 [details] [review]
hlsdemux: select correct position for live streams that  don't remove fragments
Comment 12 Athanasios Oikonomou 2015-08-07 10:28:19 UTC
Created attachment 308888 [details] [review]
hlsdemux: select correct position for live streams that  don't remove fragments

Add a missing semicolon. Thanks @alexvrs
Comment 13 Athanasios Oikonomou 2015-08-07 10:39:52 UTC
Review of attachment 308879 [details] [review]:

We need to set the correct fragment to self->current_file for both live and vod streams.
Comment 14 Athanasios Oikonomou 2015-08-25 15:17:40 UTC
Is it possible to somebody to have a look please? 

It would be nice to have that problem fixes before 1.6 version released.
Comment 15 Sebastian Dröge (slomo) 2015-08-26 09:13:12 UTC
commit 22456ce0328a8d06a12997979a143a0103867a49
Author: Athanasios Oikonomou <athoik@gmail.com>
Date:   Fri Aug 7 12:53:23 2015 +0300

    hlsdemux: select correct position for live streams that don't remove fragments
    
    Some live streams (eg youtube) don't remove fragments in order to allow
    seeking back in time (live + vod).
    
    When gst_m3u8_client_has_next_fragment is called, we are getting wrong fragment
    because current_file points in first file of the fragments list resulting in
    watching the stream from the beginning again.
    
    This patch sets current_file to nth fragment for live streams, then on
    gst_m3u8_client_has_next_fragment will keep up with the live stream.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=753344