This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

The following commit(s) were added to refs/heads/master by this push:
     new 711b1a52bd avformat/movenc: check if a packet is to be discarded when 
calculating edit list durations
711b1a52bd is described below

commit 711b1a52bd0b631f7ca999419110242c8361f38d
Author:     James Almer <[email protected]>
AuthorDate: Fri Mar 20 13:38:34 2026 -0300
Commit:     James Almer <[email protected]>
CommitDate: Sat Mar 21 23:35:39 2026 -0300

    avformat/movenc: check if a packet is to be discarded when calculating edit 
list durations
    
    Demuxers like mov will export packets not meant for presentation (e.g. 
because
    an edit list doesn't include them) by flagging them as discard, but the mov
    muxer completely ignored this, resulting in output edit lists considering 
every
    packet.
    
    Fixes issue #22552
    
    Signed-off-by: James Almer <[email protected]>
---
 libavformat/movenc.c                    | 27 ++++++++++++++++++++-------
 libavformat/movenc.h                    |  1 +
 tests/ref/fate/filter-meta-4560-rotate0 |  3 +--
 3 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 570dc1efef..8157b5e277 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3835,13 +3835,13 @@ static int mov_write_minf_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContext
 }
 
 static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
-                          int64_t *start, int64_t *end)
+                          int64_t *start, int64_t *end, int elst)
 {
     if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
         // tmcd tracks gets track_duration set in mov_write_moov_tag from
         // another track's duration, while the end_pts may be left at zero.
         // Calculate the pts duration for that track instead.
-        get_pts_range(mov, &mov->tracks[track->src_track], start, end);
+        get_pts_range(mov, &mov->tracks[track->src_track], start, end, elst);
         *start = av_rescale(*start, track->timescale,
                             mov->tracks[track->src_track].timescale);
         *end   = av_rescale(*end, track->timescale,
@@ -3852,7 +3852,7 @@ static void get_pts_range(MOVMuxContext *mov, MOVTrack 
*track,
         track->start_dts != AV_NOPTS_VALUE &&
         track->start_cts != AV_NOPTS_VALUE) {
         *start = track->start_dts + track->start_cts;
-        *end   = track->end_pts;
+        *end   = elst ? track->elst_end_pts : track->end_pts;
         return;
     }
     *start = 0;
@@ -3862,7 +3862,7 @@ static void get_pts_range(MOVMuxContext *mov, MOVTrack 
*track,
 static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
 {
     int64_t start, end;
-    get_pts_range(mov, track, &start, &end);
+    get_pts_range(mov, track, &start, &end, 0);
     return end - start;
 }
 
@@ -3874,12 +3874,19 @@ static int64_t calc_samples_pts_duration(MOVMuxContext 
*mov, MOVTrack *track)
 static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
 {
     int64_t start, end;
-    get_pts_range(mov, track, &start, &end);
+    get_pts_range(mov, track, &start, &end, 0);
     if (mov->use_editlist != 0)
         start = 0;
     return end - start;
 }
 
+static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track)
+{
+    int64_t start, end;
+    get_pts_range(mov, track, &start, &end, 1);
+    return end - start;
+}
+
 static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, 
int64_t duration)
 {
     if (track && track->mode == MODE_ISM)
@@ -4105,7 +4112,7 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack 
*track)
 static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
                               MOVTrack *track)
 {
-    int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track),
+    int64_t duration = av_rescale_rnd(calc_elst_duration(mov, track),
                                       mov->movie_timescale, track->timescale,
                                       AV_ROUND_UP);
     int version = duration < INT32_MAX ? 0 : 1;
@@ -6549,6 +6556,8 @@ static int mov_flush_fragment(AVFormatContext *s, int 
force)
                     track->end_pts = pts;
                 else
                     track->end_pts = dts;
+                if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
+                    track->elst_end_pts = track->end_pts;
             }
         }
     }
@@ -7111,7 +7120,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
             /* New fragment, but discontinuous from previous fragments.
              * Pretend the duration sum of the earlier fragments is
              * pkt->dts - trk->start_dts. */
-            trk->end_pts = AV_NOPTS_VALUE;
+            trk->end_pts = trk->elst_end_pts = AV_NOPTS_VALUE;
             trk->frag_discont = 0;
         }
     }
@@ -7166,6 +7175,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
         trk->end_pts = FFMAX(trk->end_pts, trk->cluster[trk->entry].dts +
                                            trk->cluster[trk->entry].cts +
                                            pkt->duration);
+    if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
+        trk->elst_end_pts = trk->end_pts;
 
     if (par->codec_id == AV_CODEC_ID_VC1) {
         mov_parse_vc1_frame(pkt, trk);
@@ -7291,6 +7302,8 @@ static int mov_write_single_packet(AVFormatContext *s, 
AVPacket *pkt)
                     trk->end_pts = pkt->pts;
                 else
                     trk->end_pts = pkt->dts;
+                if (!(pkt->flags & AV_PKT_FLAG_DISCARD))
+                    trk->elst_end_pts = trk->end_pts;
                 trk->end_reliable = 1;
             }
             mov_auto_flush_fragment(s, 0);
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index eb12551ee5..34e6d445cf 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -130,6 +130,7 @@ typedef struct MOVTrack {
     int64_t     start_dts;
     int64_t     start_cts;
     int64_t     end_pts;
+    int64_t     elst_end_pts;
     int         end_reliable;
     int64_t     dts_shift;
 
diff --git a/tests/ref/fate/filter-meta-4560-rotate0 
b/tests/ref/fate/filter-meta-4560-rotate0
index b0f3d67f08..ed1250a0c1 100644
--- a/tests/ref/fate/filter-meta-4560-rotate0
+++ b/tests/ref/fate/filter-meta-4560-rotate0
@@ -1,4 +1,4 @@
-6cd6b45a88881e85dfe7ad9582ffbeff *tests/data/fate/filter-meta-4560-rotate0.mov
+b03cf24561b152da246df6d0d6cf9b81 *tests/data/fate/filter-meta-4560-rotate0.mov
 347425 tests/data/fate/filter-meta-4560-rotate0.mov
 #tb 0: 1/30
 #media_type 0: video
@@ -266,4 +266,3 @@
 1,     152576,     152576,     1024,     2048, 0x26721b75
 0,        104,        104,        1,   195840, 0x46851b87
 1,     153600,     153600,     1024,     2048, 0x97a2f42c
-0,        105,        105,        1,   195840, 0x02d97dc4

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

Reply via email to