diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index 29a66eb6a9..c98faf41e0 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -508,7 +508,7 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) GST_TIME_FORMAT, rate, start_type, GST_TIME_ARGS (start), GST_TIME_ARGS (stop)); - GST_MPD_CLIENT_LOCK (demux->client); + //GST_MPD_CLIENT_LOCK (demux->client); /* select the requested Period in the Media Presentation */ target_pos = (GstClockTime) start; @@ -545,7 +545,7 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) break; } } - GST_MPD_CLIENT_UNLOCK (demux->client); + //GST_MPD_CLIENT_UNLOCK (demux->client); if (list == NULL) { GST_WARNING_OBJECT (demux, "Could not find seeked fragment"); @@ -576,21 +576,15 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event) /* FIXME: allow seeking in the buffering queue */ gst_dash_demux_clear_queue (demux); - GST_MPD_CLIENT_LOCK (demux->client); + //GST_MPD_CLIENT_LOCK (demux->client); GST_DEBUG_OBJECT (demux, "Seeking to sequence %d", current_sequence); /* Update the current sequence on all streams */ - for (stream_idx = 0; stream_idx < nb_active_stream; stream_idx++) { - stream = - gst_mpdparser_get_active_stream_by_index (demux->client, - stream_idx); - gst_mpd_client_set_segment_index (stream, current_sequence); - } + gst_mpd_client_set_segment_index_for_all_streams (demux->client, current_sequence); /* Calculate offset in the next fragment */ demux->position = gst_mpd_client_get_current_position (demux->client); demux->position_shift = start - demux->position; demux->need_segment = TRUE; - GST_MPD_CLIENT_UNLOCK (demux->client); - + //GST_MPD_CLIENT_UNLOCK (demux->client); if (flags & GST_SEEK_FLAG_FLUSH) { GST_DEBUG_OBJECT (demux, "Sending flush stop on all pad"); @@ -624,6 +618,7 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux) guint i, nb_audio; gchar *lang; + GST_MPD_CLIENT_LOCK (demux->client); /* clean old active stream list, if any */ gst_active_streams_free (demux->client); @@ -649,6 +644,7 @@ gst_dash_demux_setup_all_streams (GstDashDemux * demux) GST_STREAM_APPLICATION, lang)) GST_INFO_OBJECT (demux, "No application adaptation set found"); } + GST_MPD_CLIENT_UNLOCK (demux->client); return TRUE; } @@ -712,6 +708,9 @@ gst_dash_demux_sink_event (GstPad * pad, GstEvent * event) !gst_dash_demux_setup_all_streams (demux)) return FALSE; + /* start playing from the first segment */ + gst_mpd_client_set_segment_index_for_all_streams (demux->client, 0); + /* Send duration message */ if (!gst_mpd_client_is_live (demux->client)) { GstClockTime duration = @@ -1230,7 +1229,12 @@ gst_dash_demux_download_loop (GstDashDemux * demux) GST_WARNING_OBJECT (demux, "Error parsing the manifest."); gst_buffer_unref (buffer); } else { + GstActiveStream *stream; + guint segment_index; + gst_buffer_unref (buffer); + stream = gst_mpdparser_get_active_stream_by_index (demux->client, 0); + segment_index = gst_mpd_client_get_segment_index (stream); /* setup video, audio and subtitle streams, starting from first Period */ if (!gst_mpd_client_setup_media_presentation (demux->client) || !gst_mpd_client_set_period_index (demux->client, gst_mpd_client_get_period_index (demux->client)) || @@ -1238,6 +1242,10 @@ gst_dash_demux_download_loop (GstDashDemux * demux) GST_DEBUG_OBJECT (demux, "Error setting up the updated manifest file"); goto end_of_manifest; } + /* continue playing from the the next segment */ + /* FIXME: support multiple streams with different segment duration */ + gst_mpd_client_set_segment_index_for_all_streams (demux->client, segment_index); + /* Send an updated duration message */ duration = gst_mpd_client_get_media_presentation_duration (demux->client); @@ -1298,6 +1306,8 @@ gst_dash_demux_download_loop (GstDashDemux * demux) gst_task_start (demux->stream_task); goto end_of_manifest; } + /* start playing from the first segment of the new period */ + gst_mpd_client_set_segment_index_for_all_streams (demux->client, 0); demux->end_of_period = FALSE; } else if (!demux->cancelled) { demux->client->update_failed_count++; diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index 58c6ffea58..5d0a844d19 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -70,7 +70,7 @@ static void gst_mpdparser_parse_period_node (GList ** list, xmlNode * a_node); static void gst_mpdparser_parse_program_info_node (GList ** list, xmlNode * a_node); static void gst_mpdparser_parse_metrics_range_node (GList ** list, xmlNode * a_node); static void gst_mpdparser_parse_metrics_node (GList ** list, xmlNode * a_node); -static void gst_mpdparser_parse_root_node (GstMpdClient * client, xmlNode *a_node); +static void gst_mpdparser_parse_root_node (GstMPDNode ** pointer, xmlNode * a_node); /* Helper functions */ static gint convert_to_millisecs (gint decimals, gint pos); @@ -84,6 +84,7 @@ static gchar *gst_mpdparser_build_URL_from_template (const gchar *url_template, static gboolean gst_mpd_client_add_media_segment (GstActiveStream *stream, GstSegmentURLNode *url_node, guint number, guint start, GstClockTime start_time, GstClockTime duration); static const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType); static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client); +static void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx); /* Adaptation Set */ static GstAdaptationSetNode *gst_mpdparser_get_first_adapt_set_with_mimeType (GList *AdaptationSets, const gchar *mimeType); @@ -1487,13 +1488,13 @@ gst_mpdparser_parse_metrics_node (GList ** list, xmlNode * a_node) } static void -gst_mpdparser_parse_root_node (GstMpdClient * client, xmlNode *a_node) +gst_mpdparser_parse_root_node (GstMPDNode ** pointer, xmlNode * a_node) { xmlNode *cur_node; GstMPDNode *new_mpd; - gst_mpdparser_free_mpd_node (client->mpd_node); - client->mpd_node = new_mpd = g_slice_new0 (GstMPDNode); + gst_mpdparser_free_mpd_node (*pointer); + *pointer = new_mpd = g_slice_new0 (GstMPDNode); if (new_mpd == NULL) { GST_WARNING ("Allocation of MPD node failed!"); return; @@ -2258,7 +2259,7 @@ gst_mpdparser_get_stream_period (GstMpdClient * client) g_return_val_if_fail (client != NULL, NULL); g_return_val_if_fail (client->periods != NULL, NULL); - return g_list_nth_data (client->periods, gst_mpd_client_get_period_index (client)); + return g_list_nth_data (client->periods, client->period_idx); } /* select a stream and extract the baseURL (if present) */ @@ -2446,7 +2447,7 @@ gst_mpd_parse (GstMpdClient * client, const gchar * data, gint size) GST_ERROR ("can not find the root element MPD, failed to parse the MPD file"); } else { /* now we can parse the MPD root node and all children nodes, recursively */ - gst_mpdparser_parse_root_node (client, root_element); + gst_mpdparser_parse_root_node (&client->mpd_node, root_element); } /* free the document */ xmlFreeDoc (doc); @@ -2726,6 +2727,7 @@ gst_mpd_client_setup_media_presentation (GstMpdClient *client) g_return_val_if_fail (client->mpd_node != NULL, FALSE); GST_DEBUG ("Building the list of Periods in the Media Presentation"); + GST_MPD_CLIENT_LOCK (client); /* clean the old period list, if any */ if (client->periods) { g_list_foreach (client->periods, @@ -2786,18 +2788,22 @@ gst_mpd_client_setup_media_presentation (GstMpdClient *client) GST_TIME_FORMAT, idx, GST_TIME_ARGS (start), GST_TIME_ARGS (duration)); } + GST_MPD_CLIENT_UNLOCK (client); GST_DEBUG ("Found a total of %d valid Periods in the Media Presentation", idx); return ret; early: + GST_MPD_CLIENT_UNLOCK (client); GST_WARNING ("Found an Early Available Period, skipping the rest of the Media Presentation"); return ret; syntax_error: + GST_MPD_CLIENT_UNLOCK (client); GST_WARNING ("Cannot get the duration of the Period %d, skipping the rest of the Media Presentation", idx); return ret; no_mem: + GST_MPD_CLIENT_UNLOCK (client); GST_WARNING ("Allocation of GstStreamPeriod struct failed!"); return FALSE; } @@ -2882,9 +2888,7 @@ gst_mpd_client_setup_streaming (GstMpdClient * client, stream->baseURL_idx = 0; stream->mimeType = mimeType; - stream->representation_idx = 0; stream->cur_adapt_set = adapt_set; - gst_mpd_client_set_segment_index (stream, 0); /* retrive representation list */ if (stream->cur_adapt_set != NULL) @@ -3062,34 +3066,65 @@ gboolean gst_mpd_client_set_period_index (GstMpdClient *client, guint period_idx) { GstStreamPeriod *next_stream_period; + gboolean ret = FALSE; g_return_val_if_fail (client != NULL, FALSE); g_return_val_if_fail (client->periods != NULL, FALSE); + GST_MPD_CLIENT_LOCK (client); next_stream_period = g_list_nth_data (client->periods, period_idx); - if (next_stream_period == NULL) - return FALSE; + if (next_stream_period != NULL) { + client->period_idx = period_idx; + ret = TRUE; + } + GST_MPD_CLIENT_UNLOCK (client); - client->period_idx = period_idx; - - return TRUE; + return ret; } guint gst_mpd_client_get_period_index (GstMpdClient *client) { - return client->period_idx; + guint period_idx; + + g_return_val_if_fail (client != NULL, 0); + GST_MPD_CLIENT_LOCK (client); + period_idx = client->period_idx; + GST_MPD_CLIENT_UNLOCK (client); + + return period_idx; } void +gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient *client, guint segment_idx) +{ + GList *list; + + g_return_if_fail (client != NULL); + g_return_if_fail (client->active_streams != NULL); + + /* FIXME: support multiple streams with different segment duration */ + for (list = g_list_first (client->active_streams); list; list = g_list_next (list)) { + GstActiveStream *stream = (GstActiveStream *) list->data; + if (stream) { + stream->segment_idx = segment_idx; + } + } +} + +static void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx) { + g_return_if_fail (stream != NULL); + stream->segment_idx = segment_idx; } guint gst_mpd_client_get_segment_index (GstActiveStream * stream) { + g_return_val_if_fail (stream != NULL, 0); + return stream->segment_idx; } @@ -3103,8 +3138,8 @@ gst_mpd_client_is_live (GstMpdClient * client) } guint -gst_mpdparser_get_nb_active_stream (GstMpdClient *client){ - +gst_mpdparser_get_nb_active_stream (GstMpdClient *client) +{ g_return_val_if_fail (client != NULL, 0); return g_list_length (client->active_streams); diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h index 01c4598aab..d6132986ba 100644 --- a/ext/dash/gstmpdparser.h +++ b/ext/dash/gstmpdparser.h @@ -493,7 +493,7 @@ GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client); /* Segment */ -void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx); +void gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, guint segment_idx); guint gst_mpd_client_get_segment_index (GstActiveStream * stream); /* Get audio/video stream parameters (mimeType, width, height, rate, number of channels) */