[PR] avformat/movenc: look for remainder samples in packet side data (PR #23534)

James Almer via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178180693993.63.2773901153388483122@29965ddac10e>
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]
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.