PR #23534 opened by James Almer (jamrial)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23534
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23534.patch

Sometimes the duration itself reflects the remainder samples by being set to a 
value lower than the frame size, but in other cases it's done only through a 
discard padding value in side data.

Take the latter into account when calculating durations.


>From 0e1cf2dbdb9c7fa95f1b85ce25d6e6fd1af19f3b Mon Sep 17 00:00:00 2001
From: James Almer <[email protected]>
Date: Thu, 18 Jun 2026 15:05:04 -0300
Subject: [PATCH] avformat/movenc: look for remainder samples in packet side
 data

Sometimes the duration itself reflects the remainder samples by being set to a
value lower than the frame size, but in other cases it's done only through
a discard padding value in side data.
Take the latter into account when calculating durations.

Fixes issue #23532.

Signed-off-by: James Almer <[email protected]>
---
 libavformat/movenc.c                    | 17 ++++++++++++++---
 tests/ref/fate/filter-meta-4560-rotate0 |  6 +++---
 tests/ref/fate/mov-cover-image          |  4 ++--
 3 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 7c9dbb29f7..1ab9d170c7 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6941,6 +6941,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     AVCodecParameters *par;
     AVProducerReferenceTime *prft;
     unsigned int samples_in_chunk = 0;
+    int64_t duration = pkt->duration;
     int size = pkt->size, ret = 0, offset = 0;
     size_t prft_size;
     uint8_t *reformatted_data = NULL;
@@ -7310,7 +7311,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
                    "this case.\n",
                    pkt->stream_index, pkt->dts);
     }
-    trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
+
+    sd = av_packet_side_data_get(pkt->side_data, pkt->side_data_elems, 
AV_PKT_DATA_SKIP_SAMPLES);
+    if (sd && sd->size >= 10 && trk->par->frame_size) {
+        duration = FFMAX(trk->par->frame_size, duration);
+        duration -= av_rescale_q(AV_RL32(sd->data + 4), (AVRational){ 1, 
trk->par->sample_rate },
+                                 trk->st->time_base);
+        if (duration < 0)
+            return AVERROR_INVALIDDATA;
+    }
+
+    trk->track_duration = pkt->dts - trk->start_dts + duration;
     trk->last_sample_is_subtitle_end = 0;
 
     if (pkt->pts == AV_NOPTS_VALUE) {
@@ -7325,11 +7336,11 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
         trk->start_cts = pkt->pts - pkt->dts;
     if (trk->end_pts == AV_NOPTS_VALUE)
         trk->end_pts = trk->cluster[trk->entry].dts +
-                       trk->cluster[trk->entry].cts + pkt->duration;
+                       trk->cluster[trk->entry].cts + duration;
     else
         trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
                                            trk->cluster[trk->entry].cts +
-                                           pkt->duration);
+                                           duration);
     if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
         trk->elst_end_pts = trk->end_pts;
 
diff --git a/tests/ref/fate/filter-meta-4560-rotate0 
b/tests/ref/fate/filter-meta-4560-rotate0
index 7ebd52092d..cd49574672 100644
--- a/tests/ref/fate/filter-meta-4560-rotate0
+++ b/tests/ref/fate/filter-meta-4560-rotate0
@@ -1,5 +1,5 @@
-8718876acc3ffd74610daba770900b40 *tests/data/fate/filter-meta-4560-rotate0.mov
-347425 tests/data/fate/filter-meta-4560-rotate0.mov
+18ca1e5d9da95d06b75937eae003a38f *tests/data/fate/filter-meta-4560-rotate0.mov
+347433 tests/data/fate/filter-meta-4560-rotate0.mov
 #tb 0: 1/30
 #media_type 0: video
 #codec_id 0: rawvideo
@@ -265,4 +265,4 @@
 1,     151552,     151552,     1024,     2048, 0x473a05a3
 1,     152576,     152576,     1024,     2048, 0x26721b75
 0,        104,        104,        1,   195840, 0x46851b87
-1,     153600,     153600,     1024,     2048, 0x97a2f42c
+1,     153600,     153600,       89,      178, 0x94b35030
diff --git a/tests/ref/fate/mov-cover-image b/tests/ref/fate/mov-cover-image
index b0db8f9dd2..f128037a8b 100644
--- a/tests/ref/fate/mov-cover-image
+++ b/tests/ref/fate/mov-cover-image
@@ -1,5 +1,5 @@
-017a372d92c59971c2ddee95298e745a *tests/data/fate/mov-cover-image.mp4
-1024065 tests/data/fate/mov-cover-image.mp4
+616f09865fa0e4f90b168f16ce2b2538 *tests/data/fate/mov-cover-image.mp4
+1024073 tests/data/fate/mov-cover-image.mp4
 #extradata 0:        2, 0x00340022
 #tb 0: 1/44100
 #media_type 0: audio
-- 
2.52.0

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

Reply via email to