From ea90ceac011567b1b5696696e23a039f88737513 Mon Sep 17 00:00:00 2001 From: George Kiagiadakis Date: Wed, 6 Aug 2014 18:11:20 +0300 Subject: [PATCH] dashdemux: support downloading segments in reverse order When a seek with a negative rate is requested, find the target segment where gstsegment.stop belongs in and then download from this segment backwards until the first segment. This allows proper reverse playback. --- ext/dash/gstdashdemux.c | 8 ++++++-- ext/dash/gstmpdparser.c | 5 +++-- ext/dash/gstmpdparser.h | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c index 605d6074c4..a46e6ab4d2 100644 --- a/ext/dash/gstdashdemux.c +++ b/ext/dash/gstdashdemux.c @@ -511,7 +511,10 @@ gst_dash_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event) gst_dash_demux_wait_stop (demux); /* select the requested Period in the Media Presentation */ - target_pos = (GstClockTime) demux->segment.start; + if (demux->segment.rate > 0.0) + target_pos = (GstClockTime) demux->segment.start; + else + target_pos = (GstClockTime) demux->segment.stop; GST_DEBUG_OBJECT (demux, "Seeking to target %" GST_TIME_FORMAT, GST_TIME_ARGS (target_pos)); current_period = 0; @@ -2216,7 +2219,8 @@ gst_dash_demux_stream_download_fragment (GstDashDemux * demux, } g_mutex_lock (&stream->fragment_download_lock); - if (gst_mpd_client_get_next_fragment (demux->client, stream_idx, fragment)) { + if (gst_mpd_client_get_next_fragment (demux->client, stream_idx, fragment, + stream->demux->segment.rate > 0.0)) { GST_INFO_OBJECT (stream->pad, "Fetching next fragment %s ts:%" GST_TIME_FORMAT " dur:%" GST_TIME_FORMAT " Range:%" G_GINT64_FORMAT "-%" G_GINT64_FORMAT, diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c index 0b3b5ecc1c..29c8c1add8 100644 --- a/ext/dash/gstmpdparser.c +++ b/ext/dash/gstmpdparser.c @@ -3574,7 +3574,7 @@ gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, gboolean gst_mpd_client_get_next_fragment (GstMpdClient * client, - guint indexStream, GstMediaFragmentInfo * fragment) + guint indexStream, GstMediaFragmentInfo * fragment, gboolean forward) { GstActiveStream *stream = NULL; GstMediaSegment currentChunk; @@ -3679,7 +3679,8 @@ gst_mpd_client_get_next_fragment (GstMpdClient * client, } } - gst_mpd_client_set_segment_index (stream, segment_idx + 1); + gst_mpd_client_set_segment_index (stream, + forward ? segment_idx + 1 : segment_idx - 1); GST_MPD_CLIENT_UNLOCK (client); GST_DEBUG ("Loading chunk with URL %s", fragment->uri); diff --git a/ext/dash/gstmpdparser.h b/ext/dash/gstmpdparser.h index 5d059b8ed1..24755dee6d 100644 --- a/ext/dash/gstmpdparser.h +++ b/ext/dash/gstmpdparser.h @@ -492,7 +492,7 @@ GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, G GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client); gboolean gst_mpd_client_get_last_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts); gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts); -gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, GstMediaFragmentInfo * fragment); +gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, GstMediaFragmentInfo * fragment, gboolean forward); gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end); gboolean gst_mpd_client_get_next_header_index (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end); gboolean gst_mpd_client_is_live (GstMpdClient * client);