mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-26 17:18:15 +00:00
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.
This commit is contained in:
parent
6344f86e44
commit
57a2105a31
3 changed files with 94 additions and 64 deletions
|
@ -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 *
|
||||
|
|
|
@ -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);
|
||||
currentChunk = g_ptr_array_index (stream->segments, segment_idx);
|
||||
|
||||
if (!gst_mpdparser_get_chunk_by_index (client, stream_idx, segment_idx,
|
||||
¤tChunk)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*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,
|
||||
¤tChunk)) {
|
||||
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,
|
||||
¤tChunk)) {
|
||||
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)
|
||||
{
|
||||
guint segment_idx;
|
||||
|
||||
segment_idx = gst_mpd_client_get_segment_index (stream);
|
||||
GST_DEBUG ("Looking for fragment sequence chunk %d", segment_idx + update);
|
||||
|
||||
gst_mpd_client_set_segment_index (stream, segment_idx + update);
|
||||
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
GstMediaSegment *segment;
|
||||
|
||||
if (stream->segment_index >= stream->segments->len)
|
||||
return GST_FLOW_EOS;
|
||||
|
||||
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;
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue