This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 579edeabecc4d645d52f7a92d99fb5c66ecf696d Author: James Almer <[email protected]> AuthorDate: Sun Jun 21 02:29:37 2026 +0000 Commit: James Almer <[email protected]> CommitDate: Tue Jun 23 20:07:25 2026 -0300 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 | 28 ++++++++++++++++++++-------- tests/ref/fate/filter-meta-4560-rotate0 | 4 ++-- tests/ref/fate/hevc-bsf-dts2pts-cra | 2 +- tests/ref/fate/hevc-bsf-dts2pts-idr | 2 +- tests/ref/fate/hevc-bsf-dts2pts-idr-cra | 2 +- tests/ref/fate/mov-cover-image | 2 +- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 7b08f58977..c14f05ecc8 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3854,20 +3854,20 @@ 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, int elst) + int64_t *start, int64_t *end, int elst, int mdhd) { if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd && track->nb_src_track) { // 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, elst); + get_pts_range(mov, &mov->tracks[*track->src_track], start, end, elst, mdhd); *start = av_rescale(*start, track->timescale, mov->tracks[*track->src_track].timescale); *end = av_rescale(*end, track->timescale, mov->tracks[*track->src_track].timescale); return; } - if (track->end_pts != AV_NOPTS_VALUE && + if (!mdhd && track->end_pts != AV_NOPTS_VALUE && track->start_dts != AV_NOPTS_VALUE && track->start_cts != AV_NOPTS_VALUE) { *start = track->start_dts + track->start_cts; @@ -3881,7 +3881,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, 0); + get_pts_range(mov, track, &start, &end, 0, 1); return end - start; } @@ -3893,7 +3893,7 @@ 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, 0); + get_pts_range(mov, track, &start, &end, 0, 0); if (mov->use_editlist != 0) start = 0; return end - start; @@ -3902,7 +3902,7 @@ static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track) static int64_t calc_elst_duration(MOVMuxContext *mov, MOVTrack *track) { int64_t start, end; - get_pts_range(mov, track, &start, &end, 1); + get_pts_range(mov, track, &start, &end, 1, 0); return end - start; } @@ -6935,6 +6935,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; @@ -7304,6 +7305,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) "this case.\n", pkt->stream_index, pkt->dts); } + + 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(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; + } + trk->track_duration = pkt->dts - trk->start_dts + pkt->duration; trk->last_sample_is_subtitle_end = 0; @@ -7319,11 +7331,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..8606137e45 100644 --- a/tests/ref/fate/filter-meta-4560-rotate0 +++ b/tests/ref/fate/filter-meta-4560-rotate0 @@ -1,4 +1,4 @@ -8718876acc3ffd74610daba770900b40 *tests/data/fate/filter-meta-4560-rotate0.mov +796b09d860affeeed44b95d622c214f1 *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 @@ -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/hevc-bsf-dts2pts-cra b/tests/ref/fate/hevc-bsf-dts2pts-cra index 5d91e7538b..cd70cde3a6 100644 --- a/tests/ref/fate/hevc-bsf-dts2pts-cra +++ b/tests/ref/fate/hevc-bsf-dts2pts-cra @@ -1,4 +1,4 @@ -07052bab1eb3066536daef8bd51901a8 *tests/data/fate/hevc-bsf-dts2pts-cra.mov +72722d11426fe39218dc59f111a353d0 *tests/data/fate/hevc-bsf-dts2pts-cra.mov 103067 tests/data/fate/hevc-bsf-dts2pts-cra.mov #extradata 0: 118, 0x25f51994 #tb 0: 1/1200000 diff --git a/tests/ref/fate/hevc-bsf-dts2pts-idr b/tests/ref/fate/hevc-bsf-dts2pts-idr index 6b46ad1fff..3a339e8d6d 100644 --- a/tests/ref/fate/hevc-bsf-dts2pts-idr +++ b/tests/ref/fate/hevc-bsf-dts2pts-idr @@ -1,4 +1,4 @@ -8bf0d529d144cfd08a7e62e8b2025352 *tests/data/fate/hevc-bsf-dts2pts-idr.mov +773de1cf5d3424da867453e8c2473500 *tests/data/fate/hevc-bsf-dts2pts-idr.mov 346603 tests/data/fate/hevc-bsf-dts2pts-idr.mov #extradata 0: 699, 0x9c810c10 #tb 0: 1/1200000 diff --git a/tests/ref/fate/hevc-bsf-dts2pts-idr-cra b/tests/ref/fate/hevc-bsf-dts2pts-idr-cra index 3612ca1555..b424a8ba99 100644 --- a/tests/ref/fate/hevc-bsf-dts2pts-idr-cra +++ b/tests/ref/fate/hevc-bsf-dts2pts-idr-cra @@ -1,4 +1,4 @@ -e2374650488cf8f905c441d6f4a3cff4 *tests/data/fate/hevc-bsf-dts2pts-idr-cra.mov +81d05ed8ec426d7732ce4f73176c50fe *tests/data/fate/hevc-bsf-dts2pts-idr-cra.mov 375266 tests/data/fate/hevc-bsf-dts2pts-idr-cra.mov #extradata 0: 648, 0x30a7fa5c #tb 0: 1/1200000 diff --git a/tests/ref/fate/mov-cover-image b/tests/ref/fate/mov-cover-image index b0db8f9dd2..6c6607c39c 100644 --- a/tests/ref/fate/mov-cover-image +++ b/tests/ref/fate/mov-cover-image @@ -1,4 +1,4 @@ -017a372d92c59971c2ddee95298e745a *tests/data/fate/mov-cover-image.mp4 +124d92893a4a6dc8e0b5a6c384536e2e *tests/data/fate/mov-cover-image.mp4 1024065 tests/data/fate/mov-cover-image.mp4 #extradata 0: 2, 0x00340022 #tb 0: 1/44100 _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
