summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2015-05-08 16:31:44 -0300
committerThiago Santos <thiagoss@osg.samsung.com>2015-05-13 13:35:14 -0300
commit57a2105a310ac5837758d91ac6300d17595e3066 (patch)
treec826c475eca3388802bf24f16aca66d5ca081e76 /ext
parent6344f86e44d0c31a169fd5942b61e9126b57027f (diff)
downloadgstreamer-plugins-bad-57a2105a310ac5837758d91ac6300d17595e3066.tar.gz
dashdemux: refactor segment iteration for better performance
Segments are now stored with their repeat counts instead of spanding them to multiple segments. This caused advancing to the next segment using a single index to have to iterate over the whole list every time. This commit addresses this by storing both the segment index as well as the repeat index and makes advancing to next segment just an increment of the repeat or the segment index.
Diffstat (limited to 'ext')
-rw-r--r--ext/dash/gstdashdemux.c4
-rw-r--r--ext/dash/gstmpdparser.c148
-rw-r--r--ext/dash/gstmpdparser.h4
3 files changed, 93 insertions, 63 deletions
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 1b18ec182..b20234785 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -619,7 +619,7 @@ gst_dash_demux_setup_streams (GstAdaptiveDemux * demux)
GST_DEBUG_OBJECT (demux, "Seeking to first segment for on-demand stream ");
/* start playing from the first segment */
- gst_mpd_client_set_segment_index_for_all_streams (dashdemux->client, 0);
+ gst_mpd_client_seek_to_first_segment (dashdemux->client);
}
done:
@@ -1301,7 +1301,7 @@ gst_dash_demux_advance_period (GstAdaptiveDemux * demux)
}
gst_dash_demux_setup_all_streams (dashdemux);
- gst_mpd_client_set_segment_index_for_all_streams (dashdemux->client, 0);
+ gst_mpd_client_seek_to_first_segment (dashdemux->client);
}
static GstBuffer *
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index 309dd51b0..5243b85a3 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -3583,21 +3583,16 @@ gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client,
{
GstActiveStream *stream;
gint segment_idx;
- GstMediaSegment currentChunk;
+ GstMediaSegment *currentChunk;
GST_DEBUG ("Stream index: %i", stream_idx);
stream = g_list_nth_data (client->active_streams, stream_idx);
g_return_val_if_fail (stream != NULL, 0);
segment_idx = gst_mpd_client_get_segments_counts (stream) - 1;
- GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx);
-
- if (!gst_mpdparser_get_chunk_by_index (client, stream_idx, segment_idx,
- &currentChunk)) {
- return FALSE;
- }
+ currentChunk = g_ptr_array_index (stream->segments, segment_idx);
- *ts = currentChunk.start;
+ *ts = currentChunk->start + (currentChunk->duration * currentChunk->repeat);
return TRUE;
}
@@ -3608,7 +3603,7 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client,
{
GstActiveStream *stream;
gint segment_idx;
- GstMediaSegment currentChunk;
+ GstMediaSegment *currentChunk;
GST_DEBUG ("Stream index: %i", stream_idx);
stream = g_list_nth_data (client->active_streams, stream_idx);
@@ -3617,12 +3612,11 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client,
segment_idx = gst_mpd_client_get_segment_index (stream);
GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx);
- if (!gst_mpdparser_get_chunk_by_index (client, stream_idx, segment_idx,
- &currentChunk)) {
- return FALSE;
- }
+ currentChunk = g_ptr_array_index (stream->segments, segment_idx);
- *ts = currentChunk.start;
+ *ts =
+ currentChunk->start +
+ (currentChunk->duration * stream->segment_repeat_index);
return TRUE;
}
@@ -3646,7 +3640,7 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
guint indexStream, GstMediaFragmentInfo * fragment)
{
GstActiveStream *stream = NULL;
- GstMediaSegment currentChunk;
+ GstMediaSegment *currentChunk;
gchar *mediaURL = NULL;
gchar *indexURL = NULL;
GstUri *base_url, *frag_url;
@@ -3662,51 +3656,57 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
segment_idx = gst_mpd_client_get_segment_index (stream);
GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx);
- if (!gst_mpdparser_get_chunk_by_index (client, indexStream, segment_idx,
- &currentChunk)) {
- return FALSE;
- }
+ currentChunk = g_ptr_array_index (stream->segments, segment_idx);
- GST_DEBUG ("currentChunk->SegmentURL = %p", currentChunk.SegmentURL);
- if (currentChunk.SegmentURL != NULL) {
+ GST_DEBUG ("currentChunk->SegmentURL = %p", currentChunk->SegmentURL);
+ if (currentChunk->SegmentURL != NULL) {
mediaURL =
- g_strdup (gst_mpdparser_get_mediaURL (stream, currentChunk.SegmentURL));
- indexURL = currentChunk.SegmentURL->index;
+ g_strdup (gst_mpdparser_get_mediaURL (stream,
+ currentChunk->SegmentURL));
+ indexURL = currentChunk->SegmentURL->index;
} else if (stream->cur_seg_template != NULL) {
mediaURL =
gst_mpdparser_build_URL_from_template (stream->cur_seg_template->media,
- stream->cur_representation->id, currentChunk.number,
- stream->cur_representation->bandwidth, currentChunk.scale_start);
+ stream->cur_representation->id,
+ currentChunk->number + stream->segment_repeat_index,
+ stream->cur_representation->bandwidth,
+ currentChunk->scale_start +
+ stream->segment_repeat_index * currentChunk->scale_duration);
if (stream->cur_seg_template->index) {
indexURL =
gst_mpdparser_build_URL_from_template (stream->
cur_seg_template->index, stream->cur_representation->id,
- currentChunk.number, stream->cur_representation->bandwidth,
- currentChunk.scale_start);
+ currentChunk->number + stream->segment_repeat_index,
+ stream->cur_representation->bandwidth,
+ currentChunk->scale_start +
+ stream->segment_repeat_index * currentChunk->scale_duration);
}
}
GST_DEBUG ("mediaURL = %s", mediaURL);
GST_DEBUG ("indexURL = %s", indexURL);
- fragment->timestamp = currentChunk.start;
- fragment->duration = currentChunk.duration;
- fragment->discontinuity = segment_idx != currentChunk.number;
+ fragment->timestamp =
+ currentChunk->start +
+ stream->segment_repeat_index * currentChunk->duration;
+ fragment->duration = currentChunk->duration;
+ /* FIXME rework discont checking */
+ /* fragment->discontinuity = segment_idx != currentChunk.number; */
fragment->range_start = 0;
fragment->range_end = -1;
fragment->index_uri = NULL;
fragment->index_range_start = 0;
fragment->index_range_end = -1;
- if (currentChunk.SegmentURL) {
- if (currentChunk.SegmentURL->mediaRange) {
+ if (currentChunk->SegmentURL) {
+ if (currentChunk->SegmentURL->mediaRange) {
fragment->range_start =
- currentChunk.SegmentURL->mediaRange->first_byte_pos;
- fragment->range_end = currentChunk.SegmentURL->mediaRange->last_byte_pos;
+ currentChunk->SegmentURL->mediaRange->first_byte_pos;
+ fragment->range_end = currentChunk->SegmentURL->mediaRange->last_byte_pos;
}
- if (currentChunk.SegmentURL->indexRange) {
+ if (currentChunk->SegmentURL->indexRange) {
fragment->index_range_start =
- currentChunk.SegmentURL->indexRange->first_byte_pos;
+ currentChunk->SegmentURL->indexRange->first_byte_pos;
fragment->index_range_end =
- currentChunk.SegmentURL->indexRange->last_byte_pos;
+ currentChunk->SegmentURL->indexRange->last_byte_pos;
}
}
@@ -3743,35 +3743,44 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client,
}
}
-
GST_DEBUG ("Loading chunk with URL %s", fragment->uri);
return TRUE;
}
-static GstFlowReturn
-gst_mpd_client_update_segment (GstMpdClient * client, GstActiveStream * stream,
- gint update)
+GstFlowReturn
+gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
+ gboolean forward)
{
- guint segment_idx;
-
- segment_idx = gst_mpd_client_get_segment_index (stream);
- GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx + update);
+ GstMediaSegment *segment;
- gst_mpd_client_set_segment_index (stream, segment_idx + update);
+ if (stream->segment_index >= stream->segments->len)
+ return GST_FLOW_EOS;
- return GST_FLOW_OK;
-}
+ segment = g_ptr_array_index (stream->segments, stream->segment_index);
+ if (forward) {
+ if (stream->segment_repeat_index >= segment->repeat) {
+ stream->segment_repeat_index = 0;
+ stream->segment_index++;
+ if (stream->segment_index >= stream->segments->len)
+ return GST_FLOW_EOS;
+ } else {
+ stream->segment_repeat_index++;
+ }
+ } else {
+ if (stream->segment_repeat_index == 0) {
+ stream->segment_index--;
+ if (stream->segment_index < 0)
+ return GST_FLOW_EOS;
-GstFlowReturn
-gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream,
- gboolean forward)
-{
- if (forward)
- return gst_mpd_client_update_segment (client, stream, 1);
- else
- return gst_mpd_client_update_segment (client, stream, -1);
+ segment = g_ptr_array_index (stream->segments, stream->segment_index);
+ stream->segment_repeat_index = segment->repeat;
+ } else {
+ stream->segment_repeat_index--;
+ }
+ }
+ return GST_FLOW_OK;
}
gboolean
@@ -4018,12 +4027,12 @@ gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client,
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;
+ stream->segment_index = segment_idx;
+ stream->segment_repeat_index = 0;
}
}
}
@@ -4033,7 +4042,8 @@ gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx)
{
g_return_if_fail (stream != NULL);
- stream->segment_idx = segment_idx;
+ stream->segment_index = segment_idx;
+ stream->segment_repeat_index = 0;
}
guint
@@ -4041,7 +4051,25 @@ gst_mpd_client_get_segment_index (GstActiveStream * stream)
{
g_return_val_if_fail (stream != NULL, 0);
- return stream->segment_idx;
+ return stream->segment_index;
+}
+
+void
+gst_mpd_client_seek_to_first_segment (GstMpdClient * client)
+{
+ GList *list;
+
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (client->active_streams != NULL);
+
+ for (list = g_list_first (client->active_streams); list;
+ list = g_list_next (list)) {
+ GstActiveStream *stream = (GstActiveStream *) list->data;
+ if (stream) {
+ stream->segment_index = 0;
+ stream->segment_repeat_index = 0;
+ }
+ }
}
static guint
diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h
index ddafd4b01..7298d3c88 100644
--- a/ext/dash/gstmpdparser.h
+++ b/ext/dash/gstmpdparser.h
@@ -456,7 +456,8 @@ struct _GstActiveStream
GstSegmentBaseType *cur_segment_base; /* active segment base */
GstSegmentListNode *cur_segment_list; /* active segment list */
GstSegmentTemplateNode *cur_seg_template; /* active segment template */
- guint segment_idx; /* index of next sequence chunk */
+ guint segment_index; /* index of next sequence chunk */
+ guint segment_repeat_index; /* index of the repeat count of a segment */
GPtrArray *segments; /* array of GstMediaSegment */
GstClockTime presentationTimeOffset; /* presentation time offset of the current segment */
};
@@ -538,6 +539,7 @@ void gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, gu
guint gst_mpd_client_get_segment_index (GstActiveStream * stream);
void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx);
GstFlowReturn gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
+void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
/* Get audio/video stream parameters (mimeType, width, height, rate, number of channels) */
const gchar *gst_mpd_client_get_stream_mimeType (GstActiveStream * stream);