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:
parent
731ab94cc3
commit
40faf9e09b
@ -1067,7 +1067,8 @@ gst_dash_demux_index_entry_search (GstSidxBoxEntry * entry, GstClockTime * ts,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
gst_dash_demux_stream_sidx_seek (GstDashDemuxStream * dashstream,
|
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);
|
GstSidxBox *sidx = SIDX (dashstream);
|
||||||
GstSidxBoxEntry *entry;
|
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) {
|
if (sidx->entries[idx - 1].pts + sidx->entries[idx - 1].duration < ts) {
|
||||||
dashstream->sidx_current_remaining = 0;
|
dashstream->sidx_current_remaining = 0;
|
||||||
} else {
|
} 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 =
|
entry =
|
||||||
gst_util_array_binary_search (sidx->entries, sidx->entries_count,
|
gst_util_array_binary_search (sidx->entries, sidx->entries_count,
|
||||||
sizeof (GstSidxBoxEntry),
|
sizeof (GstSidxBoxEntry),
|
||||||
(GCompareDataFunc) gst_dash_demux_index_entry_search,
|
(GCompareDataFunc) gst_dash_demux_index_entry_search, mode, &ts, NULL);
|
||||||
GST_SEARCH_MODE_BEFORE, &ts, NULL);
|
|
||||||
|
|
||||||
idx = entry - sidx->entries;
|
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;
|
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 (gst_mpd_client_has_isoff_ondemand_profile (dashdemux->client)) {
|
||||||
if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
|
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 {
|
} else {
|
||||||
/* no index yet, seek when we have it */
|
/* no index yet, seek when we have it */
|
||||||
/* FIXME - the final_ts won't be correct here */
|
/* 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 (dash_stream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
|
||||||
if (GST_CLOCK_TIME_IS_VALID (dash_stream->pending_seek_ts)) {
|
if (GST_CLOCK_TIME_IS_VALID (dash_stream->pending_seek_ts)) {
|
||||||
/* FIXME, preserve seek flags */
|
/* FIXME, preserve seek flags */
|
||||||
gst_dash_demux_stream_sidx_seek (dash_stream, 0,
|
gst_dash_demux_stream_sidx_seek (dash_stream,
|
||||||
dash_stream->pending_seek_ts, NULL);
|
demux->segment.rate >= 0, 0, dash_stream->pending_seek_ts,
|
||||||
|
NULL);
|
||||||
dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
|
dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
|
||||||
} else {
|
} else {
|
||||||
SIDX (dash_stream)->entry_index = dash_stream->sidx_index;
|
SIDX (dash_stream)->entry_index = dash_stream->sidx_index;
|
||||||
|
@ -4670,18 +4670,48 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
|
|||||||
stream->segments->len);
|
stream->segments->len);
|
||||||
in_segment = FALSE;
|
in_segment = FALSE;
|
||||||
if (segment->start <= ts) {
|
if (segment->start <= ts) {
|
||||||
|
GstClockTime end_time;
|
||||||
|
|
||||||
if (segment->repeat >= 0) {
|
if (segment->repeat >= 0) {
|
||||||
in_segment =
|
end_time = segment->start + (segment->repeat + 1) * segment->duration;
|
||||||
ts < segment->start + (segment->repeat + 1) * segment->duration;
|
|
||||||
} else {
|
} else {
|
||||||
GstClockTime end =
|
end_time =
|
||||||
gst_mpdparser_get_segment_end_time (client, stream->segments,
|
gst_mpdparser_get_segment_end_time (client, stream->segments,
|
||||||
segment, index);
|
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) {
|
if (in_segment) {
|
||||||
selectedChunk = segment;
|
selectedChunk = segment;
|
||||||
repeat_index = (ts - segment->start) / segment->duration;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4714,6 +4744,14 @@ gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream,
|
|||||||
ts = 0;
|
ts = 0;
|
||||||
|
|
||||||
index = ts / duration;
|
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) {
|
if (segments_count > 0 && index >= segments_count) {
|
||||||
stream->segment_index = segments_count;
|
stream->segment_index = segments_count;
|
||||||
stream->segment_repeat_index = 0;
|
stream->segment_repeat_index = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user