hlsdemux: Implement proper handling of discontinuities

It's not really correct yet for seeks but better than what
we had before.

See https://bugzilla.gnome.org/show_bug.cgi?id=695846
This commit is contained in:
Sebastian Dröge 2014-03-01 17:13:58 +01:00
parent a04fe75047
commit 0a32c5f7a4
4 changed files with 16 additions and 4 deletions

View file

@ -360,6 +360,7 @@ gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
current_sequence = file->sequence;
current_pos = 0;
target_pos = (GstClockTime) start;
/* FIXME: Here we need proper discont handling */
for (walk = demux->client->current->files; walk; walk = walk->next) {
file = walk->data;
@ -793,9 +794,11 @@ gst_hls_demux_stream_loop (GstHLSDemux * demux)
buf = gst_fragment_get_buffer (fragment);
if (G_UNLIKELY (!srccaps || !gst_caps_is_equal_fixed (bufcaps, srccaps))) {
if (G_UNLIKELY (!srccaps || demux->discont || GST_BUFFER_IS_DISCONT (buf))) {
switch_pads (demux, bufcaps);
demux->need_segment = TRUE;
demux->discont = FALSE;
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
}
gst_caps_unref (bufcaps);
if (G_LIKELY (srccaps))
@ -905,6 +908,7 @@ gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose)
demux->position_shift = 0;
demux->need_segment = TRUE;
demux->discont = TRUE;
demux->have_group_id = FALSE;
demux->group_id = G_MAXUINT;
@ -1162,6 +1166,7 @@ retry_failover_protection:
GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching"
" to bitrate %dbps", old_bandwidth, max_bitrate, new_bandwidth);
demux->discont = TRUE;
if (gst_hls_demux_update_playlist (demux, FALSE, NULL)) {
GstStructure *s;
@ -1436,6 +1441,8 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux,
if (discont) {
GST_DEBUG_OBJECT (demux, "Marking fragment as discontinuous");
GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
} else {
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
}
/* The buffer ref is still kept inside the fragment download */

View file

@ -94,6 +94,7 @@ struct _GstHLSDemux
/* Position in the stream */
GstClockTime position_shift;
gboolean need_segment;
gboolean discont;
/* Cache for the last key */
gchar *key_url;

View file

@ -236,7 +236,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
gint val;
GstClockTime duration;
gchar *title, *end;
// gboolean discontinuity;
gboolean discontinuity = FALSE;
GstM3U8 *list;
gboolean have_iv = FALSE;
guint8 iv[16] = { 0, };
@ -324,8 +324,11 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
}
}
file->discont = discontinuity;
duration = 0;
title = NULL;
discontinuity = FALSE;
self->files = g_list_append (self->files, file);
}
@ -373,7 +376,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
if (int_from_string (data + 22, &data, &val))
self->mediasequence = val;
} else if (g_str_has_prefix (data, "#EXT-X-DISCONTINUITY")) {
/* discontinuity = TRUE; */
discontinuity = TRUE;
} else if (g_str_has_prefix (data, "#EXT-X-PROGRAM-DATE-TIME:")) {
/* <YYYY-MM-DDThh:mm:ssZ> */
GST_DEBUG ("FIXME parse date");
@ -618,7 +621,7 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
*timestamp = client->sequence_position;
if (discontinuity)
*discontinuity = client->sequence != file->sequence;
*discontinuity = client->sequence != file->sequence || file->discont;
if (uri)
*uri = file->uri;
if (duration)

View file

@ -66,6 +66,7 @@ struct _GstM3U8MediaFile
GstClockTime duration;
gchar *uri;
guint sequence; /* the sequence nb of this file */
gboolean discont; /* this file marks a discontinuity */
gchar *key;
guint8 iv[16];
};