This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 848fb754dd8ac26e1fa42a94d1034af3eabcea0d Author: Kacper Michajłow <[email protected]> AuthorDate: Wed Jul 8 03:56:24 2026 +0200 Commit: Kacper Michajłow <[email protected]> CommitDate: Tue Jul 28 18:01:18 2026 +0200 avformat/hls: don't discard target segment's first keyframe when seeking Segment starts on the seek timeline are derived from EXTINF durations, so the first keyframe of the target segment can have a slightly lower DTS than the snapped seek position, in which case the packet discard loop would skip it and resume playback one segment late. Make sure we start at the very beginning of the stream in this case. Signed-off-by: Kacper Michajłow <[email protected]> --- libavformat/hls.c | 11 +++++++++++ tests/ref/seek/hls | 18 +++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index ed6fe7ef5b..569bc889e8 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2909,6 +2909,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, int stream_subdemuxer_index; int64_t first_timestamp, seek_timestamp, duration; int64_t seq_no, seg_start_ts; + int snapped_to_segment = 0; if ((flags & AVSEEK_FLAG_BYTE) || (c->ctx->ctx_flags & AVFMTCTX_UNSEEKABLE)) return AVERROR(ENOSYS); @@ -2952,6 +2953,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, /* Seeking to start of segment ensures we seek to a keyframe located * before the given timestamp. */ seek_timestamp = seg_start_ts; + snapped_to_segment = 1; } av_log(s, AV_LOG_DEBUG, "Seek to %"PRId64" mapped to segment %"PRId64 @@ -3005,6 +3007,15 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, pls->seek_timestamp = seek_timestamp; pls->seek_flags = flags; + if (pls == seek_pls && snapped_to_segment) { + /* The first keyframe of the target segment may have a slightly + * lower DTS than the EXTINF-derived seg_start_ts. Relax the cutoff + * to not discard the keyframe and land one segment late. */ + int64_t idx = seq_no - pls->start_seq_no; + if (idx >= 0 && idx < pls->n_segments) + pls->seek_timestamp -= pls->segments[idx]->duration; + } + if (pls != seek_pls) { /* set closest segment seq_no for playlists not handled above */ find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no, NULL); diff --git a/tests/ref/seek/hls b/tests/ref/seek/hls index a9b3badaf8..7f3025ef70 100644 --- a/tests/ref/seek/hls +++ b/tests/ref/seek/hls @@ -2,7 +2,7 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:0 ts:-1.000000 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:1 ts:-0.105833 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:0 ts: 0.788333 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:1 ts: 1.682500 @@ -10,11 +10,11 @@ ret: 0 st: 0 flags:1 dts: 1.698078 pts: 1.698078 pos: 11092 size: 1253 ret: 0 st: 1 flags:0 ts: 2.576667 ret: 0 st: 0 flags:1 dts: 2.586233 pts: 2.586233 pos: 55836 size: 1254 ret: 0 st: 1 flags:1 ts: 3.470833 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:0 ts: 4.365002 ret: 0 st: 0 flags:1 dts: 4.388689 pts: 4.388689 pos: 45308 size: 1254 ret: 0 st:-1 flags:1 ts:-0.740831 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:0 ts: 0.153333 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:1 ts: 1.047500 @@ -22,11 +22,11 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 1 flags:0 ts: 1.941667 ret: 0 st: 0 flags:1 dts: 1.959300 pts: 1.959300 pos: 24252 size: 1254 ret: 0 st: 1 flags:1 ts: 2.835833 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:0 ts: 3.730004 ret: 0 st: 0 flags:1 dts: 3.735622 pts: 3.735622 pos: -1 size: 1254 ret: 0 st:-1 flags:1 ts: 4.624171 -ret: 0 st: 0 flags:1 dts: 4.493178 pts: 4.493178 pos: 50572 size: 1254 +ret: 0 st: 1 flags:1 dts: 4.200000 pts: 4.500000 pos: 564 size: 5196 ret: 0 st: 0 flags:0 ts:-0.481667 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:1 ts: 0.412500 @@ -34,11 +34,11 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 1 flags:0 ts: 1.306667 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 1 flags:1 ts: 2.200844 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:0 ts: 3.095006 ret: 0 st: 0 flags:1 dts: 3.108689 pts: 3.108689 pos: 82156 size: 1254 ret: 0 st:-1 flags:1 ts: 3.989173 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 0 flags:0 ts: 4.883344 ret: 0 st: 0 flags:1 dts: 4.885011 pts: 4.885011 pos: -1 size: 1253 ret: 0 st: 0 flags:1 ts:-0.222489 @@ -46,8 +46,8 @@ ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 1 flags:0 ts: 0.671678 ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st: 1 flags:1 ts: 1.565844 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 ret: 0 st:-1 flags:0 ts: 2.460008 ret: 0 st: 0 flags:1 dts: 2.481744 pts: 2.481744 pos: 50572 size: 1254 ret: 0 st:-1 flags:1 ts: 3.354175 -ret: 0 st: 0 flags:1 dts: 1.515211 pts: 1.515211 pos: -1 size: 1254 +ret: 0 st: 1 flags:1 dts: 1.400000 pts: 1.500000 pos: 564 size: 3913 _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
