[PR] avformat/mov: clip overly large trun sample durations (PR #24311)

michaelni via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <[email protected]>
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]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.