Commit e4b1a53fea for ffmpeg
commit e4b1a53feae92cb46204692513eef6c2db437e9f
Author: Romain Beauxis <romain.beauxis@gmail.com>
Date: Sat Oct 17 12:58:09 2026 +0200
avformat/seek: keep the target inside the range when rescaling it
ff_rescale_interval() rounds the bounds of the range inwards and the
target to the nearest, so a target close to a bound could fall outside
the range, which the seek then rejects. A seek through the concat
demuxer to 0.53 s in a file starting at -2112 samples fails this way:
the file it reads gets a target one tick after the end of the range.
Clamp the target to the range, and use ff_rescale_interval() for the
same conversion done for read_seek2() with a single stream.
The seek through concat now lands at the target instead of failing and
reading from the start. The rescaled targets of the interval test stay
within their range: 10 instead of 11, and 4 instead of 3.
diff --git a/libavformat/demux.h b/libavformat/demux.h
index 73ecd494b8..4fdf3fdf27 100644
--- a/libavformat/demux.h
+++ b/libavformat/demux.h
@@ -309,8 +309,8 @@ void ff_rfps_calculate(AVFormatContext *ic);
*
* The upper (lower) bound of the output interval is rounded up (down) such that
* the output interval always falls within the input interval. The timestamp is
- * rounded to the nearest integer and halfway cases away from zero, and can
- * therefore fall outside of the output interval.
+ * rounded to the nearest integer and halfway cases away from zero, then
+ * clamped to the output interval.
*
* Useful to simplify the rescaling of the arguments of FFInputFormat::read_seek2()
*
diff --git a/libavformat/seek.c b/libavformat/seek.c
index 31e3e6dd69..82875483b5 100644
--- a/libavformat/seek.c
+++ b/libavformat/seek.c
@@ -684,14 +684,8 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
ff_read_frame_flush(s);
if (stream_index == -1 && s->nb_streams == 1) {
- AVRational time_base = s->streams[0]->time_base;
- ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
- min_ts = av_rescale_rnd(min_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
- max_ts = av_rescale_rnd(max_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+ ff_rescale_interval(AV_TIME_BASE_Q, s->streams[0]->time_base,
+ &min_ts, &ts, &max_ts);
stream_index = 0;
}
@@ -760,4 +754,6 @@ void ff_rescale_interval(AVRational tb_in, AVRational tb_out,
AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
*max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out,
AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+ // Rounding to the nearest can take the target out of the interval.
+ *ts = FFMAX(FFMIN(*ts, *max_ts), *min_ts);
}
diff --git a/tests/ref/fate/preroll-aac-concat-seek b/tests/ref/fate/preroll-aac-concat-seek
index 77f874610f..08cadd8280 100644
--- a/tests/ref/fate/preroll-aac-concat-seek
+++ b/tests/ref/fate/preroll-aac-concat-seek
@@ -1,32 +1,107 @@
+ret: 0 st: 0 flags:1 dts: 0.509388 pts: 0.509388 pos: 2416 size: 27
+ret: 0 st: 0 flags:1 dts: 0.532608 pts: 0.532608 pos: 2443 size: 28
+ret: 0 st: 0 flags:1 dts: 0.555828 pts: 0.555828 pos: 2471 size: 27
+ret: 0 st:-1 flags:0 ts:-1.000000
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
-ret: 0 st: 0 flags:1 dts: 0.021769 pts: 0.021769 pos: 1791 size: 89
-ret: 0 st:-1 flags:0 ts:-1.000000
+ret: 0 st:-1 flags:1 ts:-0.105833
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st: 0 flags:0 ts: 0.788345
+ret: 0 st: 0 flags:1 dts: 0.811247 pts: 0.811247 pos: 2774 size: 27
+ret: 0 st: 0 flags:1 dts: 0.834467 pts: 0.834467 pos: 2801 size: 28
+ret: 0 st: 0 flags:1 dts: 0.857687 pts: 0.857687 pos: 2829 size: 28
+ret: 0 st: 0 flags:1 ts: 1.682494
+ret: 0 st: 0 flags:1 dts: 1.670385 pts: 1.670385 pos: 3984 size: 41
+ret: 0 st: 0 flags:1 dts: 1.693605 pts: 1.693605 pos: 4025 size: 41
+ret: 0 st: 0 flags:1 dts: 1.716825 pts: 1.716825 pos: 4066 size: 41
+ret: 0 st:-1 flags:0 ts:-0.423332
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st:-1 flags:1 ts: 0.470835
+ret: 0 st: 0 flags:1 dts: 0.462948 pts: 0.462948 pos: 2363 size: 26
+ret: 0 st: 0 flags:1 dts: 0.486168 pts: 0.486168 pos: 2389 size: 27
+ret: 0 st: 0 flags:1 dts: 0.509388 pts: 0.509388 pos: 2416 size: 27
+ret: 0 st: 0 flags:0 ts: 1.365011
+ret: 0 st: 0 flags:1 dts: 1.368526 pts: 1.368526 pos: 3465 size: 30
+ret: 0 st: 0 flags:1 dts: 1.391746 pts: 1.391746 pos: 3495 size: 39
+ret: 0 st: 0 flags:1 dts: 1.414966 pts: 1.414966 pos: 3534 size: 42
+ret: 0 st: 0 flags:1 ts:-0.740839
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st:-1 flags:0 ts: 0.153336
+ret: 0 st: 0 flags:1 dts: 0.161088 pts: 0.161088 pos: 2014 size: 27
+ret: 0 st: 0 flags:1 dts: 0.184308 pts: 0.184308 pos: 2041 size: 27
+ret: 0 st: 0 flags:1 dts: 0.207528 pts: 0.207528 pos: 2068 size: 27
+ret: 0 st:-1 flags:1 ts: 1.047503
+ret: 0 st: 0 flags:1 dts: 1.043447 pts: 1.043447 pos: 3052 size: 27
+ret: 0 st: 0 flags:1 dts: 1.066667 pts: 1.066667 pos: 3079 size: 28
+ret: 0 st: 0 flags:1 dts: 1.089887 pts: 1.089887 pos: 3107 size: 30
+ret: 0 st: 0 flags:0 ts: 1.941678
+ret: 0 st: 0 flags:1 dts: 1.949025 pts: 1.949025 pos: 4474 size: 41
+ret: 0 st: 0 flags:1 dts: 1.972245 pts: 1.972245 pos: 4515 size: 39
+ret: 0 st: 0 flags:1 dts: 1.995465 pts: 1.995465 pos: 4554 size: 42
+ret: 0 st: 0 flags:1 ts:-0.164172
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st:-1 flags:0 ts: 0.730004
+ret: 0 st: 0 flags:1 dts: 0.741587 pts: 0.741587 pos: 2691 size: 28
+ret: 0 st: 0 flags:1 dts: 0.764807 pts: 0.764807 pos: 2719 size: 28
+ret: 0 st: 0 flags:1 dts: 0.788027 pts: 0.788027 pos: 2747 size: 27
+ret: 0 st:-1 flags:1 ts: 1.624171
+ret: 0 st: 0 flags:1 dts: 1.623946 pts: 1.623946 pos: 3903 size: 39
+ret: 0 st: 0 flags:1 dts: 1.647166 pts: 1.647166 pos: 3942 size: 42
+ret: 0 st: 0 flags:1 dts: 1.670385 pts: 1.670385 pos: 3984 size: 41
+ret: 0 st: 0 flags:0 ts:-0.481655
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st: 0 flags:1 ts: 0.412494
+ret: 0 st: 0 flags:1 dts: 0.393288 pts: 0.393288 pos: 2282 size: 27
+ret: 0 st: 0 flags:1 dts: 0.416508 pts: 0.416508 pos: 2309 size: 27
+ret: 0 st: 0 flags:1 dts: 0.439728 pts: 0.439728 pos: 2336 size: 27
+ret: 0 st:-1 flags:0 ts: 1.306672
+ret: 0 st: 0 flags:1 dts: 1.322086 pts: 1.322086 pos: 3405 size: 30
+ret: 0 st: 0 flags:1 dts: 1.345306 pts: 1.345306 pos: 3435 size: 30
+ret: 0 st: 0 flags:1 dts: 1.368526 pts: 1.368526 pos: 3465 size: 30
+ret: 0 st:-1 flags:1 ts:-0.799161
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st: 0 flags:0 ts: 0.095011
+ret: 0 st: 0 flags:1 dts: 0.114649 pts: 0.114649 pos: 1961 size: 26
+ret: 0 st: 0 flags:1 dts: 0.137868 pts: 0.137868 pos: 1987 size: 27
+ret: 0 st: 0 flags:1 dts: 0.161088 pts: 0.161088 pos: 2014 size: 27
+ret: 0 st: 0 flags:1 ts: 0.989184
+ret: 0 st: 0 flags:1 dts: 0.973787 pts: 0.973787 pos: 2968 size: 28
+ret: 0 st: 0 flags:1 dts: 0.997007 pts: 0.997007 pos: 2996 size: 28
+ret: 0 st: 0 flags:1 dts: 1.020227 pts: 1.020227 pos: 3024 size: 28
+ret: 0 st:-1 flags:0 ts: 1.883340
+ret: 0 st: 0 flags:1 dts: 1.902585 pts: 1.902585 pos: 4392 size: 41
+ret: 0 st: 0 flags:1 dts: 1.925805 pts: 1.925805 pos: 4433 size: 41
+ret: 0 st: 0 flags:1 dts: 1.949025 pts: 1.949025 pos: 4474 size: 41
+ret: 0 st:-1 flags:1 ts:-0.222493
+ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
+ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
+ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
+ret: 0 st: 0 flags:0 ts: 0.671678
+ret: 0 st: 0 flags:1 dts: 0.671927 pts: 0.671927 pos: 2609 size: 27
+ret: 0 st: 0 flags:1 dts: 0.695147 pts: 0.695147 pos: 2636 size: 27
+ret: 0 st: 0 flags:1 dts: 0.718367 pts: 0.718367 pos: 2663 size: 28
+ret: 0 st: 0 flags:1 ts: 1.565850
+ret: 0 st: 0 flags:1 dts: 1.554286 pts: 1.554286 pos: 3780 size: 41
+ret: 0 st: 0 flags:1 dts: 1.577506 pts: 1.577506 pos: 3821 size: 41
+ret: 0 st: 0 flags:1 dts: 1.600726 pts: 1.600726 pos: 3862 size: 41
+ret: 0 st:-1 flags:0 ts:-0.539992
ret: 0 st: 0 flags:1 dts:-0.047891 pts:-0.047891 pos: 1366 size: 6 skip:2112 discard:0
ret: 0 st: 0 flags:1 dts:-0.024671 pts:-0.024671 pos: 1372 size: 251
ret: 0 st: 0 flags:1 dts:-0.001451 pts:-0.001451 pos: 1623 size: 168
-ret:-1 st:-1 flags:1 ts:-0.105833
-ret:-1 st: 0 flags:0 ts: 0.788345
-ret:-1 st: 0 flags:1 ts: 1.682494
-ret:-1 st:-1 flags:0 ts:-0.423332
-ret:-1 st:-1 flags:1 ts: 0.470835
-ret:-1 st: 0 flags:0 ts: 1.365011
-ret:-1 st: 0 flags:1 ts:-0.740839
-ret:-1 st:-1 flags:0 ts: 0.153336
-ret:-1 st:-1 flags:1 ts: 1.047503
-ret:-1 st: 0 flags:0 ts: 1.941678
-ret:-1 st: 0 flags:1 ts:-0.164172
-ret:-1 st:-1 flags:0 ts: 0.730004
-ret:-1 st:-1 flags:1 ts: 1.624171
-ret:-1 st: 0 flags:0 ts:-0.481655
-ret:-1 st: 0 flags:1 ts: 0.412494
-ret:-1 st:-1 flags:0 ts: 1.306672
-ret:-1 st:-1 flags:1 ts:-0.799161
-ret:-1 st: 0 flags:0 ts: 0.095011
-ret:-1 st: 0 flags:1 ts: 0.989184
-ret:-1 st:-1 flags:0 ts: 1.883340
-ret:-1 st:-1 flags:1 ts:-0.222493
-ret:-1 st: 0 flags:0 ts: 0.671678
-ret:-1 st: 0 flags:1 ts: 1.565850
-ret:-1 st:-1 flags:0 ts:-0.539992
-ret:-1 st:-1 flags:1 ts: 0.354175
+ret: 0 st:-1 flags:1 ts: 0.354175
+ret: 0 st: 0 flags:1 dts: 0.346848 pts: 0.346848 pos: 2229 size: 26
+ret: 0 st: 0 flags:1 dts: 0.370068 pts: 0.370068 pos: 2255 size: 27
+ret: 0 st: 0 flags:1 dts: 0.393288 pts: 0.393288 pos: 2282 size: 27
diff --git a/tests/ref/fate/seek_utils b/tests/ref/fate/seek_utils
index ddb0517a45..4d7f12564c 100644
--- a/tests/ref/fate/seek_utils
+++ b/tests/ref/fate/seek_utils
@@ -1,3 +1,3 @@
1/1 -> 10/1: [10, 20, 30] -> [1, 2, 3]
-1/1 -> 3/1: [10, 32, 32] -> [4, 11, 10]
-1/1 -> 3/1: [10, 10, 32] -> [4, 3, 10]
+1/1 -> 3/1: [10, 32, 32] -> [4, 10, 10]
+1/1 -> 3/1: [10, 10, 32] -> [4, 4, 10]