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.
This commit is contained in:
Youness Alaoui 2011-08-18 23:54:59 +00:00 committed by Sebastian Dröge
parent 1c73e77e32
commit 690e59e497
3 changed files with 21 additions and 7 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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 */
};