gboolean update, GError ** err);
static void gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose);
static gboolean gst_hls_demux_set_location (GstHLSDemux * demux,
- const gchar * uri);
+ const gchar * uri, const gchar * base_uri);
static gchar *gst_hls_src_buf_to_utf8_playlist (GstBuffer * buf);
static gboolean gst_hls_demux_change_playlist (GstHLSDemux * demux,
GstHLSDemux *demux;
GstQuery *query;
gboolean ret;
- gchar *uri;
demux = GST_HLS_DEMUX (parent);
ret = gst_pad_peer_query (demux->sinkpad, query);
if (ret) {
gboolean permanent;
+ gchar *uri, *redirect_uri;
- gst_query_parse_uri_redirection (query, &uri);
+ gst_query_parse_uri (query, &uri);
+ gst_query_parse_uri_redirection (query, &redirect_uri);
gst_query_parse_uri_redirection_permanent (query, &permanent);
- /* Only use the redirect target for permanent redirects */
- if (!permanent || uri == NULL) {
- g_free (uri);
- gst_query_parse_uri (query, &uri);
+ if (permanent) {
+ gst_hls_demux_set_location (demux, redirect_uri, redirect_uri);
+ } else {
+ gst_hls_demux_set_location (demux, uri, redirect_uri);
}
-
- gst_hls_demux_set_location (demux, uri);
g_free (uri);
+ g_free (redirect_uri);
}
gst_query_unref (query);
}
if (!dispose) {
- demux->client = gst_m3u8_client_new ("");
+ demux->client = gst_m3u8_client_new ("", NULL);
}
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
}
static gboolean
-gst_hls_demux_set_location (GstHLSDemux * demux, const gchar * uri)
+gst_hls_demux_set_location (GstHLSDemux * demux, const gchar * uri,
+ const gchar * base_uri)
{
if (demux->client)
gst_m3u8_client_free (demux->client);
- demux->client = gst_m3u8_client_new (uri);
- GST_INFO_OBJECT (demux, "Changed location: %s", uri);
+ demux->client = gst_m3u8_client_new (uri, base_uri);
+ GST_INFO_OBJECT (demux, "Changed location: %s (base uri: %s)", uri,
+ GST_STR_NULL (base_uri));
return TRUE;
}
GstBuffer *buf;
gchar *playlist;
gboolean updated = FALSE;
-
const gchar *uri = gst_m3u8_client_get_current_uri (demux->client);
download =
if (download == NULL)
return FALSE;
+ /* Set the base URI of the playlist to the redirect target if any */
+ GST_M3U8_CLIENT_LOCK (demux->client);
+ g_free (demux->client->current->uri);
+ g_free (demux->client->current->base_uri);
+ if (download->redirect_permanent) {
+ demux->client->current->uri = g_strdup (download->redirect_uri);
+ demux->client->current->base_uri = NULL;
+ } else {
+ demux->client->current->uri = g_strdup (download->uri);
+ demux->client->current->base_uri = g_strdup (download->redirect_uri);
+ }
+ GST_M3U8_CLIENT_UNLOCK (demux->client);
+
buf = gst_fragment_get_buffer (download);
playlist = gst_hls_src_buf_to_utf8_playlist (buf);
g_object_unref (download);
}
static void
-gst_m3u8_set_uri (GstM3U8 * self, gchar * uri)
+gst_m3u8_set_uri (GstM3U8 * self, gchar * uri, gchar * base_uri)
{
g_return_if_fail (self != NULL);
- if (self->uri)
- g_free (self->uri);
+ g_free (self->uri);
self->uri = uri;
+
+ g_free (self->base_uri);
+ self->base_uri = base_uri;
}
static void
g_return_if_fail (self != NULL);
g_free (self->uri);
+ g_free (self->base_uri);
g_free (self->codecs);
g_free (self->key);
goto next_line;
}
- data = uri_join (self->uri, data);
+ data = uri_join (self->base_uri ? self->base_uri : self->uri, data);
if (data == NULL)
goto next_line;
gst_m3u8_free (list);
g_free (data);
} else {
- gst_m3u8_set_uri (list, data);
+ gst_m3u8_set_uri (list, data, NULL);
self->lists = g_list_append (self->lists, list);
}
list = NULL;
if (uri[0] == '"')
uri += 1;
- uri = uri_join (self->uri, uri);
+ uri = uri_join (self->base_uri ? self->base_uri : self->uri, uri);
g_free (urip);
if (uri == NULL)
continue;
- gst_m3u8_set_uri (new_list, uri);
+ gst_m3u8_set_uri (new_list, uri, NULL);
}
}
if (key[0] == '"')
key += 1;
- self->key = uri_join (self->uri, key);
+ self->key =
+ uri_join (self->base_uri ? self->base_uri : self->uri, key);
g_free (keyp);
} else if (g_str_equal (a, "IV")) {
gchar *ivp = v;
}
GstM3U8Client *
-gst_m3u8_client_new (const gchar * uri)
+gst_m3u8_client_new (const gchar * uri, const gchar * base_uri)
{
GstM3U8Client *client;
client->sequence_position = 0;
client->update_failed_count = 0;
g_mutex_init (&client->lock);
- gst_m3u8_set_uri (client->main, g_strdup (uri));
+ gst_m3u8_set_uri (client->main, g_strdup (uri), g_strdup (base_uri));
return client;
}
struct _GstM3U8
{
- gchar *uri;
+ gchar *uri; /* actually downloaded URI */
+ gchar *base_uri; /* URI to use as base for resolving relative URIs.
+ * This will be different to uri in case of redirects */
gboolean endlist; /* if ENDLIST has been reached */
gint version; /* last EXT-X-VERSION */
};
-GstM3U8Client *gst_m3u8_client_new (const gchar * uri);
+GstM3U8Client *gst_m3u8_client_new (const gchar * uri, const gchar * base_uri);
void gst_m3u8_client_free (GstM3U8Client * client);
gboolean gst_m3u8_client_update (GstM3U8Client * client, gchar * data);
void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8);