diff options
author | Thiago Santos <thiagoss@osg.samsung.com> | 2016-02-01 10:49:23 -0300 |
---|---|---|
committer | Thiago Santos <thiagoss@osg.samsung.com> | 2016-02-04 14:09:35 -0300 |
commit | 40faf9e09b4180b77858a873d51e977da8dc9360 (patch) | |
tree | b76719384b2230399641dc940cf4f5610f33c7a0 | |
parent | 731ab94cc3ffc7dd906423a008ceca94962ab992 (diff) | |
download | gstreamer-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.c | 36 | ||||
-rw-r--r-- | ext/dash/gstmpdparser.c | 46 |
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; |