From c59569ca9426fef455edabfa648cb2ff678c1640 Mon Sep 17 00:00:00 2001 From: Andreas Hakon Date: Fri, 19 Apr 2019 09:32:33 +0100 Subject: [PATCH] libavformat: fix copyts and muxrate in mpegts muxer v2 When using "-copyts" and "-muxrate" with the mpegts muxer the muxing fails because the member "first_pcr" of the MpegTSWrite struct isn't initialized with a correct timestamp. The behaviour of the error is an infinite loop created in the function mpegts_write_pes() because the code never writes PES packets. This patch resolves the problem initializing the "first_pcr" with a value derived from the first DTS value seen. Signed-off-by: Andreas Hakon --- libavformat/mpegtsenc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index fc0ea22..858b0d7 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -971,6 +971,9 @@ static int mpegts_init(AVFormatContext *s) if (ts->copyts < 1) ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); + else + ts->first_pcr = AV_NOPTS_VALUE; + } else { /* Arbitrary values, PAT/PMT will also be written on video key frames */ ts->sdt_packet_period = 200; @@ -1186,12 +1189,16 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, int64_t pcr = -1; /* avoid warning */ int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; + int last_payload_size = 0; av_assert0(ts_st->payload != buf || st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO); if (ts->flags & MPEGTS_FLAG_PAT_PMT_AT_FRAMES && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { force_pat = 1; } + if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && ts->first_pcr == AV_NOPTS_VALUE) + ts->first_pcr = (dts * 300) - av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); + is_start = 1; while (payload_size > 0) { retransmit_si_info(s, force_pat, dts); @@ -1209,12 +1216,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, } if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && - (dts - get_pcr(ts, s->pb) / 300) > delay) { + last_payload_size != payload_size && (dts - get_pcr(ts, s->pb) / 300) > delay) { /* pcr insert gets priority over null packet insert */ if (write_pcr) mpegts_insert_pcr_only(s, st); else mpegts_insert_null_packet(s); + last_payload_size = payload_size; /* recalculate write_pcr and possibly retransmit si_info */ continue; } -- 1.7.10.4