mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-17 21:06:17 +00:00
hlsdemux: Handle GST_SEEK_TYPE_NONE seek
When one is only updating the "stop" position (i.e. non-flushing seek, with GST_SEEK_TYPE_NONE on the "start" (or stop in reverse) position), we only need to store those values instead of moving the current position. https://bugzilla.gnome.org/show_bug.cgi?id=775127
This commit is contained in:
parent
9b89f58cae
commit
9053a01e72
1 changed files with 61 additions and 53 deletions
|
@ -296,7 +296,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
|||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||
GstFormat format;
|
||||
GstSeekFlags flags;
|
||||
GstSeekType start_type, stop_type;
|
||||
GstSeekType start_type, stop_type, target_type;
|
||||
gint64 start, stop;
|
||||
gdouble rate, old_rate;
|
||||
GList *walk, *stream_walk;
|
||||
|
@ -348,6 +348,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
|||
/* TODO why not continue using the same? that was being used up to now? */
|
||||
gst_hls_demux_change_playlist (hlsdemux, bitrate, NULL);
|
||||
}
|
||||
|
||||
for (stream_walk = demux->streams; stream_walk != NULL;
|
||||
stream_walk = stream_walk->next) {
|
||||
GstHLSDemuxStream *hls_stream =
|
||||
|
@ -358,66 +359,73 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
|||
current_pos = 0;
|
||||
reverse = rate < 0;
|
||||
target_pos = reverse ? stop : start;
|
||||
target_type = reverse ? stop_type : start_type;
|
||||
|
||||
/* Snap to segment boundary. Improves seek performance on slow machines. */
|
||||
keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
|
||||
snap_nearest =
|
||||
(flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
|
||||
snap_before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
|
||||
snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
|
||||
if (target_type == GST_SEEK_TYPE_NONE && !(flags & GST_SEEK_FLAG_FLUSH)) {
|
||||
/* No need to move */
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||
start, stop_type, stop, NULL);
|
||||
} else {
|
||||
/* Snap to segment boundary. Improves seek performance on slow machines. */
|
||||
keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
|
||||
snap_nearest =
|
||||
(flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
|
||||
snap_before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
|
||||
snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
|
||||
|
||||
GST_M3U8_CLIENT_LOCK (hlsdemux->client);
|
||||
/* FIXME: Here we need proper discont handling */
|
||||
for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
|
||||
file = walk->data;
|
||||
GST_M3U8_CLIENT_LOCK (hlsdemux->client);
|
||||
/* FIXME: Here we need proper discont handling */
|
||||
for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
|
||||
file = walk->data;
|
||||
|
||||
current_sequence = file->sequence;
|
||||
if ((!reverse && snap_after) || snap_nearest) {
|
||||
if (current_pos >= target_pos)
|
||||
break;
|
||||
if (snap_nearest && target_pos - current_pos < file->duration / 2)
|
||||
break;
|
||||
} else if (reverse && snap_after) {
|
||||
/* check if the next fragment is our target, in this case we want to
|
||||
* start from the previous fragment */
|
||||
GstClockTime next_pos = current_pos + file->duration;
|
||||
current_sequence = file->sequence;
|
||||
if ((!reverse && snap_after) || snap_nearest) {
|
||||
if (current_pos >= target_pos)
|
||||
break;
|
||||
if (snap_nearest && target_pos - current_pos < file->duration / 2)
|
||||
break;
|
||||
} else if (reverse && snap_after) {
|
||||
/* check if the next fragment is our target, in this case we want to
|
||||
* start from the previous fragment */
|
||||
GstClockTime next_pos = current_pos + file->duration;
|
||||
|
||||
if (next_pos <= target_pos && target_pos < next_pos + file->duration) {
|
||||
if (next_pos <= target_pos && target_pos < next_pos + file->duration) {
|
||||
break;
|
||||
}
|
||||
} else if (current_pos <= target_pos
|
||||
&& target_pos < current_pos + file->duration) {
|
||||
break;
|
||||
}
|
||||
} else if (current_pos <= target_pos
|
||||
&& target_pos < current_pos + file->duration) {
|
||||
break;
|
||||
}
|
||||
current_pos += file->duration;
|
||||
}
|
||||
|
||||
if (walk == NULL) {
|
||||
GST_DEBUG_OBJECT (demux, "seeking further than track duration");
|
||||
current_sequence++;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "seeking to sequence %u",
|
||||
(guint) current_sequence);
|
||||
hls_stream->reset_pts = TRUE;
|
||||
hls_stream->playlist->sequence = current_sequence;
|
||||
hls_stream->playlist->current_file = walk;
|
||||
hls_stream->playlist->sequence_position = current_pos;
|
||||
GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
|
||||
|
||||
/* Play from the end of the current selected segment */
|
||||
if (file) {
|
||||
if (reverse && (snap_before || snap_after || snap_nearest))
|
||||
current_pos += file->duration;
|
||||
}
|
||||
}
|
||||
|
||||
if (keyunit || snap_before || snap_after || snap_nearest) {
|
||||
if (!reverse)
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||
current_pos, stop_type, stop, NULL);
|
||||
else
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||
start, stop_type, current_pos, NULL);
|
||||
if (walk == NULL) {
|
||||
GST_DEBUG_OBJECT (demux, "seeking further than track duration");
|
||||
current_sequence++;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (demux, "seeking to sequence %u",
|
||||
(guint) current_sequence);
|
||||
hls_stream->reset_pts = TRUE;
|
||||
hls_stream->playlist->sequence = current_sequence;
|
||||
hls_stream->playlist->current_file = walk;
|
||||
hls_stream->playlist->sequence_position = current_pos;
|
||||
GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
|
||||
|
||||
/* Play from the end of the current selected segment */
|
||||
if (file) {
|
||||
if (reverse && (snap_before || snap_after || snap_nearest))
|
||||
current_pos += file->duration;
|
||||
}
|
||||
|
||||
if (keyunit || snap_before || snap_after || snap_nearest) {
|
||||
if (!reverse)
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||
current_pos, stop_type, stop, NULL);
|
||||
else
|
||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||
start, stop_type, current_pos, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue