mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
c602deb138
commit
c24ee7c275
@ -1527,7 +1527,7 @@ typedef struct AVFormatContext {
|
|||||||
/**
|
/**
|
||||||
* Avoid negative timestamps during muxing.
|
* Avoid negative timestamps during muxing.
|
||||||
* Any value of the AVFMT_AVOID_NEG_TS_* constants.
|
* Any value of the AVFMT_AVOID_NEG_TS_* constants.
|
||||||
* Note, this only works when using av_interleaved_write_frame. (interleave_packet_per_dts is in use)
|
* Note, this works better when using av_interleaved_write_frame().
|
||||||
* - muxing: Set by user
|
* - muxing: Set by user
|
||||||
* - demuxing: unused
|
* - demuxing: unused
|
||||||
*/
|
*/
|
||||||
|
@ -655,16 +655,33 @@ static void handle_avoid_negative_ts(FFFormatContext *si, FFStream *sti,
|
|||||||
if (si->avoid_negative_ts_status == AVOID_NEGATIVE_TS_UNKNOWN) {
|
if (si->avoid_negative_ts_status == AVOID_NEGATIVE_TS_UNKNOWN) {
|
||||||
int use_pts = si->avoid_negative_ts_use_pts;
|
int use_pts = si->avoid_negative_ts_use_pts;
|
||||||
int64_t ts = use_pts ? pkt->pts : pkt->dts;
|
int64_t ts = use_pts ? pkt->pts : pkt->dts;
|
||||||
|
AVRational tb = sti->pub.time_base;
|
||||||
|
|
||||||
if (ts == AV_NOPTS_VALUE)
|
if (ts == AV_NOPTS_VALUE)
|
||||||
return;
|
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 ||
|
if (ts < 0 ||
|
||||||
ts > 0 && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
|
ts > 0 && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) {
|
||||||
for (unsigned i = 0; i < s->nb_streams; i++) {
|
for (unsigned i = 0; i < s->nb_streams; i++) {
|
||||||
AVStream *const st2 = s->streams[i];
|
AVStream *const st2 = s->streams[i];
|
||||||
FFStream *const sti2 = ffstream(st2);
|
FFStream *const sti2 = ffstream(st2);
|
||||||
sti2->mux_ts_offset = av_rescale_q_rnd(-ts,
|
sti2->mux_ts_offset = av_rescale_q_rnd(-ts, tb,
|
||||||
sti->pub.time_base,
|
|
||||||
st2->time_base,
|
st2->time_base,
|
||||||
AV_ROUND_UP);
|
AV_ROUND_UP);
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,6 @@ fate-matroska-dovi-write-config8: CMD = transcode mov $(TARGET_SAMPLES)/hevc/dv8
|
|||||||
# the first packet (with the overall lowest dts) is a video packet,
|
# 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
|
# whereas an audio packet to be muxed later has the overall lowest pts
|
||||||
# which happens to be negative and therefore needs to be shifted.
|
# 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 pts).
|
|
||||||
# (-ss 1.09 ensures that a video frame has the lowest dts of all packets;
|
# (-ss 1.09 ensures that a video frame has the lowest dts of all packets;
|
||||||
# yet there is an audio packet with the overall lowest pts. output_ts_offset
|
# yet there is an audio packet with the overall lowest pts. output_ts_offset
|
||||||
# makes the pts of the audio packet, but not the leading video packet negative
|
# makes the pts of the audio packet, but not the leading video packet negative
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
90cf5a330659140d47ec11208f525908 *tests/data/fate/matroska-avoid-negative-ts.matroska
|
804842437b2be0a1604ce33c6b08c800 *tests/data/fate/matroska-avoid-negative-ts.matroska
|
||||||
973070 tests/data/fate/matroska-avoid-negative-ts.matroska
|
973070 tests/data/fate/matroska-avoid-negative-ts.matroska
|
||||||
#extradata 0: 22, 0x2885037c
|
#extradata 0: 22, 0x2885037c
|
||||||
#tb 0: 1/1000
|
#tb 0: 1/1000
|
||||||
|
Loading…
Reference in New Issue
Block a user