PR #22337 opened by Nicolas Dato (ndato)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22337
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22337.patch

Functions like calc_cur_seg_no, calc_min_seg_no, and calc_max_seg_no calculated
the segment number taking into account the first_seq_no.
However, functions like get_segment_start_time_based_on_timeline and
calc_cur_seg_no didn't take first_seq_no into account.
This made dashdec believe that the cur_seq_no was always less than min_seq_no,
logging 'old fragment' and calling calc_cur_seq_no.

In live dash streams with some startNumber, that call to calc_cur_seq_no after
the 'old fragment' log made ffmpeg reposition itself 60 seconds before the
current time whenever the manifest reloaded.
This made ffmpeg skip segments, specially when the manifest reloaded slower
than the segments duration, resulting in a new manifest with more than one new
segment.

Signed-off-by: Nicolas Dato <[email protected]>


>From d86aa0dc22cba43cf5c0f28163423a6164e70fde Mon Sep 17 00:00:00 2001
From: Nicolas Dato <[email protected]>
Date: Sun, 1 Mar 2026 11:22:50 -0300
Subject: [PATCH] avformat/dashdec: fix calculation and usage of cur_seq_no,
 fixing issue 22335

Functions like calc_cur_seg_no, calc_min_seg_no, and calc_max_seg_no calculated
the segment number taking into account the first_seq_no.
However, functions like get_segment_start_time_based_on_timeline and
calc_cur_seg_no didn't take first_seq_no into account.
This made dashdec believe that the cur_seq_no was always less than min_seq_no,
logging 'old fragment' and calling calc_cur_seq_no.

In live dash streams with some startNumber, that call to calc_cur_seq_no after
the 'old fragment' log made ffmpeg reposition itself 60 seconds before the
current time whenever the manifest reloaded.
This made ffmpeg skip segments, specially when the manifest reloaded slower
than the segments duration, resulting in a new manifest with more than one new
segment.

Signed-off-by: Nicolas Dato <[email protected]>
---
 libavformat/dashdec.c | 9 +++------
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index 9a2ea78149..2068a827f3 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -260,6 +260,7 @@ static int64_t 
get_segment_start_time_based_on_timeline(struct representation *p
     int64_t j = 0;
     int64_t num = 0;
 
+    cur_seq_no -= pls->first_seq_no;
     if (pls->n_timelines) {
         for (i = 0; i < pls->n_timelines; i++) {
             if (pls->timelines[i]->starttime > 0) {
@@ -312,10 +313,10 @@ static int64_t calc_next_seg_no_from_timelines(struct 
representation *pls, int64
         num++;
     }
 
-    return -1;
+    return pls->first_seq_no;
 
 finish:
-    return num;
+    return num + pls->first_seq_no;
 }
 
 static void free_fragment(struct fragment **seg)
@@ -1417,10 +1418,6 @@ static int64_t calc_cur_seg_no(AVFormatContext *s, 
struct representation *pls)
             av_log(s, AV_LOG_TRACE, "in n_timelines mode\n");
             start_time_offset = get_segment_start_time_based_on_timeline(pls, 
0xFFFFFFFF) - 60 * pls->fragment_timescale; // 60 seconds before end
             num = calc_next_seg_no_from_timelines(pls, start_time_offset);
-            if (num == -1)
-                num = pls->first_seq_no;
-            else
-                num += pls->first_seq_no;
         } else if (pls->fragment_duration){
             av_log(s, AV_LOG_TRACE, "in fragment_duration mode 
fragment_timescale = %"PRId64", presentation_timeoffset = %"PRId64"\n", 
pls->fragment_timescale, pls->presentation_timeoffset);
             if (pls->presentation_timeoffset) {
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to