summaryrefslogtreecommitdiff
path: root/ext/hls/gsthlsdemux.c
diff options
context:
space:
mode:
authorJan Schmidt <jan@centricular.com>2016-03-09 03:07:22 +1100
committerJan Schmidt <jan@centricular.com>2016-08-03 23:49:54 +1000
commitf3397e0d547fbb2ecc3d5fb4cbc87b9f6d6aa23e (patch)
tree3805e1e1bc995b16074036438275d27bfbbdf0c1 /ext/hls/gsthlsdemux.c
parent4df6f1ee930af0ec7961ade57e21bd904f199fa9 (diff)
downloadgstreamer-plugins-bad-f3397e0d547fbb2ecc3d5fb4cbc87b9f6d6aa23e.tar.gz
hlsdemux: Choose the default variant and track it when updating
Modify playlist updating to track information across updates better, although still hackish. When connection_speed == 0, choose the default variant not the first one in the (now sorted) variant list, as that will have the lowest bitrate.
Diffstat (limited to 'ext/hls/gsthlsdemux.c')
-rw-r--r--ext/hls/gsthlsdemux.c129
1 files changed, 83 insertions, 46 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c
index 02464000d..3c600f398 100644
--- a/ext/hls/gsthlsdemux.c
+++ b/ext/hls/gsthlsdemux.c
@@ -462,20 +462,37 @@ gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux,
return;
if (hlsdemux->current_variant != NULL) {
+ gint i;
+
//#warning FIXME: Synching fragments across variants
// should be done based on media timestamps, and
// discont-sequence-numbers not sequence numbers.
variant->m3u8->sequence_position =
hlsdemux->current_variant->m3u8->sequence_position;
variant->m3u8->sequence = hlsdemux->current_variant->m3u8->sequence;
- variant->m3u8->highest_sequence_number =
- hlsdemux->current_variant->m3u8->highest_sequence_number;
GST_DEBUG_OBJECT (hlsdemux,
"Switching Variant. Copying over sequence %" G_GINT64_FORMAT
" and sequence_pos %" GST_TIME_FORMAT, variant->m3u8->sequence,
GST_TIME_ARGS (variant->m3u8->sequence_position));
+ for (i = 0; i < GST_HLS_N_MEDIA_TYPES; ++i) {
+ GList *mlist = hlsdemux->current_variant->media[i];
+
+ while (mlist != NULL) {
+ GstHLSMedia *old_media = mlist->data;
+ GstHLSMedia *new_media =
+ gst_hls_variant_find_matching_media (variant, old_media);
+
+ if (new_media) {
+ new_media->playlist->sequence = old_media->playlist->sequence;
+ new_media->playlist->sequence_position =
+ old_media->playlist->sequence_position;
+ }
+ mlist = mlist->next;
+ }
+ }
+
gst_hls_variant_stream_unref (hlsdemux->current_variant);
}
@@ -513,7 +530,7 @@ gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf)
/* select the initial variant stream */
if (demux->connection_speed == 0) {
- variant = hlsdemux->master->variants->data;
+ variant = hlsdemux->master->default_variant;
} else {
variant =
gst_hls_master_playlist_get_variant_for_bitrate (hlsdemux->master,
@@ -908,6 +925,9 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream)
g_free (stream->fragment.uri);
stream->fragment.uri = g_strdup (file->uri);
+
+ GST_DEBUG_OBJECT (stream, "URI now %s", file->uri);
+
stream->fragment.range_start = file->offset;
if (file->size != -1)
stream->fragment.range_end = file->offset + file->size - 1;
@@ -1012,67 +1032,84 @@ gst_hls_demux_update_variant_playlist (GstHLSDemux * hlsdemux, gchar * data,
GstHLSMasterPlaylist *new_master, *old;
gboolean ret = FALSE;
GList *l, *unmatched_lists;
+ GstHLSVariantStream *new_variant;
new_master = gst_hls_master_playlist_new_from_data (data, base_uri ? base_uri : uri); // FIXME: check which uri to use here
- if (new_master != NULL) {
- if (new_master->is_simple) {
- // FIXME: we should be able to support this though, in the unlikely
- // case that it changed?
- GST_ERROR
- ("Cannot update variant playlist: New playlist is not a variant playlist");
- gst_hls_master_playlist_unref (new_master);
- return FALSE;
- }
+ if (new_master == NULL)
+ return ret;
- GST_M3U8_CLIENT_LOCK (self);
+ if (new_master->is_simple) {
+ // FIXME: we should be able to support this though, in the unlikely
+ // case that it changed?
+ GST_ERROR
+ ("Cannot update variant playlist: New playlist is not a variant playlist");
+ gst_hls_master_playlist_unref (new_master);
+ return FALSE;
+ }
- if (hlsdemux->master->is_simple) {
- GST_ERROR
- ("Cannot update variant playlist: Current playlist is not a variant playlist");
- goto out;
- }
+ GST_M3U8_CLIENT_LOCK (self);
- /* Now see if the variant playlist still has the same lists */
- unmatched_lists = g_list_copy (hlsdemux->master->variants);
- for (l = new_master->variants; l != NULL; l = l->next) {
- GList *match = g_list_find_custom (unmatched_lists, l->data,
- (GCompareFunc) gst_hls_demux_find_variant_match);
- if (match) {
- unmatched_lists = g_list_delete_link (unmatched_lists, match);
- // FIXME: copy over state variables of playlist, or keep old instance
- GST_ERROR ("FIXME: copy over state variables of playlist");
- }
- }
+ if (hlsdemux->master->is_simple) {
+ GST_ERROR
+ ("Cannot update variant playlist: Current playlist is not a variant playlist");
+ goto out;
+ }
- if (unmatched_lists != NULL) {
- GST_WARNING ("Unable to match all playlists");
+ /* Now see if the variant playlist still has the same lists */
+ unmatched_lists = g_list_copy (hlsdemux->master->variants);
+ for (l = new_master->variants; l != NULL; l = l->next) {
+ GList *match = g_list_find_custom (unmatched_lists, l->data,
+ (GCompareFunc) gst_hls_demux_find_variant_match);
- for (l = unmatched_lists; l != NULL; l = l->next) {
- if (l->data == hlsdemux->current_variant) {
- GST_WARNING ("Unable to match current playlist");
- }
- }
+ if (match) {
+ GstHLSVariantStream *variant = l->data;
+ GstHLSVariantStream *old = match->data;
- g_list_free (unmatched_lists);
+ unmatched_lists = g_list_delete_link (unmatched_lists, match);
+ /* FIXME: Deal with losing position due to missing an update */
+ variant->m3u8->sequence_position = old->m3u8->sequence_position;
+ variant->m3u8->sequence = old->m3u8->sequence;
}
+ }
- /* Switch out the variant playlist, steal it from new_client */
- old = hlsdemux->master;
+ if (unmatched_lists != NULL) {
+ GST_WARNING ("Unable to match all playlists");
- // FIXME: check all this and also switch of variants, if anything needs updating
- hlsdemux->master = new_master;
+ for (l = unmatched_lists; l != NULL; l = l->next) {
+ if (l->data == hlsdemux->current_variant) {
+ GST_WARNING ("Unable to match current playlist");
+ }
+ }
- hlsdemux->current_variant = hlsdemux->master->default_variant;
+ g_list_free (unmatched_lists);
+ }
- gst_hls_master_playlist_unref (old);
+ /* Switch out the variant playlist */
+ old = hlsdemux->master;
- ret = TRUE;
+ // FIXME: check all this and also switch of variants, if anything needs updating
+ hlsdemux->master = new_master;
- out:
- GST_M3U8_CLIENT_UNLOCK (self);
+ if (hlsdemux->current_variant == NULL) {
+ new_variant = new_master->default_variant;
+ } else {
+ /* Find the same variant in the new playlist */
+ new_variant =
+ gst_hls_master_playlist_get_matching_variant (new_master,
+ hlsdemux->current_variant);
}
+ /* Use the function to set the current variant, as it copies over data */
+ if (new_variant != NULL)
+ gst_hls_demux_set_current_variant (hlsdemux, new_variant);
+
+ gst_hls_master_playlist_unref (old);
+
+ ret = (hlsdemux->current_variant != NULL);
+out:
+ GST_M3U8_CLIENT_UNLOCK (self);
+
return ret;
}