summaryrefslogtreecommitdiff
path: root/ext/hls
diff options
context:
space:
mode:
authorSeungha Yang <sh.yang@lge.com>2017-02-01 17:44:25 +0900
committerSebastian Dröge <sebastian@centricular.com>2017-03-02 19:25:48 +0200
commit32c4850b33c19fa6e67f8336a0cfb2905cb49bbc (patch)
treedac5b93fb4aef784a60ea2064a6938bcf92c82ce /ext/hls
parent9ce5646a0fe786d42c3cbb26e5a1dab43dec7c12 (diff)
downloadgstreamer-plugins-bad-32c4850b33c19fa6e67f8336a0cfb2905cb49bbc.tar.gz
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
Diffstat (limited to 'ext/hls')
-rw-r--r--ext/hls/gsthlsdemux.c128
1 files changed, 65 insertions, 63 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c
index 861140234..1c19b4e86 100644
--- a/ext/hls/gsthlsdemux.c
+++ b/ext/hls/gsthlsdemux.c
@@ -294,13 +294,17 @@ gst_hls_demux_set_current (GstHLSDemux * self, GstM3U8 * m3u8)
}
#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
gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
{
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
GstFormat format;
GstSeekFlags flags;
- GstSeekType start_type, stop_type, target_type;
+ GstSeekType start_type, stop_type;
gint64 start, stop;
gdouble rate, old_rate;
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 reverse;
- old_rate = demux->segment.rate;
-
gst_event_parse_seek (seek, &rate, &format, &flags, &start_type, &start,
&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);
/* properly cleanup pending decryption status */
@@ -364,73 +373,66 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
hls_stream->playlist->first_file_start : 0;
reverse = rate < 0;
target_pos = reverse ? stop : start;
- target_type = reverse ? stop_type : start_type;
- 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;
-
- 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) {
- break;
- }
- } else if (current_pos <= target_pos
- && target_pos < current_pos + file->duration) {
+ /* 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;
+
+ 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) {
break;
}
- current_pos += file->duration;
+ } 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++;
- }
+ 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;
- }
+ 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);
- 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);
- }
+ /* 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);
}
}