mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-09 05:38:58 +00:00
dashdemux: fix seeking on multiple streams
Each stream has its own durations and timestamps, the fragment number is different for each stream when seeking, so the seek has to be done for all streams, rather than on a single stream and propagated to others
This commit is contained in:
parent
7330225ac8
commit
80c6973319
3 changed files with 46 additions and 50 deletions
|
@ -531,10 +531,9 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event)
|
|||
GList *list;
|
||||
GstClockTime current_pos, target_pos;
|
||||
guint current_sequence, current_period;
|
||||
GstActiveStream *stream;
|
||||
GstActiveStream *active_stream;
|
||||
GstMediaSegment *chunk;
|
||||
GstStreamPeriod *period;
|
||||
guint nb_active_stream;
|
||||
GSList *iter;
|
||||
|
||||
GST_WARNING_OBJECT (demux, "Received seek event");
|
||||
|
@ -555,6 +554,26 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event)
|
|||
GST_TIME_FORMAT, rate, start_type, GST_TIME_ARGS (start),
|
||||
GST_TIME_ARGS (stop));
|
||||
|
||||
if (flags & GST_SEEK_FLAG_FLUSH) {
|
||||
GST_DEBUG_OBJECT (demux, "sending flush start");
|
||||
for (iter = demux->streams; iter; iter = g_slist_next (iter)) {
|
||||
GstDashDemuxStream *stream;
|
||||
stream = iter->data;
|
||||
gst_pad_push_event (stream->pad, gst_event_new_flush_start ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop the demux */
|
||||
demux->cancelled = TRUE;
|
||||
gst_dash_demux_stop (demux);
|
||||
|
||||
/* Wait for streaming to finish */
|
||||
g_static_rec_mutex_lock (&demux->stream_lock);
|
||||
|
||||
/* Clear the buffering queue */
|
||||
/* FIXME: allow seeking in the buffering queue */
|
||||
gst_dash_demux_clear_queues (demux);
|
||||
|
||||
//GST_MPD_CLIENT_LOCK (demux->client);
|
||||
|
||||
/* select the requested Period in the Media Presentation */
|
||||
|
@ -582,57 +601,35 @@ gst_dash_demux_src_event (GstPad * pad, GstEvent * event)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
stream = gst_mpdparser_get_active_stream_by_index (demux->client, 0);
|
||||
current_pos = 0;
|
||||
current_sequence = 0;
|
||||
for (list = g_list_first (stream->segments); list;
|
||||
list = g_list_next (list)) {
|
||||
chunk = list->data;
|
||||
current_pos = chunk->start_time;
|
||||
//current_sequence = chunk->number;
|
||||
GST_WARNING_OBJECT (demux, "%llu <= %llu (%llu)", current_pos,
|
||||
target_pos, chunk->duration);
|
||||
if (current_pos <= target_pos
|
||||
&& target_pos < current_pos + chunk->duration) {
|
||||
break;
|
||||
}
|
||||
current_sequence++;
|
||||
}
|
||||
//GST_MPD_CLIENT_UNLOCK (demux->client);
|
||||
|
||||
if (list == NULL) {
|
||||
GST_WARNING_OBJECT (demux, "Could not find seeked fragment");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We can actually perform the seek */
|
||||
nb_active_stream = gst_mpdparser_get_nb_active_stream (demux->client);
|
||||
|
||||
if (flags & GST_SEEK_FLAG_FLUSH) {
|
||||
GST_DEBUG_OBJECT (demux, "sending flush start");
|
||||
for (iter = demux->streams; iter; iter = g_slist_next (iter)) {
|
||||
GstDashDemuxStream *stream;
|
||||
stream = iter->data;
|
||||
gst_pad_push_event (stream->pad, gst_event_new_flush_start ());
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop the demux */
|
||||
demux->cancelled = TRUE;
|
||||
gst_dash_demux_stop (demux);
|
||||
|
||||
/* Wait for streaming to finish */
|
||||
g_static_rec_mutex_lock (&demux->stream_lock);
|
||||
|
||||
/* Clear the buffering queue */
|
||||
/* FIXME: allow seeking in the buffering queue */
|
||||
gst_dash_demux_clear_queues (demux);
|
||||
|
||||
//GST_MPD_CLIENT_LOCK (demux->client);
|
||||
GST_DEBUG_OBJECT (demux, "Seeking to sequence %d", current_sequence);
|
||||
/* Update the current sequence on all streams */
|
||||
gst_mpd_client_set_segment_index_for_all_streams (demux->client,
|
||||
current_sequence);
|
||||
for (iter = demux->streams; iter; iter = g_slist_next (iter)) {
|
||||
GstDashDemuxStream *stream = iter->data;
|
||||
|
||||
active_stream =
|
||||
gst_mpdparser_get_active_stream_by_index (demux->client,
|
||||
stream->index);
|
||||
current_pos = 0;
|
||||
current_sequence = 0;
|
||||
for (list = g_list_first (active_stream->segments); list;
|
||||
list = g_list_next (list)) {
|
||||
chunk = list->data;
|
||||
current_pos = chunk->start_time;
|
||||
//current_sequence = chunk->number;
|
||||
GST_WARNING_OBJECT (demux, "%llu <= %llu (%llu)", current_pos,
|
||||
target_pos, chunk->duration);
|
||||
if (current_pos <= target_pos
|
||||
&& target_pos < current_pos + chunk->duration) {
|
||||
break;
|
||||
}
|
||||
current_sequence++;
|
||||
}
|
||||
gst_mpd_client_set_segment_index (active_stream, current_sequence);
|
||||
}
|
||||
/* Calculate offset in the next fragment */
|
||||
demux->position = gst_mpd_client_get_current_position (demux->client);
|
||||
demux->position_shift = start - demux->position;
|
||||
|
|
|
@ -127,8 +127,6 @@ static gboolean gst_mpd_client_add_media_segment (GstActiveStream * stream,
|
|||
GstClockTime start_time, GstClockTime duration);
|
||||
static const gchar *gst_mpdparser_mimetype_to_caps (const gchar * mimeType);
|
||||
static GstClockTime gst_mpd_client_get_segment_duration (GstMpdClient * client);
|
||||
static void gst_mpd_client_set_segment_index (GstActiveStream * stream,
|
||||
guint segment_idx);
|
||||
|
||||
/* Adaptation Set */
|
||||
static GstAdaptationSetNode
|
||||
|
@ -3338,7 +3336,7 @@ gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx)
|
||||
{
|
||||
g_return_if_fail (stream != NULL);
|
||||
|
|
|
@ -496,6 +496,7 @@ guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client);
|
|||
/* Segment */
|
||||
void gst_mpd_client_set_segment_index_for_all_streams (GstMpdClient * client, guint segment_idx);
|
||||
guint gst_mpd_client_get_segment_index (GstActiveStream * stream);
|
||||
void gst_mpd_client_set_segment_index (GstActiveStream * stream, guint segment_idx);
|
||||
|
||||
/* 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