From b3a72429107b5f9dea2633735314c07b065f233a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sun, 23 Feb 2014 15:18:22 +0100 Subject: [PATCH] hlsdemux: Keep track of timestamps by adding them up during playback ...instead of adding them from the start of playlist every time. This among other things fixes timestamps for live streams, where the playlist is some kind of ringbuffer of fragments and thus adding from the beginning of the playlist will miss the past fragments. https://bugzilla.gnome.org/show_bug.cgi?id=724983 --- ext/hls/gsthlsdemux.c | 6 +++--- ext/hls/m3u8.c | 23 ++++------------------- ext/hls/m3u8.h | 3 +-- 3 files changed, 8 insertions(+), 24 deletions(-) diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index 2563e3aeb6..bcc045078d 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -329,7 +329,7 @@ gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) GstSeekType start_type, stop_type; gint64 start, stop; GList *walk; - GstClockTime position, current_pos, target_pos; + GstClockTime current_pos, target_pos; gint current_sequence; GstM3U8MediaFile *file; @@ -388,8 +388,8 @@ gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) GST_M3U8_CLIENT_LOCK (demux->client); GST_DEBUG_OBJECT (demux, "seeking to sequence %d", current_sequence); demux->client->sequence = current_sequence; - gst_m3u8_client_get_current_position (demux->client, &position); - demux->position_shift = start - position; + demux->client->sequence_position = current_pos; + demux->position_shift = start - current_pos; demux->need_segment = TRUE; GST_M3U8_CLIENT_UNLOCK (demux->client); diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c index fed20db4ec..5cf4b0e218 100644 --- a/ext/hls/m3u8.c +++ b/ext/hls/m3u8.c @@ -484,6 +484,7 @@ gst_m3u8_client_new (const gchar * uri) client->main = gst_m3u8_new (); client->current = NULL; client->sequence = -1; + client->sequence_position = 0; client->update_failed_count = 0; g_mutex_init (&client->lock); gst_m3u8_set_uri (client->main, g_strdup (uri)); @@ -546,6 +547,7 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data) if (m3u8->files && self->sequence == -1) { self->sequence = GST_M3U8_MEDIA_FILE (g_list_first (m3u8->files)->data)->sequence; + self->sequence_position = 0; GST_DEBUG ("Setting first sequence at %d", self->sequence); } @@ -570,24 +572,6 @@ _find_next (GstM3U8MediaFile * file, GstM3U8Client * client) return TRUE; } -void -gst_m3u8_client_get_current_position (GstM3U8Client * client, - GstClockTime * timestamp) -{ - GList *l; - GList *walk; - - l = g_list_find_custom (client->current->files, client, - (GCompareFunc) _find_next); - - *timestamp = 0; - for (walk = client->current->files; walk; walk = walk->next) { - if (walk == l) - break; - *timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration; - } -} - gboolean gst_m3u8_client_get_next_fragment (GstM3U8Client * client, gboolean * discontinuity, const gchar ** uri, GstClockTime * duration, @@ -613,7 +597,7 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client, file->sequence, client->sequence); if (timestamp) - gst_m3u8_client_get_current_position (client, timestamp); + *timestamp = client->sequence_position; if (discontinuity) *discontinuity = client->sequence != file->sequence; @@ -652,6 +636,7 @@ gst_m3u8_client_advance_fragment (GstM3U8Client * client) file = GST_M3U8_MEDIA_FILE (l->data); GST_DEBUG ("Advancing from sequence %u", file->sequence); client->sequence = file->sequence + 1; + client->sequence_position += file->duration; GST_M3U8_CLIENT_UNLOCK (client); } diff --git a/ext/hls/m3u8.h b/ext/hls/m3u8.h index 4d80f04f70..b249e986ce 100644 --- a/ext/hls/m3u8.h +++ b/ext/hls/m3u8.h @@ -76,6 +76,7 @@ struct _GstM3U8Client GstM3U8 *current; guint update_failed_count; gint sequence; /* the next sequence for this client */ + GstClockTime sequence_position; /* position of this sequence */ GMutex lock; }; @@ -88,8 +89,6 @@ gboolean gst_m3u8_client_get_next_fragment (GstM3U8Client * client, gboolean * discontinuity, const gchar ** uri, GstClockTime * duration, GstClockTime * timestamp, const gchar ** key, const guint8 ** iv); void gst_m3u8_client_advance_fragment (GstM3U8Client * client); -void gst_m3u8_client_get_current_position (GstM3U8Client * client, - GstClockTime * timestamp); GstClockTime gst_m3u8_client_get_duration (GstM3U8Client * client); GstClockTime gst_m3u8_client_get_target_duration (GstM3U8Client * client); const gchar *gst_m3u8_client_get_uri(GstM3U8Client * client);