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
This commit is contained in:
Thiago Santos 2016-02-01 10:49:23 -03:00
parent 731ab94cc3
commit 40faf9e09b
2 changed files with 72 additions and 10 deletions

View file

@ -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;

View file

@ -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;