From 690e59e49769fc67b3d88fa98be69cef6cfed3c2 Mon Sep 17 00:00:00 2001 From: Youness Alaoui Date: Thu, 18 Aug 2011 23:54:59 +0000 Subject: [PATCH] hlsdemux: Keep a separate variable for the current variant used By using a separate variable, first it allows us to sort the lists of alternates but keep the pointer on the first occurence in the main playlist (to respect the spec of starting with the bitrate specified first in the main playlist). It also avoid playing with the lists variable which should be used to store the list of playlists and not as a pointer to the current one. Also fixes a memleak with the g_list_foreach freeing the lists, if it wasn't pointing to the first element of the list. --- gst/hls/gsthlsdemux.c | 10 +++++----- gst/hls/m3u8.c | 16 ++++++++++++++-- gst/hls/m3u8.h | 2 ++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gst/hls/gsthlsdemux.c b/gst/hls/gsthlsdemux.c index c8069344c0..51cec38c78 100644 --- a/gst/hls/gsthlsdemux.c +++ b/gst/hls/gsthlsdemux.c @@ -834,7 +834,7 @@ gst_hls_demux_cache_fragments (GstHLSDemux * demux) /* If this playlist is a variant playlist, select the first one * and update it */ if (gst_m3u8_client_has_variant_playlist (demux->client)) { - GstM3U8 *child = demux->client->main->lists->data; + GstM3U8 *child = demux->client->main->current_variant->data; gst_m3u8_client_set_current (demux->client, child); if (!gst_hls_demux_update_playlist (demux, FALSE)) { GST_ERROR_OBJECT (demux, "Could not fetch the child playlist %s", @@ -972,17 +972,17 @@ gst_hls_demux_change_playlist (GstHLSDemux * demux, gboolean is_fast) GstStructure *s; if (is_fast) - list = g_list_next (demux->client->main->lists); + list = g_list_next (demux->client->main->current_variant); else - list = g_list_previous (demux->client->main->lists); + list = g_list_previous (demux->client->main->current_variant); /* Don't do anything else if the playlist is the same */ if (!list || list->data == demux->client->current) return TRUE; - demux->client->main->lists = list; + demux->client->main->current_variant = list; - gst_m3u8_client_set_current (demux->client, demux->client->main->lists->data); + gst_m3u8_client_set_current (demux->client, list->data); gst_hls_demux_update_playlist (demux, TRUE); GST_INFO_OBJECT (demux, "Client is %s, switching to bitrate %d", is_fast ? "fast" : "slow", demux->client->current->bandwidth); diff --git a/gst/hls/m3u8.c b/gst/hls/m3u8.c index 66b4f16421..26548101f3 100644 --- a/gst/hls/m3u8.c +++ b/gst/hls/m3u8.c @@ -206,6 +206,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated) if (!g_str_has_prefix (data, "#EXTM3U")) { GST_WARNING ("Data doesn't start with #EXTM3U"); + *updated = FALSE; g_free (data); return FALSE; } @@ -350,11 +351,22 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated) } /* redorder playlists by bitrate */ - if (self->lists) + if (self->lists) { + gchar *top_variant_uri = NULL; + + if (!self->current_variant) + top_variant_uri = GST_M3U8 (self->lists->data)->uri; + else + top_variant_uri = GST_M3U8 (self->current_variant->data)->uri; + self->lists = g_list_sort (self->lists, (GCompareFunc) gst_m3u8_compare_playlist_by_bitrate); + self->current_variant = g_list_find_custom (self->lists, top_variant_uri, + (GCompareFunc) _m3u8_compare_uri); + } + return TRUE; } @@ -416,7 +428,7 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data) /* select the first playlist, for now */ if (!self->current) { if (self->main->lists) { - self->current = g_list_first (self->main->lists)->data; + self->current = self->main->current_variant->data; } else { self->current = self->main; } diff --git a/gst/hls/m3u8.h b/gst/hls/m3u8.h index 97a8ee2142..aefe8667d1 100644 --- a/gst/hls/m3u8.h +++ b/gst/hls/m3u8.h @@ -29,6 +29,7 @@ G_BEGIN_DECLS typedef struct _GstM3U8 GstM3U8; typedef struct _GstM3U8MediaFile GstM3U8MediaFile; typedef struct _GstM3U8Client GstM3U8Client; +#define GST_M3U8(m) ((GstM3U8*)m) #define GST_M3U8_MEDIA_FILE(f) ((GstM3U8MediaFile*)f) struct _GstM3U8 @@ -50,6 +51,7 @@ struct _GstM3U8 /*< private > */ gchar *last_data; GList *lists; /* list of GstM3U8 from the main playlist */ + GList *current_variant; /* Current variant playlist used */ GstM3U8 *parent; /* main playlist (if any) */ guint mediasequence; /* EXT-X-MEDIA-SEQUENCE & increased with new media file */ };