From 7f9f1a992615e15121b661d4cd1b9c1e32e1c894 Mon Sep 17 00:00:00 2001 From: Andreas Hakon Date: Thu, 25 Apr 2019 09:49:29 +0100 Subject: [PATCH] libavformat/mpegtsenc: enforce PCR packets without payload This patch provides a new optional parameter for the mpegtsenc muxer. The parameter "-pcr_without_payload" can be used to override the default behaviour of writing PCR timestamps in TS packets with payload. Using a value greater than 0 all TS packets carrying PCR timestamps will be forced to have an empty payload. Otherwise (with 0) the regular behaviour is used and PCR packets can have payload. Futhermore with a value greater than 1 the packet with the PCR will be repeated the number of times indicated. The default value is "-pcr_without_payload 0", which corresponds to the current behaviour. This can be handy for many reasons. Signed-off-by: Andreas Hakon --- doc/muxers.texi | 5 +++++ libavformat/mpegtsenc.c | 18 ++++++++++++++---- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 83ae017..9acdee3 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1564,6 +1564,11 @@ Set a constant muxrate. Default is VBR. @item pes_payload_size @var{integer} Set minimum PES packet payload in bytes. Default is @code{2930}. +@item pcr_without_payload @var{integer} +Generates PCR packets without payload. When the value is greater than 1 +it repeats the PCR packet N times. With a 0 value it generates regular +PCR packets with payload. Default is @code{0}. + @item mpegts_flags @var{flags} Set mpegts flags. Accepts the following options: @table @samp diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index fc0ea22..0cc42cd 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -97,6 +97,7 @@ typedef struct MpegTSWrite { int pmt_start_pid; int start_pid; int m2ts_mode; + int pcr_repetition; int reemit_pat_pmt; // backward compatibility @@ -1093,12 +1094,13 @@ static void mpegts_insert_null_packet(AVFormatContext *s) } /* Write a single transport stream packet with a PCR and no payload */ -static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) +static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st, int repetition) { MpegTSWrite *ts = s->priv_data; MpegTSWriteStream *ts_st = st->priv_data; uint8_t *q; uint8_t buf[TS_PACKET_SIZE]; + int i; q = buf; *q++ = 0x47; @@ -1119,7 +1121,9 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) /* stuffing bytes */ memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); mpegts_prefix_m2ts_header(s); - avio_write(s->pb, buf, TS_PACKET_SIZE); + for (i=0; ipb, buf, TS_PACKET_SIZE); + } } static void write_pts(uint8_t *q, int fourbits, int64_t pts) @@ -1212,12 +1216,15 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, (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); + mpegts_insert_pcr_only(s, st, ts->pcr_repetition < 1 ? 1 : ts->pcr_repetition); else mpegts_insert_null_packet(s); /* recalculate write_pcr and possibly retransmit si_info */ continue; } + if (write_pcr && ts->pcr_repetition > 0) { + mpegts_insert_pcr_only(s, st, ts->pcr_repetition); + } /* prepare packet header */ q = buf; @@ -1241,7 +1248,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, set_af_flag(buf, 0x40); q = get_ts_payload_start(buf); } - if (write_pcr) { + if (write_pcr && ts->pcr_repetition == 0) { set_af_flag(buf, 0x10); q = get_ts_payload_start(buf); // add 11, pcr references the last byte of program clock reference base @@ -1926,6 +1933,9 @@ static const AVOption options[] = { { "pes_payload_size", "Minimum PES packet payload in bytes", offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, { .i64 = DEFAULT_PES_PAYLOAD_SIZE }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, + { "pcr_without_payload", "Generate PCR packets without payload", + offsetof(MpegTSWrite, pcr_repetition), AV_OPT_TYPE_INT, + { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, { "mpegts_flags", "MPEG-TS muxing flags", offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" }, -- 1.7.10.4