Commit 34da54fd authored by Michael Niedermayer's avatar Michael Niedermayer

avformat/mpegtsenc: Support a user specified PAT/PMT period

Can be used to fix Ticket3714
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent a9c1545a
...@@ -759,6 +759,8 @@ Set a constant muxrate (default VBR). ...@@ -759,6 +759,8 @@ Set a constant muxrate (default VBR).
@item -pcr_period @var{numer} @item -pcr_period @var{numer}
Override the default PCR retransmission time (default 20ms), ignored Override the default PCR retransmission time (default 20ms), ignored
if variable muxrate is selected. if variable muxrate is selected.
@item pat_period @var{number}
Maximal time in seconds between PAT/PMT tables.
@item -pes_payload_size @var{number} @item -pes_payload_size @var{number}
Set minimum PES packet payload in bytes. Set minimum PES packet payload in bytes.
@item -mpegts_flags @var{flags} @item -mpegts_flags @var{flags}
......
...@@ -102,6 +102,8 @@ typedef struct MpegTSWrite { ...@@ -102,6 +102,8 @@ typedef struct MpegTSWrite {
int flags; int flags;
int copyts; int copyts;
int tables_version; int tables_version;
float pat_period;
int64_t last_pat_ts;
int omit_video_pes_length; int omit_video_pes_length;
} MpegTSWrite; } MpegTSWrite;
...@@ -784,6 +786,12 @@ static int mpegts_write_header(AVFormatContext *s) ...@@ -784,6 +786,12 @@ static int mpegts_write_header(AVFormatContext *s)
service->pcr_packet_period = 1; service->pcr_packet_period = 1;
} }
ts->last_pat_ts = AV_NOPTS_VALUE;
// The user specified a period, use only it
if (ts->pat_period < INT_MAX/2) {
ts->pat_packet_period = INT_MAX;
}
// output a PCR as soon as possible // output a PCR as soon as possible
service->pcr_packet_count = service->pcr_packet_period; service->pcr_packet_count = service->pcr_packet_period;
ts->pat_packet_count = ts->pat_packet_period - 1; ts->pat_packet_count = ts->pat_packet_period - 1;
...@@ -834,7 +842,7 @@ fail: ...@@ -834,7 +842,7 @@ fail:
} }
/* send SDT, PAT and PMT tables regulary */ /* send SDT, PAT and PMT tables regulary */
static void retransmit_si_info(AVFormatContext *s, int force_pat) static void retransmit_si_info(AVFormatContext *s, int force_pat, int64_t dts)
{ {
MpegTSWrite *ts = s->priv_data; MpegTSWrite *ts = s->priv_data;
int i; int i;
...@@ -843,8 +851,13 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat) ...@@ -843,8 +851,13 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat)
ts->sdt_packet_count = 0; ts->sdt_packet_count = 0;
mpegts_write_sdt(s); mpegts_write_sdt(s);
} }
if (++ts->pat_packet_count == ts->pat_packet_period || force_pat) { if (++ts->pat_packet_count == ts->pat_packet_period ||
(dts != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
(dts != AV_NOPTS_VALUE && dts - ts->last_pat_ts >= ts->pat_period*90000.0) ||
force_pat) {
ts->pat_packet_count = 0; ts->pat_packet_count = 0;
if (dts != AV_NOPTS_VALUE)
ts->last_pat_ts = FFMAX(dts, ts->last_pat_ts);
mpegts_write_pat(s); mpegts_write_pat(s);
for (i = 0; i < ts->nb_services; i++) for (i = 0; i < ts->nb_services; i++)
mpegts_write_pmt(s, ts->services[i]); mpegts_write_pmt(s, ts->services[i]);
...@@ -979,7 +992,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ...@@ -979,7 +992,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
is_start = 1; is_start = 1;
while (payload_size > 0) { while (payload_size > 0) {
retransmit_si_info(s, force_pat); retransmit_si_info(s, force_pat, dts);
force_pat = 0; force_pat = 0;
write_pcr = 0; write_pcr = 0;
...@@ -1530,6 +1543,9 @@ static const AVOption options[] = { ...@@ -1530,6 +1543,9 @@ static const AVOption options[] = {
{ "pcr_period", "PCR retransmission time", { "pcr_period", "PCR retransmission time",
offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT, offsetof(MpegTSWrite, pcr_period), AV_OPT_TYPE_INT,
{ .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, { .i64 = PCR_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ "pat_period", "PAT/PMT retransmission time limit in seconds",
offsetof(MpegTSWrite, pat_period), AV_OPT_TYPE_FLOAT,
{ .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
{ NULL }, { NULL },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment