1 --- a/libavformat/mpegtsenc.c 2016-09-30 19:12:42.000000000 -0600
2 +++ b/libavformat/mpegtsenc.c 2017-01-25 17:25:58.720017593 -0700
4 int sid; /* service ID */
8 + int pcr_sid, pcr_pid;
10 int pcr_packet_period;
21 int reemit_pat_pmt; // backward compatibility
24 service->pmt.pid = ts->pmt_start_pid + ts->nb_services;
26 service->pcr_pid = 0x1fff;
27 + service->pcr_sid = 0x1fff;
28 service->provider_name = av_strdup(provider_name);
29 service->name = av_strdup(name);
30 if (!service->provider_name || !service->name)
32 static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
34 return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
36 + ts->first_pcr + ts->pcr_offset;
39 static void mpegts_prefix_m2ts_header(AVFormatContext *s)
41 if (s->max_delay < 0) /* Not set by the caller */
44 + if (ts->m2ts_mode == -1) {
45 + if (av_match_ext(s->filename, "m2ts")) {
52 // round up to a whole number of TS packets
53 ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
56 service->program = program;
59 + if (ts->m2ts_mode > 1)
60 + service->pmt.pid = 0x00ff + ts->service_id;
62 ts->pat.pid = PAT_PID;
63 /* Initialize at 15 so that it wraps and is equal to 0 for the
66 /* update PCR pid by using the first video stream */
67 if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
68 - service->pcr_pid == 0x1fff) {
69 - service->pcr_pid = ts_st->pid;
70 + service->pcr_sid == 0x1fff)
74 if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
75 st->codecpar->extradata_size > 0) {
80 /* if no video stream, use the first stream as PCR */
81 - if (service->pcr_pid == 0x1fff && s->nb_streams > 0) {
82 - pcr_st = s->streams[0];
83 - ts_st = pcr_st->priv_data;
84 - service->pcr_pid = ts_st->pid;
86 - ts_st = pcr_st->priv_data;
87 + if (!pcr_st && s->nb_streams > 0)
88 + pcr_st = s->streams[0];
90 + av_log(s, AV_LOG_ERROR, "no streams\n");
91 + ret = AVERROR(EINVAL);
94 + ts_st = pcr_st->priv_data;
95 + if (service->pcr_sid == 0x1fff)
96 + service->pcr_sid = ts_st->pid;
97 + if (service->pcr_pid == 0x1fff)
98 + service->pcr_pid = ts->m2ts_mode > 1 ?
99 + 0x1000 + ts->service_id : service->pcr_sid ;
100 + if (service->pmt.pid == service->pcr_pid) {
101 + av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid);
102 + ret = AVERROR(EINVAL);
106 if (ts->mux_rate > 1) {
107 service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period /
108 @@ -989,14 +1013,6 @@
109 service->pcr_packet_period,
110 ts->sdt_packet_period, ts->pat_packet_period);
112 - if (ts->m2ts_mode == -1) {
113 - if (av_match_ext(s->filename, "m2ts")) {
123 @@ -1010,9 +1026,9 @@
124 MpegTSWrite *ts = s->priv_data;
127 - if (++ts->sdt_packet_count == ts->sdt_packet_period ||
128 + if ( ts->sdt_period >= 0 && (++ts->sdt_packet_count == ts->sdt_packet_period ||
129 (dts != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
130 - (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0)
131 + (dts != AV_NOPTS_VALUE && dts - ts->last_sdt_ts >= ts->sdt_period*90000.0))
133 ts->sdt_packet_count = 0;
134 if (dts != AV_NOPTS_VALUE)
135 @@ -1067,13 +1083,14 @@
137 MpegTSWrite *ts = s->priv_data;
138 MpegTSWriteStream *ts_st = st->priv_data;
139 + uint32_t pcr_pid = ts_st->service->pcr_pid;
141 uint8_t buf[TS_PACKET_SIZE];
145 - *q++ = ts_st->pid >> 8;
147 + *q++ = pcr_pid >> 8;
149 *q++ = 0x20 | ts_st->cc; /* Adaptation only */
150 /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
151 *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
152 @@ -1148,7 +1165,7 @@
153 uint8_t buf[TS_PACKET_SIZE];
155 int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
156 - int afc_len, stuffing_len;
157 + int afc_len, stuffing_len, write_null;
158 int64_t pcr = -1; /* avoid warning */
159 int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
160 int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
161 @@ -1163,8 +1180,8 @@
162 retransmit_si_info(s, force_pat, dts);
166 - if (ts_st->pid == ts_st->service->pcr_pid) {
167 + write_pcr = write_null = 0;
168 + if (ts_st->pid == ts_st->service->pcr_sid) {
169 if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames
170 ts_st->service->pcr_packet_count++;
171 if (ts_st->service->pcr_packet_count >=
172 @@ -1173,15 +1190,17 @@
177 if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
178 - (dts - get_pcr(ts, s->pb) / 300) > delay) {
179 - /* pcr insert gets priority over null packet insert */
181 - mpegts_insert_pcr_only(s, st);
183 - mpegts_insert_null_packet(s);
184 - /* recalculate write_pcr and possibly retransmit si_info */
185 + (dts - get_pcr(ts, s->pb) / 300) > delay) {
188 + /* pcr insert gets priority over null packet insert */
189 + if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
190 + mpegts_insert_pcr_only(s, st);
194 + mpegts_insert_null_packet(s);
198 @@ -1191,13 +1210,17 @@
199 val = ts_st->pid >> 8;
202 + if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
203 + st->codecpar->codec_id == AV_CODEC_ID_AC3 &&
208 ts_st->cc = ts_st->cc + 1 & 0xf;
209 *q++ = 0x10 | ts_st->cc; // payload indicator + CC
210 if (key && is_start && pts != AV_NOPTS_VALUE) {
211 // set Random Access for key frames
212 - if (ts_st->pid == ts_st->service->pcr_pid)
213 + if (ts_st->pid == ts_st->service->pcr_sid)
215 set_af_flag(buf, 0x40);
216 q = get_ts_payload_start(buf);
217 @@ -1310,11 +1333,13 @@
220 if (pts != AV_NOPTS_VALUE) {
221 - write_pts(q, flags >> 6, pts);
222 + int64_t ts_pts = pts + ts->pcr_offset;
223 + write_pts(q, flags >> 6, ts_pts);
226 if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
227 - write_pts(q, 1, dts);
228 + int64_t ts_dts = dts + ts->pcr_offset;
229 + write_pts(q, 1, ts_dts);
232 if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
233 @@ -1838,12 +1863,18 @@
234 { "mpegts_pmt_start_pid", "Set the first pid of the PMT.",
235 offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT,
236 { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
237 + { "mpegts_pcr_start_pid", "Set the first pid of the PCR.",
238 + offsetof(MpegTSWrite, pcr_start_pid), AV_OPT_TYPE_INT,
239 + { .i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM },
240 { "mpegts_start_pid", "Set the first pid.",
241 offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
242 { .i64 = 0x0100 }, 0x0020, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM },
243 { "mpegts_m2ts_mode", "Enable m2ts mode.",
244 offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
245 - { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
246 + { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
247 + { "mpegts_pcr_offset", "clock offset.",
248 + offsetof(MpegTSWrite, pcr_offset), AV_OPT_TYPE_BOOL,
249 + { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
251 offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
252 { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
253 @@ -1886,7 +1917,7 @@
254 { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
255 { "sdt_period", "SDT retransmission time limit in seconds",
256 offsetof(MpegTSWrite, sdt_period), AV_OPT_TYPE_DOUBLE,
257 - { .dbl = INT_MAX }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
258 + { .dbl = INT_MAX }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },