mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-21 09:53:47 +00:00
dashdemux: fix playing of single-segment media streams
other fixes: - fixed a buffering bug: now we stop buffering when we reach the end of manifest - now gst_mpd_client_get_target_duration() always returns a valid duration (in case of single-segment streams, we return either Period duration or mediaPresentation duration) TODO: support SegmentTimeline
This commit is contained in:
parent
5ade664680
commit
b580ee8cd7
2 changed files with 53 additions and 34 deletions
|
@ -1508,6 +1508,11 @@ gst_dash_demux_get_next_fragment_set (GstDashDemux * demux)
|
||||||
stream_idx, &discont, &next_fragment_uri, &duration, ×tamp)) {
|
stream_idx, &discont, &next_fragment_uri, &duration, ×tamp)) {
|
||||||
GST_INFO_OBJECT (demux, "This manifest doesn't contain more fragments");
|
GST_INFO_OBJECT (demux, "This manifest doesn't contain more fragments");
|
||||||
demux->end_of_manifest = TRUE;
|
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_task_start (demux->stream_task);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2501,43 +2501,52 @@ gst_mpd_client_setup_representation (GstMpdClient * client, GstActiveStream *str
|
||||||
/* get the first segment_base of the selected representation */
|
/* get the first segment_base of the selected representation */
|
||||||
if ((stream->cur_segment_base =
|
if ((stream->cur_segment_base =
|
||||||
gst_mpdparser_get_segment_base (client->cur_period, stream->cur_adapt_set, representation)) == NULL) {
|
gst_mpdparser_get_segment_base (client->cur_period, stream->cur_adapt_set, representation)) == NULL) {
|
||||||
GST_WARNING ("No valid SegmentBase node in the MPD file");
|
GST_DEBUG ("No useful SegmentBase node for the current Representation");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the first segment_list of the selected representation */
|
/* get the first segment_list of the selected representation */
|
||||||
if ((stream->cur_segment_list =
|
if ((stream->cur_segment_list =
|
||||||
gst_mpdparser_get_segment_list (client->cur_period, stream->cur_adapt_set, representation)) == NULL) {
|
gst_mpdparser_get_segment_list (client->cur_period, stream->cur_adapt_set, representation)) == NULL) {
|
||||||
GST_WARNING ("No valid SegmentList node in the MPD file, aborting...");
|
GST_DEBUG ("No useful SegmentList node for the current Representation");
|
||||||
return FALSE;
|
/* here we should have a single segment for each representation, whose URL is encoded in the baseURL element */
|
||||||
}
|
|
||||||
|
|
||||||
/* build the list of GstMediaSegment nodes from the SegmentList node */
|
|
||||||
SegmentURL = stream->cur_segment_list->SegmentURL;
|
|
||||||
if (SegmentURL == NULL) {
|
|
||||||
GST_WARNING ("No valid list of SegmentURL nodes in the MPD file, aborting...");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* build segment list */
|
|
||||||
i = stream->cur_segment_list->MultSegBaseType->startNumber;
|
|
||||||
start_time = 0;
|
|
||||||
duration = gst_mpd_client_get_target_duration (client);
|
|
||||||
|
|
||||||
while (SegmentURL) {
|
|
||||||
media_segment = g_slice_new0 (GstMediaSegment);
|
media_segment = g_slice_new0 (GstMediaSegment);
|
||||||
if (media_segment == NULL) {
|
if (media_segment == NULL) {
|
||||||
GST_WARNING ("Allocation of GstMediaSegment struct failed!");
|
GST_WARNING ("Allocation of GstMediaSegment struct failed!");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
stream->segments = g_list_append (stream->segments, media_segment);
|
stream->segments = g_list_append (stream->segments, media_segment);
|
||||||
/* TODO: support SegmentTimeline */
|
media_segment->number = 1;
|
||||||
media_segment->SegmentURL = (GstSegmentURLNode *) SegmentURL->data;
|
media_segment->start_time = 0;
|
||||||
media_segment->number = i;
|
media_segment->duration = PeriodEnd;
|
||||||
media_segment->start_time = start_time;
|
} else {
|
||||||
media_segment->duration = duration;
|
/* build the list of GstMediaSegment nodes from the SegmentList node */
|
||||||
i++;
|
SegmentURL = stream->cur_segment_list->SegmentURL;
|
||||||
start_time += duration;
|
if (SegmentURL == NULL) {
|
||||||
SegmentURL = g_list_next (SegmentURL);
|
GST_WARNING ("No valid list of SegmentURL nodes in the MPD file, aborting...");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* build segment list */
|
||||||
|
i = stream->cur_segment_list->MultSegBaseType->startNumber;
|
||||||
|
start_time = 0;
|
||||||
|
duration = gst_mpd_client_get_target_duration (client);
|
||||||
|
|
||||||
|
while (SegmentURL) {
|
||||||
|
media_segment = g_slice_new0 (GstMediaSegment);
|
||||||
|
if (media_segment == NULL) {
|
||||||
|
GST_WARNING ("Allocation of GstMediaSegment struct failed!");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
stream->segments = g_list_append (stream->segments, media_segment);
|
||||||
|
/* TODO: support SegmentTimeline */
|
||||||
|
media_segment->SegmentURL = (GstSegmentURLNode *) SegmentURL->data;
|
||||||
|
media_segment->number = i;
|
||||||
|
media_segment->start_time = start_time;
|
||||||
|
media_segment->duration = duration;
|
||||||
|
i++;
|
||||||
|
start_time += duration;
|
||||||
|
SegmentURL = g_list_next (SegmentURL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (representation->SegmentTemplate != NULL) {
|
if (representation->SegmentTemplate != NULL) {
|
||||||
|
@ -2836,7 +2845,6 @@ gst_mpd_client_get_current_position (GstMpdClient * client,
|
||||||
|
|
||||||
*timestamp = GST_CLOCK_TIME_NONE;
|
*timestamp = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
/* select stream TODO: support multiple streams */
|
|
||||||
stream = g_list_nth_data (client->active_streams, client->stream_idx);
|
stream = g_list_nth_data (client->active_streams, client->stream_idx);
|
||||||
g_return_if_fail (stream != NULL);
|
g_return_if_fail (stream != NULL);
|
||||||
|
|
||||||
|
@ -2882,15 +2890,21 @@ gst_mpd_client_get_target_duration (GstMpdClient * client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base == NULL || base->SegBaseType == NULL) {
|
if (base == NULL || base->SegBaseType == NULL) {
|
||||||
return GST_CLOCK_TIME_NONE;
|
/* this may happen when we have a single segment */
|
||||||
|
/* TODO: support SegmentTimeline */
|
||||||
|
if (client->cur_period->duration) {
|
||||||
|
duration = client->cur_period->duration * GST_MSECOND;
|
||||||
|
} else {
|
||||||
|
duration = client->mpd_node->mediaPresentationDuration * GST_MSECOND;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
duration = base->duration * GST_SECOND;
|
||||||
|
timescale = base->SegBaseType->timescale;
|
||||||
|
|
||||||
|
if (timescale > 1)
|
||||||
|
duration /= timescale;
|
||||||
}
|
}
|
||||||
|
|
||||||
duration = base->duration * GST_SECOND;
|
|
||||||
timescale = base->SegBaseType->timescale;
|
|
||||||
|
|
||||||
if (timescale > 1)
|
|
||||||
duration /= timescale;
|
|
||||||
|
|
||||||
return duration;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue