adaptivedemux: Handle more live seeking use-cases

This commit fixes the following assumptions with live seeking:
1) start was always valid and of type GST_SEEK_TYPE_SET
2) direction was always forward
3) stop should be offsetted when handling non-accurate seeks before
   the range start position.

In order to handle more live seeking use-cases (including reverse playback),
only do non-accurate start/stop value clamping for GST_SEEK_TYPE_SET values.

Also add a bit more debugging lines for issues

https://bugzilla.gnome.org/show_bug.cgi?id=782330
This commit is contained in:
Edward Hervey 2017-05-08 15:34:50 +02:00 committed by Edward Hervey
parent df60e12203
commit ea6e58d27f

View file

@ -1496,21 +1496,31 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
if (format != GST_FORMAT_TIME) { if (format != GST_FORMAT_TIME) {
GST_MANIFEST_UNLOCK (demux); GST_MANIFEST_UNLOCK (demux);
GST_API_UNLOCK (demux); GST_API_UNLOCK (demux);
GST_WARNING_OBJECT (demux,
"Adaptive demuxers only support TIME-based seeking");
gst_event_unref (event); gst_event_unref (event);
return FALSE; return FALSE;
} }
seqnum = gst_event_get_seqnum (event);
if (gst_adaptive_demux_is_live (demux)) { if (gst_adaptive_demux_is_live (demux)) {
gint64 range_start, range_stop; gint64 range_start, range_stop;
gboolean changed = FALSE; gboolean changed = FALSE;
if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start, if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
&range_stop)) { &range_stop)) {
GST_MANIFEST_UNLOCK (demux); GST_MANIFEST_UNLOCK (demux);
GST_API_UNLOCK (demux); GST_API_UNLOCK (demux);
gst_event_unref (event); gst_event_unref (event);
GST_WARNING_OBJECT (demux, "Failure getting the live seek ranges");
return FALSE; return FALSE;
} }
GST_DEBUG_OBJECT (demux,
"Live range is %" GST_STIME_FORMAT " %" GST_STIME_FORMAT,
GST_STIME_ARGS (range_start), GST_STIME_ARGS (range_stop));
/* Handle relative positioning for live streams (relative to the range_stop) */ /* Handle relative positioning for live streams (relative to the range_stop) */
if (start_type == GST_SEEK_TYPE_END) { if (start_type == GST_SEEK_TYPE_END) {
start = range_stop + start; start = range_stop + start;
@ -1528,19 +1538,27 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
* to map to the start for live cases, since those can return a "moving * to map to the start for live cases, since those can return a "moving
* target" based on wall time. * target" based on wall time.
*/ */
if (start < range_start) { if (start_type == GST_SEEK_TYPE_SET && start < range_start) {
guint64 dt = range_start - start;
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Non accurate seek before live stream start, offsetting by %" "Non accurate seek before live stream start, setting to range start: %"
GST_TIME_FORMAT, GST_TIME_ARGS (dt)); GST_TIME_FORMAT, GST_TIME_ARGS (range_start));
start = range_start; start = range_start;
if (stop != GST_CLOCK_TIME_NONE) changed = TRUE;
stop += dt; }
/* truncate stop position also if set */
if (stop_type == GST_SEEK_TYPE_SET && stop > range_stop) {
GST_DEBUG_OBJECT (demux,
"Non accurate seek beyong now, setting to: %"
GST_TIME_FORMAT, GST_TIME_ARGS (range_stop));
stop = range_stop;
changed = TRUE; changed = TRUE;
} }
} }
if (start < range_start || start > range_stop) { /* If the seek position is still outside of the seekable range, refuse the seek */
if (((start_type == GST_SEEK_TYPE_SET) && (start < range_start
|| start > range_stop)) || ((stop_type == GST_SEEK_TYPE_SET)
&& (stop < range_start || stop > range_stop))) {
GST_MANIFEST_UNLOCK (demux); GST_MANIFEST_UNLOCK (demux);
GST_API_UNLOCK (demux); GST_API_UNLOCK (demux);
GST_WARNING_OBJECT (demux, "Seek to invalid position"); GST_WARNING_OBJECT (demux, "Seek to invalid position");
@ -1548,17 +1566,16 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
return FALSE; return FALSE;
} }
/* Re-create seek event with changed/updated values */
if (changed) { if (changed) {
gst_event_unref (event); gst_event_unref (event);
event = event =
gst_event_new_seek (rate, format, flags, gst_event_new_seek (rate, format, flags,
start_type, start, stop_type, stop); start_type, start, stop_type, stop);
gst_event_set_seqnum (event, seqnum);
} }
} }
seqnum = gst_event_get_seqnum (event);
GST_DEBUG_OBJECT (demux, "seek event, %" GST_PTR_FORMAT, event); GST_DEBUG_OBJECT (demux, "seek event, %" GST_PTR_FORMAT, event);
/* have a backup in case seek fails */ /* have a backup in case seek fails */