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:
Vincent Penquerc'h 2015-09-09 14:49:17 +01:00
parent 69bfa8222f
commit 50400fa2a6

View file

@ -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--;
} }