For duration queries on live streams, adaptivedemux ignores the query.
The problem then is that the query is answered by the downstream
qtdemux element, with the duration of the currently passing fragment.
This commit changes the behaviour of adaptivedemux to answer the duration
queries for live streams, returning GST_CLOCK_TIME_NONE.
https://bugzilla.gnome.org/show_bug.cgi?id=753879
hls live starts playback from the allowed latest fragment,
but its "sequence position" is set to zero, and so stream
time is also set to zero.
This does not make sense, because hls live allows seeking to past position,
and it's negative stream time from downstream element's point of view.
Note that, allowed seekable range (and seeking query) is
from the first fragment of playlist to the allowed latest fragment.
https://bugzilla.gnome.org/show_bug.cgi?id=777682
HLS spec 6.3.3 is saying that
"the client SHOULD NOT choose a segment which starts less than
three target durations from the end of the Playlist file."
To ensure above statement, the third fragment from the end of playlist
should be excluded from seekable range and also from available starting fragment.
(i.e., the fourth fragment from end of playlist is the starting fragment).
https://bugzilla.gnome.org/show_bug.cgi?id=777682
Without failing, we would play back random parts of the stream which is
arguably a worse user experience, and failing is also recommended by the
spec here.
And also handle live streams without any media sequence numbers at all
properly, that is, make sure the sequence numbers are increasing instead
of starting again at 0 every time.
https://bugzilla.gnome.org/show_bug.cgi?id=775665
After the check in line 1,111, media->uri can't be NULL. So the two checks
for GST_HLS_MEDIA_TYPE_CLOSED_CAPTIONS are the same, removing the redundant
one which goes to cc_unsupported.
CID 1364752
Modify playlist updating to track information across updates
better, although still hackish.
When connection_speed == 0, choose the default variant
not the first one in the (now sorted) variant list, as that
will have the lowest bitrate.
Make M3U8 and GstM3U8MediaFile refcounted. The contents
of it and GstM3U8MediaFile are pretty much immutable
already, but if we make it refcounted we can just
return a ref to the media file from _get_next_fragment()
instead of copying over all fields one-by-one, and then
copying them all into the adaptive stream structure fields again.
Move state from client into m3u8 structure. This will
be useful later when we'll have multiple media playlists
being streamed at the same time, as will be the case with
alternative renditions.
This has the downside that we need to copy over some
state when we switch between variant streams.
The GstM3U8Client structure is gone, and main/current
lists are not directly in hlsdemux. hlsdemux had as
many CLIENT_LOCK/UNLOCK as the m3u8 code anyway...
The URI attribute from the EXT-X-KEY tag and the URI attribute from the
EXT-X-I-FRAMES-ONLY tag are both quoted-string attibutes that have their
quotation marks removed during parsing. The CODECS attribute of the
EXT-X-STREAM-INF is also a quoted-string attribute, but this attribute
was not being un-quoted.
This commit changes the parser to always unquote all quoted-string
attributes and adjusts the unit tests to this new bevahiour for the
CODECS attribute.
An additional test is added to check that parsing of all of the fields
in the EXT-X-STREAM tag is correct, including those that contain comma
characters.
https://bugzilla.gnome.org/show_bug.cgi?id=758384
As HLS does not provide any way of knowing the server's clock, and we do
buffering of "live" streams, at some point we will fall behind the server in
many cases and would have to advance to a fragment that is not in the playlist
anymore.
Previously we would've just resynced to the next oldest fragment that is still
there, but this causes problems as from this point onwards we would always
fall off the playlist again all the time.
Instead we now resync and move to the 3rd newest fragment like we would do
when starting playback of a live stream.
https://bugzilla.gnome.org/show_bug.cgi?id=758987
If a (master) playlist contains a variant list entry without a
URI then during parsing of the next variant list entry we are
a) leaking the entry we're currently parsing (new_list), and
b) free'ing the pointer to the previous list entry (list) without
updating the pointer.
Hence when then adding the URI for the latest parsed entry, incorrect
information is stored, as the information is used from 'list' which
is not valid memory anymore, also leading to crashes.
Fix this by correctly storing the new variant list entry pointer
as needed.
https://bugzilla.gnome.org/show_bug.cgi?id=756861
Nicer to read, two lines of code less, and also the callback
function should've been a GCompareFunc that returns a gint
and not a boolean (it did work correctly, was just confusing).
In order to ensure the sequence_position will always be consistently updated,
store the current file duration.
This way, when we advance, we can always increment the position based on what
was previously outputted.
https://bugzilla.gnome.org/show_bug.cgi?id=752132
Allows playlists that are missing the mediasequence information to
be correctly parsed. If the playlist was updated without reseting
the mediasequence it would constantly increase over subsequent updates,
leading to issues during playback.
Some live streams (eg youtube) don't remove fragments in order to allow
seeking back in time (live + vod).
When gst_m3u8_client_has_next_fragment is called, we are getting wrong fragment
because current_file points in first file of the fragments list resulting in
watching the stream from the beginning again.
This patch sets current_file to nth fragment for live streams, then on
gst_m3u8_client_has_next_fragment will keep up with the live stream.
https://bugzilla.gnome.org/show_bug.cgi?id=753344
This reverts commit 4ca3a22b6b.
The connection-speed=0 is used as a special value in the property
of hlsdemux to mean 'automatic' selection, m3u8.c doesn't need
to know about that as it should be as simple as possible.
So this patch hides this automatic selection documented in hlsdemux
into m3u8 logic and I think the gets harder to understand the code.
It also makes the hlsdemux unit tests work again
https://bugzilla.gnome.org/show_bug.cgi?id=749328
In live situations, it is not uncommon for the current fragment to end
up out of the (updated) play range (lowest/highest sequence). But the next
fragment to play *is* present in the play range.
When advancing, if we can't find the current GstM3U8MediaFile, don't abort
straight away. Instead, look if a GstM3U8MediaFile with the next sequence value
is present, and if so switch to it.
https://bugzilla.gnome.org/show_bug.cgi?id=750028
It's better to just select some random variant playlist instead of stopping,
chances are that it's still continuing to work and we might just have to
select a different variant again later.
Optimize loop by moving condition outside of it and reuse the
find_next_fragment function to check if there is next instead of
replicating the same loop
Duration queries can be done a few times per second and would cause
the segment list to be traversed for every one. Caching the duration
prevents that.
hlsdemux assumes that seeking is not allowed for live streams,
however seek is possible if there are sufficient fragments in the
manifest. For example the BBC have live streams that contain 2 hours
of fragments.
The seek code for both live and on-demand is common code. The
difference between them is that an offset has to be calculated
for the timecode of the first fragment in the live playlist.
When hlsdemux starts to play a live stream, the possible seek range
is between 0 and A seconds. After some time has passed, the beginning of
the stream will no longer be available in the playlist and the seek
range is between B and C seconds.
Seek range:
start 0 ........... A
later B ........... C
This commit adds code to keep a note of the B and C values
and the highest sequence number it has seen. Every time it updates the
media playlist, it walks the list of fragments, seeing if there is a
fragment with sequence number > highest_seen_sequence. If so, the values
of B and C are updated. The value of B is used when timestamping
buffers.
It also makes sure the seek range is never closer than three fragments
from the end of the playlist - see 6.3.3. "Playing the Playlist file"
of the HLS draft.
https://bugzilla.gnome.org/show_bug.cgi?id=725435
In gst_hls_demux_get_next_fragment() the next fragment URI gets
stored in next_fragment_uri, but the gst_hls_demux_updates_loop()
can at any time update the playlist, rendering this string invalid.
Therefore, any data (like key, iv, URIs) that is taken from a
GstM3U8Client needs to be copied. In addition, accessing the
internals of a GstM3U8Client requires locking.
https://bugzilla.gnome.org/show_bug.cgi?id=737793