hls/m3u8: Update current position in all cases
authorEdward Hervey <edward@centricular.com>
Wed, 8 Jul 2015 15:17:12 +0000 (17:17 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Tue, 20 Oct 2015 07:12:32 +0000 (10:12 +0300)
In order to ensure the sequence_position will always be consistently updated,
store the current file duration.

This way, when we advance, we can always increment the position based on what
was previously outputted.

https://bugzilla.gnome.org/show_bug.cgi?id=752132

ext/hls/m3u8.c
ext/hls/m3u8.h

index b931749fa86e56f52cf54e72b97d76dfce3f2403..eca283b421bdb3814eaa3650d3c81b686074b52c 100644 (file)
@@ -782,6 +782,7 @@ gst_m3u8_client_new (const gchar * uri, const gchar * base_uri)
   client->main = gst_m3u8_new ();
   client->current = NULL;
   client->current_file = NULL;
+  client->current_file_duration = GST_CLOCK_TIME_NONE;
   client->sequence = -1;
   client->sequence_position = 0;
   client->update_failed_count = 0;
@@ -1039,6 +1040,7 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
   GST_DEBUG ("Got fragment with sequence %u (client sequence %u)",
       (guint) file->sequence, (guint) client->sequence);
 
+  client->current_file_duration = file->duration;
   if (timestamp)
     *timestamp = client->sequence_position;
 
@@ -1111,14 +1113,8 @@ alternate_advance (GstM3U8Client * client, gboolean forward)
   }
   client->current_file = tmp;
   client->sequence = targetnum;
-  if (forward)
-    client->sequence_position += mf->duration;
-  else {
-    if (client->sequence_position > mf->duration)
-      client->sequence_position -= mf->duration;
-    else
-      client->sequence_position = 0;
-  }
+  client->current_file_duration =
+      GST_M3U8_MEDIA_FILE (client->current_file->data)->duration;
 }
 
 void
@@ -1130,6 +1126,20 @@ gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
   g_return_if_fail (client->current != NULL);
 
   GST_M3U8_CLIENT_LOCK (client);
+  GST_DEBUG ("Sequence position was %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (client->sequence_position));
+  if (GST_CLOCK_TIME_IS_VALID (client->current_file_duration)) {
+    /* Advance our position based on the previous fragment we played */
+    if (forward)
+      client->sequence_position += client->current_file_duration;
+    else if (client->current_file_duration < client->sequence_position)
+      client->sequence_position -= client->current_file_duration;
+    else
+      client->sequence_position = 0;
+    client->current_file_duration = GST_CLOCK_TIME_NONE;
+    GST_DEBUG ("Sequence position now %" GST_TIME_FORMAT,
+        GST_TIME_ARGS (client->sequence_position));
+  }
   if (!client->current_file) {
     GList *l;
 
@@ -1156,8 +1166,6 @@ gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
     } else {
       client->sequence = file->sequence + 1;
     }
-
-    client->sequence_position += file->duration;
   } else {
     client->current_file = client->current_file->prev;
     if (client->current_file) {
@@ -1166,11 +1174,12 @@ gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
     } else {
       client->sequence = file->sequence - 1;
     }
-
-    if (client->sequence_position > file->duration)
-      client->sequence_position -= file->duration;
-    else
-      client->sequence_position = 0;
+  }
+  if (client->current_file) {
+    /* Store duration of the fragment we're using to update the position 
+     * the next time we advance */
+    client->current_file_duration =
+        GST_M3U8_MEDIA_FILE (client->current_file->data)->duration;
   }
   GST_M3U8_CLIENT_UNLOCK (client);
 }
index 6c4b6c6bddd9045881e190f449bcbd71f8c3a930..7b09de165cd89a06ddba17232b461985a8da59ae 100644 (file)
@@ -96,6 +96,7 @@ struct _GstM3U8Client
   GstM3U8 *current;
   guint update_failed_count;
   GList *current_file;
+  GstClockTime current_file_duration; /* Duration of current fragment */
   gint64 sequence;              /* the next sequence for this client */
   GstClockTime sequence_position; /* position of this sequence */
   gint64 highest_sequence_number; /* largest seen sequence number */