mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
hlsdemux2: Resync stream time on partial segment boundaries
When resyncing stream times in a playlist, support at any partial segment position, not just at full segment boundaries. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
parent
bdec75f9dc
commit
1e6550f623
3 changed files with 63 additions and 12 deletions
|
@ -1383,23 +1383,41 @@ gst_hlsdemux_handle_internal_time (GstHLSDemux * demux,
|
||||||
GST_STIME_ARGS (real_stream_time), GST_STIME_ARGS (difference));
|
GST_STIME_ARGS (real_stream_time), GST_STIME_ARGS (difference));
|
||||||
|
|
||||||
if (ABS (difference) > 10 * GST_MSECOND) {
|
if (ABS (difference) > 10 * GST_MSECOND) {
|
||||||
/* FIXME: LL-HLS could recalculate stream times on parts.
|
GstClockTimeDiff wrong_position_threshold =
|
||||||
* For now, only do it at the first part in a segment */
|
hls_stream->current_segment->duration / 2;
|
||||||
if (!hls_stream->in_partial_segments || hls_stream->part_idx == 0) {
|
|
||||||
/* Update the value */
|
|
||||||
GST_DEBUG_OBJECT (hls_stream,
|
|
||||||
"Updating current stream time to %" GST_STIME_FORMAT,
|
|
||||||
GST_STIME_ARGS (real_stream_time));
|
|
||||||
current_segment->stream_time = real_stream_time;
|
|
||||||
|
|
||||||
|
/* Update the value */
|
||||||
|
GST_DEBUG_OBJECT (hls_stream,
|
||||||
|
"Updating current stream time to %" GST_STIME_FORMAT,
|
||||||
|
GST_STIME_ARGS (real_stream_time));
|
||||||
|
|
||||||
|
/* For LL-HLS, make sure to update and recalculate stream time from
|
||||||
|
* the right partial segment if playing one */
|
||||||
|
if (hls_stream->in_partial_segments && hls_stream->part_idx != 0) {
|
||||||
|
if (current_segment->partial_segments
|
||||||
|
&& hls_stream->part_idx < current_segment->partial_segments->len) {
|
||||||
|
GstM3U8PartialSegment *part =
|
||||||
|
g_ptr_array_index (current_segment->partial_segments,
|
||||||
|
hls_stream->part_idx);
|
||||||
|
part->stream_time = real_stream_time;
|
||||||
|
|
||||||
|
gst_hls_media_playlist_recalculate_stream_time_from_part
|
||||||
|
(hls_stream->playlist, hls_stream->current_segment,
|
||||||
|
hls_stream->part_idx);
|
||||||
|
|
||||||
|
/* When playing partial segments, the "Wrong position" threshold should be
|
||||||
|
* half the part duration */
|
||||||
|
wrong_position_threshold = part->duration / 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Aligned to the start of the segment, update there */
|
||||||
|
current_segment->stream_time = real_stream_time;
|
||||||
gst_hls_media_playlist_recalculate_stream_time (hls_stream->playlist,
|
gst_hls_media_playlist_recalculate_stream_time (hls_stream->playlist,
|
||||||
hls_stream->current_segment);
|
hls_stream->current_segment);
|
||||||
gst_hls_media_playlist_dump (hls_stream->playlist);
|
|
||||||
}
|
}
|
||||||
|
gst_hls_media_playlist_dump (hls_stream->playlist);
|
||||||
|
|
||||||
/* FIXME: When playing partial segments, the threshold should be
|
if (ABS (difference) > wrong_position_threshold) {
|
||||||
* half the part duration */
|
|
||||||
if (ABS (difference) > (hls_stream->current_segment->duration / 2)) {
|
|
||||||
GstAdaptiveDemux2Stream *stream = (GstAdaptiveDemux2Stream *) hls_stream;
|
GstAdaptiveDemux2Stream *stream = (GstAdaptiveDemux2Stream *) hls_stream;
|
||||||
GstM3U8SeekResult seek_result;
|
GstM3U8SeekResult seek_result;
|
||||||
|
|
||||||
|
|
|
@ -1667,6 +1667,35 @@ gst_hls_media_playlist_recalculate_stream_time (GstHLSMediaPlaylist * playlist,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_hls_media_playlist_recalculate_stream_time_from_part (GstHLSMediaPlaylist *
|
||||||
|
playlist, GstM3U8MediaSegment * anchor, guint part_idx)
|
||||||
|
{
|
||||||
|
g_assert (anchor->partial_segments != NULL
|
||||||
|
&& part_idx < anchor->partial_segments->len);
|
||||||
|
|
||||||
|
GstClockTimeDiff last_stream_time;
|
||||||
|
GstM3U8PartialSegment *part =
|
||||||
|
g_ptr_array_index (anchor->partial_segments, part_idx);
|
||||||
|
GstM3U8PartialSegment *cand, *prev;
|
||||||
|
gint iter;
|
||||||
|
|
||||||
|
/* Work backward from the target partial segment, assigning stream times until
|
||||||
|
* we update the segment time itself, then recalculate all stream times */
|
||||||
|
prev = part;
|
||||||
|
last_stream_time = part->stream_time;
|
||||||
|
for (iter = part_idx - 1; iter >= 0; iter--) {
|
||||||
|
cand = g_ptr_array_index (anchor->partial_segments, iter);
|
||||||
|
last_stream_time = cand->stream_time = prev->stream_time - cand->duration;
|
||||||
|
GST_DEBUG ("Backward partial segment iter %d %" GST_STIME_FORMAT, iter,
|
||||||
|
GST_STIME_ARGS (cand->stream_time));
|
||||||
|
prev = cand;
|
||||||
|
}
|
||||||
|
anchor->stream_time = last_stream_time;
|
||||||
|
|
||||||
|
gst_hls_media_playlist_recalculate_stream_time (playlist, anchor);
|
||||||
|
}
|
||||||
|
|
||||||
/* If a segment with the same URI, size, offset, SN and DSN is present in the
|
/* If a segment with the same URI, size, offset, SN and DSN is present in the
|
||||||
* playlist, returns that one */
|
* playlist, returns that one */
|
||||||
static GstM3U8MediaSegment *
|
static GstM3U8MediaSegment *
|
||||||
|
|
|
@ -279,6 +279,10 @@ void
|
||||||
gst_hls_media_playlist_recalculate_stream_time (GstHLSMediaPlaylist *playlist,
|
gst_hls_media_playlist_recalculate_stream_time (GstHLSMediaPlaylist *playlist,
|
||||||
GstM3U8MediaSegment *anchor);
|
GstM3U8MediaSegment *anchor);
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_hls_media_playlist_recalculate_stream_time_from_part (GstHLSMediaPlaylist *playlist,
|
||||||
|
GstM3U8MediaSegment *anchor, guint part_idx);
|
||||||
|
|
||||||
GstM3U8MediaSegment *
|
GstM3U8MediaSegment *
|
||||||
gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * m3u8,
|
gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * m3u8,
|
||||||
GstM3U8MediaSegment * segment);
|
GstM3U8MediaSegment * segment);
|
||||||
|
|
Loading…
Reference in a new issue