PR #25673 opened by Kacper Michajłow (kasper93)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25673
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25673.patch

ISO/IEC 14496-12:2026 8.6.6.1 allows the last edit to be a non-empty
entry with a duration of 0, which readers shall interpret as the
accumulated duration of all samples. mov_fix_index() took the zero
literally, discarded every sample and left such tracks without frames.
The standard states this for fragmented movies, but a literal zero
selects nothing in any movie, and files flattened from fragmented
movies by other muxers keep the edit.

Fixes: https://trac.ffmpeg.org/ticket/6138
Fixes: https://trac.ffmpeg.org/ticket/7123
Fixes: https://github.com/mpv-player/mpv/issues/14167
Fixes: https://github.com/mpv-player/mpv/issues/18742




From 1d1ec8af1a402b381a3b90a3043391eb850066ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Mon, 2 Nov 2026 05:33:16 +0100
Subject: [PATCH] avformat/mov: read a zero last edit duration as the track
 duration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ISO/IEC 14496-12:2026 8.6.6.1 allows the last edit to be a non-empty
entry with a duration of 0, which readers shall interpret as the
accumulated duration of all samples. mov_fix_index() took the zero
literally, discarded every sample and left such tracks without frames.
The standard states this for fragmented movies, but a literal zero
selects nothing in any movie, and files flattened from fragmented
movies by other muxers keep the edit.

Fixes: https://trac.ffmpeg.org/ticket/6138
Fixes: https://trac.ffmpeg.org/ticket/7123
Fixes: https://github.com/mpv-player/mpv/issues/14167
Fixes: https://github.com/mpv-player/mpv/issues/18742
Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavformat/mov.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 786994699e7..93b3e21cdea 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4600,6 +4600,11 @@ static void mov_fix_index(MOVContext *mov, AVStream *st)
         av_log(mov->fc, AV_LOG_DEBUG, "Processing st: %d, edit list %"PRId64" 
- media time: %"PRId64", duration: %"PRId64"\n",
                st->index, edit_list_index, edit_list_media_time, 
edit_list_duration);
         edit_list_index++;
+        // The last edit may have a zero duration, which stands for the
+        // accumulated duration of all samples (ISO/IEC 14496-12:2026 8.6.6.1).
+        if (!msc->elst_data[edit_list_index - 1].duration &&
+            edit_list_media_time >= 0 && edit_list_index == msc->elst_count)
+            edit_list_duration = av_clip64(msc->track_end, 0, INT64_MAX - 
edit_list_media_time);
         edit_list_dts_counter = edit_list_dts_entry_end;
         edit_list_dts_entry_end = av_sat_add64(edit_list_dts_entry_end, 
edit_list_duration);
         if (edit_list_dts_entry_end == INT64_MAX) {
-- 
2.54.0

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

Reply via email to