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
This can happen if the playlists have moved due to the variant playlist
now being redirected to another target. This currently only works as long
as the referenced playlists don't change in relation to the variant
playlist, and the new location is purely due to a new path triggered by a
new redirection target of the variant playlist, or a new redirection
target of the playlist itself.
https://bugzilla.gnome.org/show_bug.cgi?id=731164
data does not have to be freed at all here, it's a pointer to
an arbitrary position inside the current line. Also don't reuse
the data variable for anything else, that will cause crashes
in playlists that have the I-frame playlist URI followed by
other attributes.
CID 1212127
hlsdemux causes a null pointer dereference if the media playlist
does not contain any media files. The gst_m3u8_client_get_duration
function assumes that demux->client->current->files is valid when
computing duration.
gst_m3u8_client_update needed to be modified to check for the
case of downloading an M3U8 file that doesn't contain any media
files, and returning an error to gsthlsdemux.c
This bug can be reproduced by creating a master m3u8 file that
contains one media playlist that points back to the master m3u8
file. For example create a file called bug725134.m3u8:
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-STREAM-INF:PROGRAM-ID=1, BANDWIDTH=1251135, CODECS="avc1.42001f mp4a.40.2", RESOLUTION=640x352
bug725134.m3u8
https://bugzilla.gnome.org/show_bug.cgi?id=725134
hlsdemux does not check for the '"' character in #EXT-X-STREAM-INF
attributes. The CODECS parameter is an example of an attribute
that might use the '"' symbol and might contain a ',' character
inside this quoted string.
For example: CODECS="avc1.77.30, mp4a.40.2"
hlsdemux does not correctly parse the RESOLUTION attribute, it
assumes that an '=' character is used to delineate the width
and height values, but the HLS RFC states that a 'x' character
must be used as the delimiter between width and height.
https://bugzilla.gnome.org/show_bug.cgi?id=725140
...instead of adding them from the start of playlist every time. This
among other things fixes timestamps for live streams, where the playlist
is some kind of ringbuffer of fragments and thus adding from the beginning
of the playlist will miss the past fragments.
https://bugzilla.gnome.org/show_bug.cgi?id=724983
We now download fragments as fast as possible and push them downstream
while another thread is just responsible for updating live playlists
every now and then.
This simplifies the code a lot and together with the new buffering
mode for adaptive streams in multiqueue makes streams start much faster.
Also simplify threading a bit and hopefully make the GstTask usage safer.