diff mbox series

[FFmpeg-devel,30/31] avformat/mux: Peek into the muxing queue for avoid_negative_ts

Message ID AM7PR03MB6660DBD5247438BCBC5E0A818F589@AM7PR03MB6660.eurprd03.prod.outlook.com
State Superseded
Headers show
Series [FFmpeg-devel,01/25] avformat/matroskaenc: Fix potential overflow | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc fail Make fate failed
andriy/make_aarch64_jetson success Make finished
andriy/make_fate_aarch64_jetson success Make fate finished

Commit Message

Andreas Rheinhardt Jan. 18, 2022, 11:32 p.m. UTC
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.rheinhardt@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 mbox series

Patch

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