Peeking into the muxing queue can improve the estimate of the lowest timestamp needed for avoid_negative_ts in case the lowest timestamp is in a packet other than the first packet to be muxed. This fixes tickets #4536 and #5784 as well as the output from the matroska-avoid-negative-ts FATE-test.
Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavformat/mux.c | 21 ++++++++- tests/fate/matroska.mak | 2 - tests/ref/fate/matroska-avoid-negative-ts | 52 +++++++++++------------ 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/libavformat/mux.c b/libavformat/mux.c index 0810b674a7..53eb56f0af 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -655,16 +655,33 @@ static void handle_avoid_negative_ts(FFFormatContext *si, FFStream *sti, if (si->avoid_negative_ts_status == AVOID_NEGATIVE_TS_UNKNOWN) { int use_pts = si->avoid_negative_ts_use_pts; int64_t ts = use_pts ? pkt->pts : pkt->dts; + AVRational tb = sti->pub.time_base; if (ts == AV_NOPTS_VALUE) return; + + /* Peek into the muxing queue to improve our estimate + * of the lowest timestamp if av_interleaved_write_frame() is used. */ + for (const PacketListEntry *pktl = si->packet_buffer.head; + pktl; pktl = pktl->next) { + AVRational cmp_tb = s->streams[pktl->pkt.stream_index]->time_base; + int64_t cmp_ts = use_pts ? pktl->pkt.pts : pktl->pkt.dts; + if (cmp_ts == AV_NOPTS_VALUE) + continue; + if (s->output_ts_offset) + cmp_ts += av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, cmp_tb); + if (av_compare_ts(cmp_ts, cmp_tb, ts, tb) < 0) { + ts = cmp_ts; + tb = cmp_tb; + } + } + if (ts < 0 || ts > 0 && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) { for (unsigned i = 0; i < s->nb_streams; i++) { AVStream *const st2 = s->streams[i]; FFStream *const sti2 = ffstream(st2); - sti2->mux_ts_offset = av_rescale_q_rnd(-ts, - sti->pub.time_base, + sti2->mux_ts_offset = av_rescale_q_rnd(-ts, tb, st2->time_base, AV_ROUND_UP); } diff --git a/tests/fate/matroska.mak b/tests/fate/matroska.mak index 3d8110a434..e31ce39eda 100644 --- a/tests/fate/matroska.mak +++ b/tests/fate/matroska.mak @@ -94,8 +94,6 @@ fate-matroska-dovi-write-config7: CMD = transcode mov $(TARGET_SAMPLES)/mov/dovi # the first packet (with the overall lowest dts) is a video packet, # whereas an audio packet to be muxed later has the overall lowest pts # which happens to be negative and therefore needs to be shifted. -# This is currently buggy (the timestamps are not shifted properly: -# the first audio packet has negative timestamps). # Also tests muxing DOVI. FATE_MATROSKA_FFMPEG_FFPROBE-$(call ALLYES, FILE_PROTOCOL MOV_DEMUXER \ AAC_FIXED_DECODER HEVC_DECODER \ diff --git a/tests/ref/fate/matroska-avoid-negative-ts b/tests/ref/fate/matroska-avoid-negative-ts index 5bc71c76f7..8266a4491f 100644 --- a/tests/ref/fate/matroska-avoid-negative-ts +++ b/tests/ref/fate/matroska-avoid-negative-ts @@ -1,4 +1,4 @@ -e31928477981a8ffad351379f6d5f14a *tests/data/fate/matroska-avoid-negative-ts.matroska +e18a45c95db97f7cdfae28bd002786b6 *tests/data/fate/matroska-avoid-negative-ts.matroska 3618353 tests/data/fate/matroska-avoid-negative-ts.matroska #extradata 0: 551, 0xa18acf66 #tb 0: 1/1000 @@ -12,32 +12,32 @@ e31928477981a8ffad351379f6d5f14a *tests/data/fate/matroska-avoid-negative-ts.mat #sample_rate 1: 44100 #channel_layout 1: 3 #channel_layout_name 1: stereo -0, -62, 5, 33, 63375, 0xc76606ab, S=1, 8 -0, -29, 138, 33, 46706, 0x0e08a7e5, F=0x0 +0, -61, 6, 33, 63375, 0xc76606ab, S=1, 8 +0, -28, 139, 33, 46706, 0x0e08a7e5, F=0x0 1, 0, 0, 34, 834, 0x7e7776bd -0, 5, 72, 33, 29766, 0x753c031a, F=0x0 -1, 34, 34, 34, 836, 0x14a3a0ff -0, 38, 38, 33, 19409, 0x4b948b6c, F=0x0 -1, 69, 69, 34, 836, 0xf55e9a61 -0, 72, 105, 33, 21086, 0x1b9412ce, F=0x0 -1, 104, 104, 34, 836, 0x415591f1 -0, 105, 272, 33, 62043, 0xc2356b56, F=0x0 -0, 138, 205, 33, 36175, 0x0a7df38c, F=0x0 -1, 139, 139, 34, 836, 0xe26c9bad -0, 172, 172, 33, 16028, 0xa57fcbe9, F=0x0 -1, 173, 173, 34, 836, 0xbc8c9b66 -0, 205, 238, 33, 15428, 0x9a91f357, F=0x0 -1, 208, 208, 34, 836, 0xddeb9643 -0, 238, 405, 33, 66072, 0xa542b6d7, F=0x0 -1, 243, 243, 34, 836, 0x08a494eb -0, 272, 338, 33, 34985, 0xbfd8ff45, F=0x0 -1, 278, 278, 34, 836, 0x94f09bb4 -0, 305, 305, 33, 16036, 0xfc39c6ea, F=0x0 -1, 313, 313, 34, 836, 0xd6358a3a -0, 338, 372, 33, 19893, 0x7e746f4e, F=0x0 -1, 347, 347, 34, 836, 0x76ac91f1 -0, 372, 538, 33, 77576, 0xeba2e5c8, F=0x0 -1, 382, 382, 34, 836, 0xb32a86ac +0, 6, 73, 33, 29766, 0x753c031a, F=0x0 +1, 35, 35, 34, 836, 0x14a3a0ff +0, 39, 39, 33, 19409, 0x4b948b6c, F=0x0 +1, 70, 70, 34, 836, 0xf55e9a61 +0, 73, 106, 33, 21086, 0x1b9412ce, F=0x0 +1, 105, 105, 34, 836, 0x415591f1 +0, 106, 273, 33, 62043, 0xc2356b56, F=0x0 +0, 139, 206, 33, 36175, 0x0a7df38c, F=0x0 +1, 140, 140, 34, 836, 0xe26c9bad +0, 173, 173, 33, 16028, 0xa57fcbe9, F=0x0 +1, 174, 174, 34, 836, 0xbc8c9b66 +0, 206, 239, 33, 15428, 0x9a91f357, F=0x0 +1, 209, 209, 34, 836, 0xddeb9643 +0, 239, 406, 33, 66072, 0xa542b6d7, F=0x0 +1, 244, 244, 34, 836, 0x08a494eb +0, 273, 339, 33, 34985, 0xbfd8ff45, F=0x0 +1, 279, 279, 34, 836, 0x94f09bb4 +0, 306, 306, 33, 16036, 0xfc39c6ea, F=0x0 +1, 314, 314, 34, 836, 0xd6358a3a +0, 339, 373, 33, 19893, 0x7e746f4e, F=0x0 +1, 348, 348, 34, 836, 0x76ac91f1 +0, 373, 539, 33, 77576, 0xeba2e5c8, F=0x0 +1, 383, 383, 34, 836, 0xb32a86ac [STREAM] [SIDE_DATA] side_data_type=DOVI configuration record -- 2.32.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".