The live playlists should be updated at a defined interval. The problem is that
this interval was used *after* the playlist was finally received and processed,
which resulted in a gradual shift happening in playlist updates.
Instead store and use the time at which playlists were requested to determine
when the next one should be downloaded.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
The scanning is done in a reverse order, the proper full checks to do are
therefore:
* If the position is beyond half a "segment duration", it's in the following
segment
* If the position is within the first half of a segment, it's in that one
* If the segment is the first one and the position is within half a duration
backwards, we consider the position as being within that first segment
Also handle the case where a "partial only" segment doesn't have a reliable
duration, and therefore use the playlist target duration instead.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
The implementation wouldn't work with regular HLS streams (i.e. the final
fallback).
Now that the implementation uses time to search for the starting
segment (instead of just the n-th from the end), we can specify the correct
hold_back fallback value from the RFC
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Avoid a deadlock if a downstream seeking query happens while the scheduler
thread is holding the manifest lock (for example during a seek back to live).
Instead, do a more elaborate fix where the external calls that need access to a
'manifest' access a copy that's updated during a manually triggered manifest
update callback.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Rename track_dequeue_data_locked() to
gst_adaptive_demux_track_dequeue_data_locked(), since it's non-static.
Make find_stream_for_track_locked() static since it's only used in the main
gstadaptivedemux.c file.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
gst_adaptive_demux2_stream_finish_download() will already schedule another
fragment download if it can so don't fall through to the retry code that will
also try and schedule a download (triggering an assert).
Fix the logic in general to retry advancing into the live seek range once.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When calculating the seek range for a live stream, use the same hold-back logic
as when choosing a starting segment, including low-latency segments if
enabled. Permits seeking closer to the live edge when re-synching or catching
up.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing at the live edge of a live playlist, and a download fails, we don't
expect there to be a next fragment. That case is handled lower down anyway, so
don't retry infinitely on spurious http errors at the live edge.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
gst_hls_demux_stream_has_next_fragment() can be called with a NULL
current_segment if we're past the end of the current playlist. In that case,
just return FALSE instead of hitting a critical in the playlist code.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing LL-HLS playlists in LL-HLS mode, update the playlist more often (on
the partial segment interval) or else we end up downloading them in bursts and
playing further from the live edge than intended.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
When playing a live stream, make the recommended buffering threshold at most the
hold-back distance from live. If we start 3 seconds from the live edge, there's
no point trying to buffer more - we'll just hit the live edge and have to wait
for more data to be available anyway.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a field to the DownloadRequest that reports the most recent time at which
data arrived. Update it in the DownloadHelper.
Add a method to retrieve the GST_BUFFER_OFFSET() for the DownloadRequest's data
buffer (if any).
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
After cancelling a DownloadRequest, the download helper may not do so
immediately, so we can't assert on the in_use flag. Also, since there's no
refcount on the preload hint struct in the download request callback data, make
sure no callbacks will be dispatched when we're going to free the preload hint
struct.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Implement fulfilment of HTTP requests from the active preload downloads by
finding any preload request that can provide the requested data and feeding
bytes from the internal DownloadRequest to the caller provided target
DownloadRequest.
Doesn't yet calculate timestamps to make the target request have a sensible
apparent bitrate.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add download_request_take_buffer_range() and
download_request_get_bytes_available() methods.
download_request_take_buffer_range() takes bytes from the front of the request
that satisfy the requested start/end byterange, and puts any remaining bytes
back into the DownloadRequest
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a helper that submits and handles blocking preload requests for future
PART/MAP data from live playlists. Add handling in the hlsdemux stream to submit
preload requests when hitting the end of the available segments in a live
playlist.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a flag to hlsdemux to enable or disable LL-HLS handling.
When LL-HLS is enabled and an LL-HLS playlist is loaded, use the part-hold-back
threshold to choose a starting segment.
For live streams that aren't LL-HLS, use the provided hold-back attribute, or
fall back to landing 3 segments from the end.
Make the gst_hls_media_playlist_seek() method able to choose a partial segment
within 2 target durations of the end of the playlist when requested.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Fix an off-by-one in gst_hls_media_playlist_sync_to_playlist() that would ignore
the first fragment in the reference playlist. The error was harmless, since we
expect the reference playlist to be older than the playlist we're
synchronising (so the first/oldest segment in the reference playlist will likely
not exist in the new playlist), so this is just for correctness.
Also fix a segment leak in gst_hls_media_playlist_advance_fragment() when
ignoring the partial_only segment.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Add a function for synchronising current position with the contents of a
playlist that is specifically for that and can handle synchronising to a partial
segment.
gst_hls_media_playlist_seek() will be used only when performing external seek
requests, to find the best segment or partial segment at which to resume
playback.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
Fixes for stream_time recalculation and handling in partial segments.
Disallow bitrate switching when in the middle of partial segments - only at a
full segment (or right before the first partial segment of a segment).
It's possible but more difficult to switch bitrates in the middle of a partial
segment group, since they are less likely to have aligned keyframes. In any
case, the seek code can't do that right now.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
All the RTP src pads were sharing the same stream-id while each actually
carry a different stream.
This was causing problem for example when funneling the streams together
and then trying to split them using 'streamiddemux'.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3855>
In theory, `dispose()` functions should be idempotent and should be
prepared not to crash or cause a double-free if an unref done from
inside caused a recursive call to `dispose()` of the same object.
https://developer.gnome.org/gobject/stable/howto-gobject-destruction.html
This patch modifies the `dispose()` method to honor these constraints.
Since the double `dispose()` call won't actually occur in qtdemux (there
is no cycle detection mechanism that could invoke it to work that way),
this is more of a code cleanup than a user-facing problem fix.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3822>
Without this, the plugin cannot be loaded in a devenv because the
RPATH is not added to the plugin dylib. This RPATH will be stripped on
install, which is what we want.
When deploying apps, people are supposed to use `macdeployqt` to
create an AppBundle that bundles Qt for you and sets the RPATHs
correctly to point to that bundled Qt.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3708>