PR #24311 opened by michaelni
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24311
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24311.patch

The mov demuxer already treats sample durations above max_stts_delta as invalid 
when reading stts. Apply the same policy to fragmented files before storing 
trun durations in the packet time-to-sample table.

This prevents a corrupt UINT32_MAX duration from making timestamp-generating 
filters duplicate millions of frames.

Fixes issue #22843.

Assisted-by: Fairy



>From b45005038847402bc02b150d9a14be416fc6b38e Mon Sep 17 00:00:00 2001
From: Michael Niedermayer <[email protected]>
Date: Fri, 28 Aug 2026 16:34:20 +0000
Subject: [PATCH] avformat/mov: clip overly large trun sample durations

The mov demuxer already treats sample durations above max_stts_delta as invalid 
when reading stts. Apply the same policy to fragmented files before storing 
trun durations in the packet time-to-sample table.

This prevents a corrupt UINT32_MAX duration from making timestamp-generating 
filters duplicate millions of frames.

Fixes issue #22843.

Assisted-by: Fairy
---
 libavformat/mov.c                             |  7 +++++++
 tests/fate/mov.mak                            | 16 ++++++++++++++++
 tests/ref/fate/mov-trun-large-sample-duration | 10 ++++++++++
 3 files changed, 33 insertions(+)
 create mode 100644 tests/ref/fate/mov-trun-large-sample-duration

diff --git a/libavformat/mov.c b/libavformat/mov.c
index f53ce693f8..ba6c376209 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6404,6 +6404,13 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
         if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
         if (flags & MOV_TRUN_SAMPLE_CTS)      ctts_duration   = avio_rb32(pb);
 
+        if (sample_duration > c->max_stts_delta) {
+            av_log(c->fc, AV_LOG_WARNING,
+                   "Too large sample duration %u in trun entry %u in st:%d. 
Clipping to 1.\n",
+                   sample_duration, i, st->index);
+            sample_duration = 1;
+        }
+
         mov_update_dts_shift(sc, ctts_duration, c->fc);
         if (pts != AV_NOPTS_VALUE) {
             dts = pts - sc->dts_shift;
diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak
index 1a81962626..022e0214d6 100644
--- a/tests/fate/mov.mak
+++ b/tests/fate/mov.mak
@@ -313,6 +313,22 @@ FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, COLOR_FILTER 
SETPTS_FILTER MPEG4_ENCODER
                                       MOV_MUXER MOV_DEMUXER FILE_PROTOCOL)     
 \
                                       += fate-mov-vfr-bframes-derived-duration
 
+FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, COLOR_FILTER SETPTS_FILTER 
MPEG4_ENCODER \
+                                      MP4_MUXER MOV_DEMUXER FILE_PROTOCOL)     
 \
+                                      += fate-mov-trun-large-sample-duration
+
+# Generate a fragmented VFR file, then replace the last sample duration in
+# its first trun with UINT32_MAX.
+fate-mov-trun-large-sample-duration: CMD = run_with_patched_temp \
+    "$(FFMPEG) -nostdin -v error \
+    -filter_complex color=c=black:s=2x2:r=1,setpts=N*N \
+    -frames:v 10 -fps_mode vfr -c:v mpeg4 -g 5 -bf 0 -q:v 2 -threads 1 \
+    -flags +bitexact -fflags +bitexact \
+    -movflags empty_moov+frag_keyframe+default_base_moof -f mp4 -y" \
+    "ffprobe$(PROGSSUF)$(EXESUF) -show_packets \
+    -show_entries packet=pts,dts,duration -print_format compact \
+    -select_streams v -v 0" mp4 923 "\\0377\\0377\\0377\\0377"
+
 # Create VFR B-frames whose presentation durations are not a permutation of
 # the STTS sample deltas.
 tests/data/mov-vfr-bframes-derived-duration.mov: TAG = GEN
diff --git a/tests/ref/fate/mov-trun-large-sample-duration 
b/tests/ref/fate/mov-trun-large-sample-duration
new file mode 100644
index 0000000000..d65fa60996
--- /dev/null
+++ b/tests/ref/fate/mov-trun-large-sample-duration
@@ -0,0 +1,10 @@
+packet|pts=0|dts=0|duration=16384
+packet|pts=16384|dts=16384|duration=49152
+packet|pts=65536|dts=65536|duration=81920
+packet|pts=147456|dts=147456|duration=114688
+packet|pts=262144|dts=262144|duration=1
+packet|pts=409600|dts=409600|duration=180224
+packet|pts=589824|dts=589824|duration=212992
+packet|pts=802816|dts=802816|duration=245760
+packet|pts=1048576|dts=1048576|duration=278528
+packet|pts=1327104|dts=1327104|duration=16384
-- 
2.52.0

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

Reply via email to