This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 8191fa0b8c05da7919f5ffecf631a7aa669b9203 Author: Romain Beauxis <[email protected]> AuthorDate: Sat Oct 17 06:32:53 2026 +0200 Commit: Romain Beauxis <[email protected]> CommitDate: Thu Oct 22 02:51:14 2026 +0000 avformat/hls: accept EXT-X-START in Master Playlists EXT-X-START may appear in both Master and Media Playlists (RFC 8216 4.3.5.2). Parsing it allocated a Media Playlist, so a Master Playlist carrying it before its EXT-X-STREAM-INF entries was rejected since 0e6eef3551. Record the offset while parsing and apply it once the playlist type is known. A value from a Master Playlist applies to all its Media Playlists, which then ignore their own, as RFC 8216 4.3.5 recommends. Defer EXT-X-ENDLIST the same way, so that it is not lost when it precedes the first tag allocating the Media Playlist. --- libavformat/hls.c | 36 ++++++++++++++++++++------ tests/ref/fate/hls-parse-master-start | 4 ++- tests/ref/fate/hls-parse-master-start-media | 4 ++- tests/ref/fate/hls-parse-master-start-override | 4 ++- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 519d3d852f..c68b5e88cf 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -264,6 +264,7 @@ typedef struct HLSContext { int m3u8_hold_counters; int live_start_index; int prefer_x_start; + int master_time_offset_flag; ///< EXT-X-START was set by the Master Playlist int first_packet; int64_t first_timestamp; struct playlist *first_timestamp_pls; @@ -979,6 +980,9 @@ static int parse_playlist(HLSContext *c, const char *url, int prev_n_segments = 0; int64_t prev_start_seq_no = -1; int64_t load_start = av_gettime_relative(); + int64_t start_time_offset = 0; + int time_offset_flag = 0; + int finished = 0; if (is_http && !in && c->http_persistent && c->playlist_pb) { in = c->playlist_pb; @@ -1139,15 +1143,11 @@ static int parse_playlist(HLSContext *c, const char *url, } else if (av_strstart(line, "#EXT-X-START:", &ptr)) { const char *time_offset_value = NULL; - ret = ensure_playlist(c, &pls, url); - if (ret < 0) { - goto fail; - } if (av_strstart(ptr, "TIME-OFFSET=", &time_offset_value)) { double offset = strtod(time_offset_value, NULL) * AV_TIME_BASE; if (offset >= -0x1p63 && offset < 0x1p63) { - pls->start_time_offset = offset; - pls->time_offset_flag = 1; + start_time_offset = offset; + time_offset_flag = 1; } else { av_log(c->ctx, AV_LOG_WARNING, "TIME-OFFSET value is" "invalid, it will be ignored"); @@ -1158,8 +1158,7 @@ static int parse_playlist(HLSContext *c, const char *url, continue; } } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { - if (pls) - pls->finished = 1; + finished = 1; } else if (av_strstart(line, "#EXTINF:", &ptr)) { double d = atof(ptr) * AV_TIME_BASE; if (d < 0 || d > INT64_MAX || isnan(d)) { @@ -1290,6 +1289,27 @@ static int parse_playlist(HLSContext *c, const char *url, } } + /* Media Playlist tags may precede the first tag that allocates the + * playlist. */ + if (pls && finished) + pls->finished = 1; + + /* EXT-X-START is valid in both playlist types. A value from the Master + * Playlist applies to all its Media Playlists, which then ignore their + * own (RFC 8216 4.3.5). */ + if (time_offset_flag && !c->master_time_offset_flag) { + if (pls) { + pls->start_time_offset = start_time_offset; + pls->time_offset_flag = 1; + } else { + c->master_time_offset_flag = 1; + for (int i = 0; i < c->n_playlists; i++) { + c->playlists[i]->start_time_offset = start_time_offset; + c->playlists[i]->time_offset_flag = 1; + } + } + } + fail: free_segment_dynarray(prev_segments, prev_n_segments); av_freep(&prev_segments); diff --git a/tests/ref/fate/hls-parse-master-start b/tests/ref/fate/hls-parse-master-start index 401c7af49d..57e88ecc7d 100644 --- a/tests/ref/fate/hls-parse-master-start +++ b/tests/ref/fate/hls-parse-master-start @@ -1 +1,3 @@ -error: Invalid data found when processing input +2 variant(s), 2 playlist(s) +a.m3u8: live, start offset 1500000 +b.m3u8: live, start offset 1500000 diff --git a/tests/ref/fate/hls-parse-master-start-media b/tests/ref/fate/hls-parse-master-start-media index 401c7af49d..57e88ecc7d 100644 --- a/tests/ref/fate/hls-parse-master-start-media +++ b/tests/ref/fate/hls-parse-master-start-media @@ -1 +1,3 @@ -error: Invalid data found when processing input +2 variant(s), 2 playlist(s) +a.m3u8: live, start offset 1500000 +b.m3u8: live, start offset 1500000 diff --git a/tests/ref/fate/hls-parse-master-start-override b/tests/ref/fate/hls-parse-master-start-override index 401c7af49d..57e88ecc7d 100644 --- a/tests/ref/fate/hls-parse-master-start-override +++ b/tests/ref/fate/hls-parse-master-start-override @@ -1 +1,3 @@ -error: Invalid data found when processing input +2 variant(s), 2 playlist(s) +a.m3u8: live, start offset 1500000 +b.m3u8: live, start offset 1500000 -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
