mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
hlsdemux: Early terminate seeking if we don't need to do
Some codes are imported from dashdemux https://bugzilla.gnome.org/show_bug.cgi?id=776997
This commit is contained in:
parent
9ce5646a0f
commit
32c4850b33
1 changed files with 64 additions and 62 deletions
|
@ -294,13 +294,17 @@ gst_hls_demux_set_current (GstHLSDemux * self, GstM3U8 * m3u8)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SEEK_UPDATES_PLAY_POSITION(r, start_type, stop_type) \
|
||||||
|
((r >= 0 && start_type != GST_SEEK_TYPE_NONE) || \
|
||||||
|
(r < 0 && stop_type != GST_SEEK_TYPE_NONE))
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
{
|
{
|
||||||
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
GstSeekFlags flags;
|
GstSeekFlags flags;
|
||||||
GstSeekType start_type, stop_type, target_type;
|
GstSeekType start_type, stop_type;
|
||||||
gint64 start, stop;
|
gint64 start, stop;
|
||||||
gdouble rate, old_rate;
|
gdouble rate, old_rate;
|
||||||
GList *walk, *stream_walk;
|
GList *walk, *stream_walk;
|
||||||
|
@ -310,11 +314,16 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
gboolean snap_before, snap_after, snap_nearest, keyunit;
|
gboolean snap_before, snap_after, snap_nearest, keyunit;
|
||||||
gboolean reverse;
|
gboolean reverse;
|
||||||
|
|
||||||
old_rate = demux->segment.rate;
|
|
||||||
|
|
||||||
gst_event_parse_seek (seek, &rate, &format, &flags, &start_type, &start,
|
gst_event_parse_seek (seek, &rate, &format, &flags, &start_type, &start,
|
||||||
&stop_type, &stop);
|
&stop_type, &stop);
|
||||||
|
|
||||||
|
if (!SEEK_UPDATES_PLAY_POSITION (rate, start_type, stop_type)) {
|
||||||
|
/* nothing to do if we don't have to update the current position */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
old_rate = demux->segment.rate;
|
||||||
|
|
||||||
bitrate = gst_hls_demux_get_bitrate (hlsdemux);
|
bitrate = gst_hls_demux_get_bitrate (hlsdemux);
|
||||||
|
|
||||||
/* properly cleanup pending decryption status */
|
/* properly cleanup pending decryption status */
|
||||||
|
@ -364,73 +373,66 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
|
||||||
hls_stream->playlist->first_file_start : 0;
|
hls_stream->playlist->first_file_start : 0;
|
||||||
reverse = rate < 0;
|
reverse = rate < 0;
|
||||||
target_pos = reverse ? stop : start;
|
target_pos = reverse ? stop : start;
|
||||||
target_type = reverse ? stop_type : start_type;
|
|
||||||
|
|
||||||
if (target_type == GST_SEEK_TYPE_NONE && !(flags & GST_SEEK_FLAG_FLUSH)) {
|
/* Snap to segment boundary. Improves seek performance on slow machines. */
|
||||||
/* No need to move */
|
keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
|
||||||
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
snap_nearest =
|
||||||
start, stop_type, stop, NULL);
|
(flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
|
||||||
} else {
|
snap_before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
|
||||||
/* Snap to segment boundary. Improves seek performance on slow machines. */
|
snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
|
||||||
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);
|
GST_M3U8_CLIENT_LOCK (hlsdemux->client);
|
||||||
/* FIXME: Here we need proper discont handling */
|
/* FIXME: Here we need proper discont handling */
|
||||||
for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
|
for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
|
||||||
file = walk->data;
|
file = walk->data;
|
||||||
|
|
||||||
current_sequence = file->sequence;
|
current_sequence = file->sequence;
|
||||||
if ((!reverse && snap_after) || snap_nearest) {
|
if ((!reverse && snap_after) || snap_nearest) {
|
||||||
if (current_pos >= target_pos)
|
if (current_pos >= target_pos)
|
||||||
break;
|
break;
|
||||||
if (snap_nearest && target_pos - current_pos < file->duration / 2)
|
if (snap_nearest && target_pos - current_pos < file->duration / 2)
|
||||||
break;
|
break;
|
||||||
} else if (reverse && snap_after) {
|
} else if (reverse && snap_after) {
|
||||||
/* check if the next fragment is our target, in this case we want to
|
/* check if the next fragment is our target, in this case we want to
|
||||||
* start from the previous fragment */
|
* start from the previous fragment */
|
||||||
GstClockTime next_pos = current_pos + file->duration;
|
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;
|
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;
|
current_pos += file->duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walk == NULL) {
|
if (keyunit || snap_before || snap_after || snap_nearest) {
|
||||||
GST_DEBUG_OBJECT (demux, "seeking further than track duration");
|
if (!reverse)
|
||||||
current_sequence++;
|
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||||
}
|
current_pos, stop_type, stop, NULL);
|
||||||
|
else
|
||||||
GST_DEBUG_OBJECT (demux, "seeking to sequence %u",
|
gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
|
||||||
(guint) current_sequence);
|
start, stop_type, current_pos, NULL);
|
||||||
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