}
static gboolean
+gst_dash_demux_setup_all_streams (GstDashDemux *demux)
+{
+ GList *listLang = NULL;
+ guint i, nb_audio;
+ gchar *lang;
+
+ /* clean old active stream list, if any */
+ gst_active_streams_free (demux->client);
+
+ if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_VIDEO, ""))
+ GST_INFO_OBJECT (demux, "No video adaptation set found");
+
+ nb_audio = gst_mpdparser_get_list_and_nb_of_audio_language (demux->client, &listLang);
+ if (nb_audio == 0)
+ nb_audio = 1;
+ GST_INFO_OBJECT (demux, "Number of language is=%d", nb_audio);
+
+ for (i = 0; i < nb_audio; i++) {
+ lang = (gchar *) g_list_nth_data (listLang, i);
+ if (gst_mpdparser_get_nb_adaptationSet (demux->client) > 1)
+ if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_AUDIO, lang))
+ GST_INFO_OBJECT (demux, "No audio adaptation set found");
+
+ if (gst_mpdparser_get_nb_adaptationSet (demux->client) > nb_audio)
+ if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_APPLICATION, lang))
+ GST_INFO_OBJECT (demux, "No application adaptation set found");
+ }
+
+ return TRUE;
+}
+
+static gboolean
gst_dash_demux_sink_event (GstPad * pad, GstEvent * event)
{
GstDashDemux *demux = GST_DASH_DEMUX (gst_pad_get_parent (pad));
("Incompatible manifest file."), (NULL));
return FALSE;
}
-
- if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_VIDEO, "")) {
- GST_ELEMENT_ERROR (demux, STREAM, DECODE,
- ("Incompatible manifest file."), (NULL));
+ /* start from first Period */
+ demux->client->period_idx = 0;
+ /* setup video, audio and subtitle streams */
+ if (!gst_dash_demux_setup_all_streams (demux))
return FALSE;
- }
-
- GList *listLang = NULL;
- guint nb_audio =
- gst_mpdparser_get_list_and_nb_of_audio_language (demux->client,
- &listLang);
- if (nb_audio == 0)
- nb_audio = 1;
- GST_INFO_OBJECT (demux, "Number of language is=%d", nb_audio);
- guint i = 0;
- for (i = 0; i < nb_audio; i++) {
- gchar *lang = (gchar *) g_list_nth_data (listLang, i);
- if (gst_mpdparser_get_nb_adaptationSet (demux->client) > 1)
- if (!gst_mpd_client_setup_streaming (demux->client, GST_STREAM_AUDIO,
- lang))
- GST_INFO_OBJECT (demux, "No audio adaptation set found");
-
- if (gst_mpdparser_get_nb_adaptationSet (demux->client) > nb_audio)
- if (!gst_mpd_client_setup_streaming (demux->client,
- GST_STREAM_APPLICATION, lang)) {
- GST_INFO_OBJECT (demux, "No application adaptation set found");
- }
- }
-
/* Send duration message */
if (!gst_mpd_client_is_live (demux->client)) {
GstClockTime duration = gst_mpd_client_get_duration (demux->client);
static void
gst_dash_demux_reset (GstDashDemux * demux, gboolean dispose)
{
+ demux->end_of_period = FALSE;
demux->end_of_manifest = FALSE;
demux->cancelled = FALSE;
gst_dash_demux_get_buffering_ratio (demux));
/* fetch the next fragment */
- if (!gst_dash_demux_get_next_fragment_set (demux)) {
- if (demux->end_of_manifest) {
- GST_INFO_OBJECT (demux, "Reached the end of the manifest file");
- goto end_of_manifest;
+ while (!gst_dash_demux_get_next_fragment_set (demux)) {
+ if (demux->end_of_period) {
+ GST_INFO_OBJECT (demux, "Reached the end of the Period");
+ /* load the next Period in the Media Presentation */
+ if (!gst_mpd_client_get_next_period (demux->client) || !gst_dash_demux_setup_all_streams (demux)) {
+ GST_INFO_OBJECT (demux, "Reached the end of the manifest file");
+ demux->end_of_manifest = TRUE;
+ if (GST_STATE (demux) != GST_STATE_PLAYING) {
+ /* Restart the pipeline regardless of the current buffering level */
+ gst_element_post_message (GST_ELEMENT (demux),
+ gst_message_new_buffering (GST_OBJECT (demux), 100));
+ }
+ gst_task_start (demux->stream_task);
+ goto end_of_manifest;
+ }
+ /* create a new set of pads and send new_segment events */
+ /* FIXME: fix pad switching */
+ //demux->need_segment = TRUE;
+ demux->end_of_period = FALSE;
} else if (!demux->cancelled) {
demux->client->update_failed_count++;
if (demux->client->update_failed_count < DEFAULT_FAILED_COUNT) {
GST_WARNING_OBJECT (demux, "Could not fetch the next fragment");
- return;
- } else
+ goto quit;
+ } else {
goto error_downloading;
+ }
+ } else {
+ goto quit;
}
- } else {
- GST_INFO_OBJECT (demux, "Internal buffering : %d s",
- gst_dash_demux_get_buffering_time (demux) / GST_SECOND);
- demux->client->update_failed_count = 0;
}
+ GST_INFO_OBJECT (demux, "Internal buffering : %d s",
+ gst_dash_demux_get_buffering_time (demux) / GST_SECOND);
+ demux->client->update_failed_count = 0;
} else {
/* schedule the next download in 100 ms */
g_get_current_time (&demux->next_download);
guint i = 0;
while (i < gst_mpdparser_get_nb_active_stream (demux->client)) {
- if (demux->client->active_streams)
- stream = g_list_nth_data (demux->client->active_streams, i);
+ stream = gst_mpdparser_get_active_stream_by_index (demux->client, i);
if (!stream)
return FALSE;
while (stream_idx < gst_mpdparser_get_nb_active_stream (demux->client)) {
if (!gst_mpd_client_get_next_fragment (demux->client,
stream_idx, &discont, &next_fragment_uri, &duration, ×tamp)) {
- GST_INFO_OBJECT (demux, "This manifest doesn't contain more fragments");
- demux->end_of_manifest = TRUE;
- if (GST_STATE (demux) != GST_STATE_PLAYING) {
- /* Restart the pipeline regardless of the current buffering level */
- gst_element_post_message (GST_ELEMENT (demux),
- gst_message_new_buffering (GST_OBJECT (demux), 100));
- }
- gst_task_start (demux->stream_task);
+ GST_INFO_OBJECT (demux, "This Period doesn't contain more fragments");
+ demux->end_of_period = TRUE;
return FALSE;
}
static const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType);
/* Adaptation Set */
-static GstAdaptationSetNode *gst_mpdparser_get_first_adapt_set (GList *AdaptationSets);
static GstAdaptationSetNode *gst_mpdparser_get_first_adapt_set_with_mimeType (GList *AdaptationSets, const gchar *mimeType);
static GstAdaptationSetNode *gst_mpdparser_get_adapt_set_with_mimeType_and_idx (GList *AdaptationSets, const gchar *mimeType, gint idx);
static GstAdaptationSetNode *gst_mpdparser_get_first_adapt_set_with_mimeType_and_lang (GList *AdaptationSets, const gchar *mimeType, const gchar *lang);
/* navigation functions */
static GstAdaptationSetNode *
-gst_mpdparser_get_first_adapt_set (GList * AdaptationSets)
-{
- GList *list = NULL;
-
- if (AdaptationSets == NULL)
- return NULL;
-
- list = g_list_first (AdaptationSets);
-
- return list ? (GstAdaptationSetNode *) list->data : NULL;
-}
-
-static GstAdaptationSetNode *
gst_mpdparser_get_first_adapt_set_with_mimeType (GList * AdaptationSets,
const gchar * mimeType)
{
return client;
}
+void gst_active_streams_free (GstMpdClient * client)
+{
+ if (client->active_streams) {
+ g_list_foreach (client->active_streams,
+ (GFunc) gst_mpdparser_free_active_stream, NULL);
+ g_list_free (client->active_streams);
+ client->active_streams = NULL;
+ }
+}
+
void gst_mpd_client_free (GstMpdClient * client)
{
g_return_if_fail (client != NULL);
g_list_free (client->periods);
}
- if (client->active_streams) {
- g_list_foreach (client->active_streams,
- (GFunc) gst_mpdparser_free_active_stream, NULL);
- g_list_free (client->active_streams);
- }
+ gst_active_streams_free (client);
if (client->lock)
g_mutex_free (client->lock);
{
GstStreamPeriod *stream_period;
GList *rep_list;
- GstClockTime PeriodStart = 0, PeriodEnd, start_time, duration;
+ GstClockTime PeriodStart, PeriodEnd, start_time, duration;
GstMediaSegment *last_media_segment;
guint i, start;
gst_mpdparser_get_segment_list (stream_period->period, stream->cur_adapt_set, representation)) == NULL) {
GST_DEBUG ("No useful SegmentList node for the current Representation");
/* here we should have a single segment for each representation, whose URL is encoded in the baseURL element */
- if (!gst_mpd_client_add_media_segment (stream, NULL, 1, 0, 0, PeriodEnd)) {
+ if (!gst_mpd_client_add_media_segment (stream, NULL, 1, 0, PeriodStart, PeriodEnd)) {
return FALSE;
}
} else {
/* build segment list */
i = stream->cur_segment_list->MultSegBaseType->startNumber;
start = 0;
- start_time = 0;
+ start_time = PeriodStart;
GST_LOG ("Building media segment list using a SegmentList node");
if (stream->cur_segment_list->MultSegBaseType->SegmentTimeline) {
/* build segment list */
i = stream->cur_seg_template->MultSegBaseType->startNumber;
start = 0;
- start_time = 0;
+ start_time = PeriodStart;
GST_LOG ("Building media segment list using this template: %s", stream->cur_seg_template->media);
if (stream->cur_seg_template->MultSegBaseType->SegmentTimeline) {
/* select the adaptation set for the video pipeline */
adapt_set =
gst_mpdparser_get_adapt_set_with_mimeType_and_idx (stream_period->period->AdaptationSets, "video", 0);
- /* if we found no 'video' adaptation set, just get the first one */
- if (!adapt_set)
- adapt_set =
- gst_mpdparser_get_first_adapt_set (stream_period->period->AdaptationSets);
if (!adapt_set) {
- GST_INFO ("No adaptation set found, aborting...");
+ GST_INFO ("No video adaptation set found");
return FALSE;
}
/* retrive the list of representations */
}
break;
case GST_STREAM_AUDIO:
-#if 0
- if (g_strcmp0 (client->audio_lang, "none") == 0) {
- GST_INFO ("Audio stream disabled");
- return FALSE;
- }
-#endif
adapt_set =
gst_mpdparser_get_first_adapt_set_with_mimeType_and_lang (stream_period->period->AdaptationSets, "audio", lang);
/* if we did not found the requested audio language, get the first one */
}
break;
case GST_STREAM_APPLICATION:
-#if 0
- if (g_strcmp0 (client->subtitle_lang, "none") == 0) {
- GST_INFO ("Subtitles pipeline disabled");
- return FALSE;
- }
-#endif
adapt_set =
gst_mpdparser_get_first_adapt_set_with_mimeType_and_lang (stream_period->period->AdaptationSets, "application", lang);
/* if we did not found the requested subtitles language, get the first one */
}
gst_mpd_client_get_current_position (client, timestamp);
+ *duration = gst_mpd_client_get_target_duration (client);
+ //*timestamp = currentChunk->start_time;
+ //*duration = currentChunk->duration;
*discontinuity = stream->segment_idx != currentChunk->number;
stream->segment_idx += 1;
if (mediaURL == NULL) {
} else {
*uri = mediaURL;
}
- *duration = gst_mpd_client_get_target_duration (client);
GST_MPD_CLIENT_UNLOCK (client);
GST_DEBUG ("Loading chunk with URL %s", *uri);
}
gboolean
+gst_mpd_client_get_next_period (GstMpdClient *client)
+{
+ GstStreamPeriod *next_stream_period;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (client->periods != NULL, FALSE);
+
+ next_stream_period = g_list_nth_data (client->periods, client->period_idx + 1);
+ if (next_stream_period == NULL)
+ return FALSE;
+
+ client->period_idx++;
+
+ return TRUE;
+}
+
+gboolean
gst_mpd_client_is_live (GstMpdClient * client)
{
g_return_val_if_fail (client != NULL, FALSE);