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

#23534 stores pkt->duration in a local variable upon entering 
ff_mov_write_packet and assumes pkt->duration remains unchanged until checking 
the packet side data.

But handle_eac3() buffers and concatenates "short" frames until 6 blocks (1536 
samples) are reached, and updates pkt->duration as it does so, and the above 
change basically "overwrites" such updates with the initial value of 
pkt->duration, possibly  (probably?) causing issue #23600

It seems easier (and possibly safer) to eliminate the local variable at the 
root of the function and ensure the side data code block uses the latest 
pkt->duration than to check the whole function to determine which functions 
might update pkt->duration and pass the local variable to them for updating 
instead.

---

This patch fixes src.wav from 23600 for me.

Some fate test results are changed and I have no had the time to check whether 
the changes are expected, hence the WIP.

---

In addition, the Tears of Steel sample referenced in 23600 still has a 
different duration in the edit list when short eac3 frames are used, but I 
suspect this may be because the encoder is producing an odd number of frames 
and movenc is just dropping one of the short frames (but I haven't fully 
ascertained that's what happens yet).


>From d5c71f318bc4b3a8ccda7ca65e41629f3ee1066d Mon Sep 17 00:00:00 2001
From: Tim Walker <[email protected]>
Date: Fri, 26 Jun 2026 07:31:03 +0200
Subject: [PATCH] avformat/movenc: don't override changes to pkt->duration
 ff_mov_write_packet may call other functions that update it; so storing its
 value in a variable upon entry is unreliable.

---
 libavformat/movenc.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index c14f05ecc8..56f8f393d9 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -6935,7 +6935,6 @@ 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;
@@ -7308,12 +7307,16 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket 
*pkt)
 
     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) {
+        // pkt->duration may have changed since ff_mov_write_packet was entered
+        // it is e.g. updated by handle_eac3() when concatenating "short" 
frames
+        int64_t duration = pkt->duration;
         duration = FFMAX(av_rescale_q(trk->par->frame_size, (AVRational){ 1, 
trk->par->sample_rate },
                                       trk->st->time_base), 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;
+        pkt->duration = duration;
     }
 
     trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
@@ -7331,11 +7334,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 + duration;
+                       trk->cluster[trk->entry].cts + pkt->duration;
     else
         trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
                                            trk->cluster[trk->entry].cts +
-                                           duration);
+                                           pkt->duration);
     if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
         trk->elst_end_pts = trk->end_pts;
 
-- 
2.52.0

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

Reply via email to