summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2016-02-01 10:49:23 -0300
committerThiago Santos <thiagoss@osg.samsung.com>2016-02-04 14:09:35 -0300
commit40faf9e09b4180b77858a873d51e977da8dc9360 (patch)
treeb76719384b2230399641dc940cf4f5610f33c7a0
parent731ab94cc3ffc7dd906423a008ceca94962ab992 (diff)
downloadgstreamer-plugins-bad-40faf9e09b4180b77858a873d51e977da8dc9360.tar.gz
dashdemux: implement snap seek handling
Handle snap seeking at the stream_seek method and let superclass do the rest to support snap seeking https://bugzilla.gnome.org/show_bug.cgi?id=759158
-rw-r--r--ext/dash/gstdashdemux.c36
-rw-r--r--ext/dash/gstmpdparser.c46
2 files changed, 72 insertions, 10 deletions
diff --git a/ext/dash/gstdashdemux.c b/ext/dash/gstdashdemux.c
index 966fdc53b..7267ae08b 100644
--- a/ext/dash/gstdashdemux.c
+++ b/ext/dash/gstdashdemux.c
@@ -1067,7 +1067,8 @@ gst_dash_demux_index_entry_search (GstSidxBoxEntry * entry, GstClockTime * ts,
static void
gst_dash_demux_stream_sidx_seek (GstDashDemuxStream * dashstream,
- GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts)
+ gboolean forward, GstSeekFlags flags, GstClockTime ts,
+ GstClockTime * final_ts)
{
GstSidxBox *sidx = SIDX (dashstream);
GstSidxBoxEntry *entry;
@@ -1077,13 +1078,34 @@ gst_dash_demux_stream_sidx_seek (GstDashDemuxStream * dashstream,
if (sidx->entries[idx - 1].pts + sidx->entries[idx - 1].duration < ts) {
dashstream->sidx_current_remaining = 0;
} else {
+ GstSearchMode mode = GST_SEARCH_MODE_BEFORE;
+
+ if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST) {
+ mode = GST_SEARCH_MODE_BEFORE;
+ } else if ((forward && (flags & GST_SEEK_FLAG_SNAP_AFTER)) ||
+ (!forward && (flags & GST_SEEK_FLAG_SNAP_BEFORE))) {
+ mode = GST_SEARCH_MODE_AFTER;
+ } else {
+ mode = GST_SEARCH_MODE_BEFORE;
+ }
+
entry =
gst_util_array_binary_search (sidx->entries, sidx->entries_count,
sizeof (GstSidxBoxEntry),
- (GCompareDataFunc) gst_dash_demux_index_entry_search,
- GST_SEARCH_MODE_BEFORE, &ts, NULL);
+ (GCompareDataFunc) gst_dash_demux_index_entry_search, mode, &ts, NULL);
idx = entry - sidx->entries;
+
+ /* FIXME in reverse mode, if we are exactly at a fragment start it makes more
+ * sense to start from the end of the previous fragment */
+ /* FIXME we should have a GST_SEARCH_MODE_NEAREST */
+ if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST &&
+ idx + 1 < sidx->entries_count) {
+ if (ABS (sidx->entries[idx + 1].pts - ts) <
+ ABS (sidx->entries[idx].pts - ts))
+ idx += 1;
+ }
+
dashstream->sidx_current_remaining = sidx->entries[idx].size;
}
@@ -1107,7 +1129,8 @@ gst_dash_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
if (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {
if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
- gst_dash_demux_stream_sidx_seek (dashstream, flags, ts, final_ts);
+ gst_dash_demux_stream_sidx_seek (dashstream, forward, flags, ts,
+ final_ts);
} else {
/* no index yet, seek when we have it */
/* FIXME - the final_ts won't be correct here */
@@ -1611,8 +1634,9 @@ gst_dash_demux_data_received (GstAdaptiveDemux * demux,
if (dash_stream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
if (GST_CLOCK_TIME_IS_VALID (dash_stream->pending_seek_ts)) {
/* FIXME, preserve seek flags */
- gst_dash_demux_stream_sidx_seek (dash_stream, 0,
- dash_stream->pending_seek_ts, NULL);
+ gst_dash_demux_stream_sidx_seek (dash_stream,
+ demux->segment.rate >= 0, 0, dash_stream->pending_seek_ts,
+ NULL);
dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
} else {
SIDX (dash_stream)->entry_index = dash_stream->sidx_index;
diff --git a/ext/dash/gstmpdparser.c b/ext/dash/gstmpdparser.c
index 62ebbd68b..234008ee3 100644
--- a/ext/dash/gstmpdparser.c
+++ b/ext/dash/gstmpdparser.c
@@ -4670,18 +4670,48 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
stream->segments->len);
in_segment = FALSE;
if (segment->start <= ts) {
+ GstClockTime end_time;
+
if (segment->repeat >= 0) {
- in_segment =
- ts < segment->start + (segment->repeat + 1) * segment->duration;
+ end_time = segment->start + (segment->repeat + 1) * segment->duration;
} else {
- GstClockTime end =
+ end_time =
gst_mpdparser_get_segment_end_time (client, stream->segments,
segment, index);
- in_segment = ts < end;
}
+
+ /* avoid downloading another fragment just for 1ns in reverse mode */
+ if (forward)
+ in_segment = ts < end_time;
+ else
+ in_segment = ts <= end_time;
+
if (in_segment) {
selectedChunk = segment;
repeat_index = (ts - segment->start) / segment->duration;
+
+ /* At the end of a segment in reverse mode, start from the previous fragment */
+ if (!forward && repeat_index > 0
+ && ((ts - segment->start) % segment->duration == 0))
+ repeat_index--;
+
+ if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) ==
+ GST_SEEK_FLAG_SNAP_NEAREST) {
+ /* FIXME implement this */
+ } else if ((forward && flags & GST_SEEK_FLAG_SNAP_AFTER) ||
+ (!forward && flags & GST_SEEK_FLAG_SNAP_BEFORE)) {
+
+ if (repeat_index + 1 < segment->repeat) {
+ repeat_index++;
+ } else {
+ repeat_index = 0;
+ if (index + 1 >= stream->segments->len) {
+ selectedChunk = NULL;
+ } else {
+ selectedChunk = g_ptr_array_index (stream->segments, index + 1);
+ }
+ }
+ }
break;
}
}
@@ -4714,6 +4744,14 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
ts = 0;
index = ts / duration;
+
+ if ((flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST) {
+ /* FIXME implement this */
+ } else if ((forward && flags & GST_SEEK_FLAG_SNAP_AFTER) ||
+ (!forward && flags & GST_SEEK_FLAG_SNAP_BEFORE)) {
+ index++;
+ }
+
if (segments_count > 0 && index >= segments_count) {
stream->segment_index = segments_count;
stream->segment_repeat_index = 0;