summaryrefslogtreecommitdiff
path: root/libavformat/mux.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-01-18 22:55:27 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-01-21 16:47:38 +0100
commitc24ee7c275b6374b4b6ef4030e93d416a9c2265f (patch)
treef18f74da636a6b6a4b09e6ed247dc68a3580c6b0 /libavformat/mux.c
parentc602deb138562a2a7ff9e2c05d9ba9b1fb76668c (diff)
downloadffmpeg-c24ee7c275b6374b4b6ef4030e93d416a9c2265f.tar.gz
avformat/mux: Peek into the muxing queue for avoid_negative_ts
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>
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r--libavformat/mux.c21
1 files changed, 19 insertions, 2 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);
}