mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
mpdparser: support for negative repeat count in segments
Implements negative repeat segment fields, defined in 5.3.9.6.1.
This commit is contained in:
parent
69bfa8222f
commit
50400fa2a6
1 changed files with 87 additions and 18 deletions
|
@ -1314,12 +1314,6 @@ gst_mpdparser_parse_s_node (GQueue * queue, xmlNode * a_node)
|
||||||
gst_mpdparser_get_xml_prop_unsigned_integer_64 (a_node, "d", 0,
|
gst_mpdparser_get_xml_prop_unsigned_integer_64 (a_node, "d", 0,
|
||||||
&new_s_node->d);
|
&new_s_node->d);
|
||||||
gst_mpdparser_get_xml_prop_signed_integer (a_node, "r", 0, &new_s_node->r);
|
gst_mpdparser_get_xml_prop_signed_integer (a_node, "r", 0, &new_s_node->r);
|
||||||
|
|
||||||
/* we don't support negative r values yet (5.3.9.6.1) */
|
|
||||||
if (new_s_node->r < 0) {
|
|
||||||
GST_WARNING ("Negative r are unsupported, defaulting to 0");
|
|
||||||
new_s_node->r = 0; /* single segment */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstSegmentTimelineNode *
|
static GstSegmentTimelineNode *
|
||||||
|
@ -3076,6 +3070,27 @@ gst_mpdparser_get_baseURL (GstMpdClient * client, guint indexStream)
|
||||||
return stream->baseURL;
|
return stream->baseURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstClockTime
|
||||||
|
gst_mpdparser_get_segment_end_time (GstMpdClient * client, GPtrArray * segments,
|
||||||
|
const GstMediaSegment * segment, gint index)
|
||||||
|
{
|
||||||
|
const GstStreamPeriod *stream_period;
|
||||||
|
GstClockTime end;
|
||||||
|
|
||||||
|
if (segment->repeat >= 0)
|
||||||
|
return segment->start + (segment->repeat + 1) * segment->duration;
|
||||||
|
|
||||||
|
if (index < segments->len - 1) {
|
||||||
|
const GstMediaSegment *next_segment =
|
||||||
|
g_ptr_array_index (segments, index + 1);
|
||||||
|
end = next_segment->start;
|
||||||
|
} else {
|
||||||
|
stream_period = gst_mpdparser_get_stream_period (client);
|
||||||
|
end = stream_period->start + stream_period->duration;
|
||||||
|
}
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_mpdparser_find_segment_by_index (GstMpdClient * client,
|
gst_mpdparser_find_segment_by_index (GstMpdClient * client,
|
||||||
GPtrArray * segments, gint index, GstMediaSegment * result)
|
GPtrArray * segments, gint index, GstMediaSegment * result)
|
||||||
|
@ -3083,9 +3098,18 @@ gst_mpdparser_find_segment_by_index (GstMpdClient * client,
|
||||||
gint i;
|
gint i;
|
||||||
for (i = 0; i < segments->len; i++) {
|
for (i = 0; i < segments->len; i++) {
|
||||||
GstMediaSegment *s;
|
GstMediaSegment *s;
|
||||||
|
gint repeat;
|
||||||
|
|
||||||
s = g_ptr_array_index (segments, i);
|
s = g_ptr_array_index (segments, i);
|
||||||
if (s->number + s->repeat >= index) {
|
if (s->repeat >= 0) {
|
||||||
|
repeat = s->repeat;
|
||||||
|
} else {
|
||||||
|
GstClockTime start = s->start;
|
||||||
|
GstClockTime end =
|
||||||
|
gst_mpdparser_get_segment_end_time (client, segments, s, i);
|
||||||
|
repeat = (guint) (end - start) / s->duration;
|
||||||
|
}
|
||||||
|
if (s->number + repeat >= index) {
|
||||||
/* it is in this segment */
|
/* it is in this segment */
|
||||||
result->SegmentURL = s->SegmentURL;
|
result->SegmentURL = s->SegmentURL;
|
||||||
result->number = index;
|
result->number = index;
|
||||||
|
@ -3616,6 +3640,7 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
|
||||||
gint index = 0;
|
gint index = 0;
|
||||||
gint repeat_index = 0;
|
gint repeat_index = 0;
|
||||||
GstMediaSegment *selectedChunk = NULL;
|
GstMediaSegment *selectedChunk = NULL;
|
||||||
|
gboolean in_segment;
|
||||||
|
|
||||||
g_return_val_if_fail (stream != NULL, 0);
|
g_return_val_if_fail (stream != NULL, 0);
|
||||||
|
|
||||||
|
@ -3625,13 +3650,24 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
|
||||||
|
|
||||||
GST_DEBUG ("Looking at fragment sequence chunk %d / %d", index,
|
GST_DEBUG ("Looking at fragment sequence chunk %d / %d", index,
|
||||||
stream->segments->len);
|
stream->segments->len);
|
||||||
if (segment->start <= ts
|
in_segment = FALSE;
|
||||||
&& ts < segment->start + (segment->repeat + 1) * segment->duration) {
|
if (segment->start <= ts) {
|
||||||
|
if (segment->repeat >= 0) {
|
||||||
|
in_segment =
|
||||||
|
ts < segment->start + (segment->repeat + 1) * segment->duration;
|
||||||
|
} else {
|
||||||
|
GstClockTime end =
|
||||||
|
gst_mpdparser_get_segment_end_time (client, stream->segments,
|
||||||
|
segment, index);
|
||||||
|
in_segment = ts < end;
|
||||||
|
}
|
||||||
|
if (in_segment) {
|
||||||
selectedChunk = segment;
|
selectedChunk = segment;
|
||||||
repeat_index = (ts - segment->start) / segment->duration;
|
repeat_index = (ts - segment->start) / segment->duration;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (selectedChunk == NULL) {
|
if (selectedChunk == NULL) {
|
||||||
stream->segment_index = stream->segments->len;
|
stream->segment_index = stream->segments->len;
|
||||||
|
@ -3730,6 +3766,7 @@ gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client,
|
||||||
GstActiveStream *stream;
|
GstActiveStream *stream;
|
||||||
gint segment_idx;
|
gint segment_idx;
|
||||||
GstMediaSegment *currentChunk;
|
GstMediaSegment *currentChunk;
|
||||||
|
GstStreamPeriod *stream_period;
|
||||||
|
|
||||||
GST_DEBUG ("Stream index: %i", stream_idx);
|
GST_DEBUG ("Stream index: %i", stream_idx);
|
||||||
stream = g_list_nth_data (client->active_streams, stream_idx);
|
stream = g_list_nth_data (client->active_streams, stream_idx);
|
||||||
|
@ -3738,9 +3775,18 @@ gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client,
|
||||||
segment_idx = gst_mpd_client_get_segments_counts (client, stream) - 1;
|
segment_idx = gst_mpd_client_get_segments_counts (client, stream) - 1;
|
||||||
currentChunk = g_ptr_array_index (stream->segments, segment_idx);
|
currentChunk = g_ptr_array_index (stream->segments, segment_idx);
|
||||||
|
|
||||||
|
if (currentChunk->repeat >= 0) {
|
||||||
*ts =
|
*ts =
|
||||||
currentChunk->start + (currentChunk->duration * (1 +
|
currentChunk->start + (currentChunk->duration * (1 +
|
||||||
currentChunk->repeat));
|
currentChunk->repeat));
|
||||||
|
} else {
|
||||||
|
/* 5.3.9.6.1: negative repeat means repeat till the end of the
|
||||||
|
* period, or the next update of the MPD (which I think is
|
||||||
|
* implicit, as this will all get deleted/recreated), or the
|
||||||
|
* start of the next segment, if any. */
|
||||||
|
stream_period = gst_mpdparser_get_stream_period (client);
|
||||||
|
*ts = stream_period->start + stream_period->duration;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -4082,7 +4128,17 @@ gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
|
||||||
if (stream->segment_index >= segments_count) {
|
if (stream->segment_index >= segments_count) {
|
||||||
stream->segment_index = segments_count - 1;
|
stream->segment_index = segments_count - 1;
|
||||||
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
||||||
|
if (segment->repeat >= 0) {
|
||||||
stream->segment_repeat_index = segment->repeat;
|
stream->segment_repeat_index = segment->repeat;
|
||||||
|
} else {
|
||||||
|
GstClockTime start = segment->start;
|
||||||
|
GstClockTime end =
|
||||||
|
gst_mpdparser_get_segment_end_time (client, stream->segments,
|
||||||
|
segment,
|
||||||
|
stream->segment_index);
|
||||||
|
stream->segment_repeat_index =
|
||||||
|
(guint) (end - start) / segment->duration;
|
||||||
|
}
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4090,7 +4146,7 @@ gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
|
||||||
/* for the normal cases we can get the segment safely here */
|
/* for the normal cases we can get the segment safely here */
|
||||||
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
||||||
if (forward) {
|
if (forward) {
|
||||||
if (stream->segment_repeat_index >= segment->repeat) {
|
if (segment->repeat >= 0 && stream->segment_repeat_index >= segment->repeat) {
|
||||||
stream->segment_repeat_index = 0;
|
stream->segment_repeat_index = 0;
|
||||||
stream->segment_index++;
|
stream->segment_index++;
|
||||||
if (segments_count > 0 && stream->segment_index >= segments_count) {
|
if (segments_count > 0 && stream->segment_index >= segments_count) {
|
||||||
|
@ -4109,7 +4165,20 @@ gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
segment = g_ptr_array_index (stream->segments, stream->segment_index);
|
||||||
|
/* negative repeats only seem to make sense at the end of a list,
|
||||||
|
* so this one will probably not be. Needs some sanity checking
|
||||||
|
* when loading the XML data. */
|
||||||
|
if (segment->repeat >= 0) {
|
||||||
stream->segment_repeat_index = segment->repeat;
|
stream->segment_repeat_index = segment->repeat;
|
||||||
|
} else {
|
||||||
|
GstClockTime start = segment->start;
|
||||||
|
GstClockTime end =
|
||||||
|
gst_mpdparser_get_segment_end_time (client, stream->segments,
|
||||||
|
segment,
|
||||||
|
stream->segment_index);
|
||||||
|
stream->segment_repeat_index =
|
||||||
|
(guint) (end - start) / segment->duration;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stream->segment_repeat_index--;
|
stream->segment_repeat_index--;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue