hlsdemux: Search more when advancing fragment
authorEdward Hervey <edward@centricular.com>
Thu, 28 May 2015 12:30:46 +0000 (14:30 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Thu, 28 May 2015 12:56:36 +0000 (14:56 +0200)
In live situations, it is not uncommon for the current fragment to end
up out of the (updated) play range (lowest/highest sequence). But the next
fragment to play *is* present in the play range.

When advancing, if we can't find the current GstM3U8MediaFile, don't abort
straight away. Instead, look if a GstM3U8MediaFile with the next sequence value
is present, and if so switch to it.

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

ext/hls/m3u8.c

index bf33793..3f3c278 100755 (executable)
@@ -1085,6 +1085,40 @@ gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward)
   return ret;
 }
 
+static void
+alternate_advance (GstM3U8Client * client, gboolean forward)
+{
+  gint targetnum = client->sequence;
+  GList *tmp;
+  GstM3U8MediaFile *mf;
+
+  /* figure out the target seqnum */
+  if (forward)
+    targetnum += 1;
+  else
+    targetnum -= 1;
+
+  for (tmp = client->current->files; tmp; tmp = tmp->next) {
+    mf = (GstM3U8MediaFile *) tmp->data;
+    if (mf->sequence == targetnum)
+      break;
+  }
+  if (tmp == NULL) {
+    GST_ERROR ("Can't find next fragment");
+    return;
+  }
+  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;
+  }
+}
+
 void
 gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
 {
@@ -1101,7 +1135,9 @@ gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
     l = g_list_find_custom (client->current->files, client,
         (GCompareFunc) _find_current);
     if (l == NULL) {
-      GST_ERROR ("Could not find current fragment");
+      GST_DEBUG
+          ("Could not find current fragment, trying next fragment directly");
+      alternate_advance (client, forward);
       GST_M3U8_CLIENT_UNLOCK (client);
       return;
     }