1 diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
2 --- a/libavformat/mpegtsenc.c
3 +++ b/libavformat/mpegtsenc.c
4 @@ -56,7 +56,8 @@ typedef struct MpegTSService {
5 int sid; /* service ID */
7 uint8_t provider_name[256];
9 + int pcr_sid; /* stream triggering pcr writes */
10 + int pcr_pid; /* pid of pcr stream */
14 @@ -79,10 +80,8 @@ typedef struct MpegTSWrite {
15 int64_t sdt_period; /* SDT period in PCR time base */
16 int64_t pat_period; /* PAT/PMT period in PCR time base */
23 + int64_t pcr, first_pcr, next_pcr, delay;
24 int mux_rate; ///< set to 1 when VBR
27 @@ -94,8 +93,8 @@ typedef struct MpegTSWrite {
34 #define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01
35 #define MPEGTS_FLAG_AAC_LATM 0x02
36 #define MPEGTS_FLAG_PAT_PMT_AT_FRAMES 0x04
37 @@ -104,11 +103,11 @@ typedef struct MpegTSWrite {
41 - int64_t pat_period_us;
42 - int64_t sdt_period_us;
43 - int64_t last_pat_ts;
44 + double pcr_period_ms;
45 + double sdt_period_ms;
46 + double pat_period_ms;
49 + int64_t last_pat_ts;
50 int omit_video_pes_length;
53 @@ -217,10 +216,10 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id,
54 #define DEFAULT_PROVIDER_NAME "FFmpeg"
55 #define DEFAULT_SERVICE_NAME "Service"
57 -/* we retransmit the SI info at this rate */
58 +/* we retransmit the SI info at this rate (ms) */
59 #define SDT_RETRANS_TIME 500
60 #define PAT_RETRANS_TIME 100
61 -#define PCR_RETRANS_TIME 20
62 +#define PCR_RETRANS_TIME 50
64 typedef struct MpegTSWriteStream {
65 int pid; /* stream associated pid */
66 @@ -234,7 +233,7 @@ typedef struct MpegTSWriteStream {
69 AVFormatContext *amux;
71 + MpegTSService *service;
72 int64_t pcr_period; /* PCR period in PCR time base */
75 @@ -713,18 +712,11 @@ invalid:
79 -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb)
81 - return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) +
85 static void write_packet(AVFormatContext *s, const uint8_t *packet)
87 MpegTSWrite *ts = s->priv_data;
89 - int64_t pcr = get_pcr(s->priv_data, s->pb);
90 - uint32_t tp_extra_header = pcr % 0x3fffffff;
91 + uint32_t tp_extra_header = ts->pcr % 0x3fffffff;
92 tp_extra_header = AV_RB32(&tp_extra_header);
93 avio_write(s->pb, (unsigned char *) &tp_extra_header,
94 sizeof(tp_extra_header));
95 @@ -763,6 +755,7 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,
96 service->pmt.pid = ts->pmt_start_pid + ts->nb_services;
98 service->pcr_pid = 0x1fff;
99 + service->pcr_sid = 0x1fff;
100 if (encode_str8(service->provider_name, provider_name) < 0 ||
101 encode_str8(service->name, service_name) < 0) {
102 av_log(s, AV_LOG_ERROR, "Too long service or provider name\n");
103 @@ -788,30 +781,32 @@ static void enable_pcr_generation_for_stream(AVFormatContext *s, AVStream *pcr_s
104 MpegTSWrite *ts = s->priv_data;
105 MpegTSWriteStream *ts_st = pcr_st->priv_data;
107 - if (ts->mux_rate > 1 || ts->pcr_period_ms >= 0) {
108 - int pcr_period_ms = ts->pcr_period_ms == -1 ? PCR_RETRANS_TIME : ts->pcr_period_ms;
109 - ts_st->pcr_period = av_rescale(pcr_period_ms, PCR_TIME_BASE, 1000);
111 + int64_t pcr_period = -1;
112 + if (ts->pcr_period_ms >= 0)
113 + pcr_period = av_rescale(ts->pcr_period_ms, PCR_TIME_BASE, 1000);
114 + else if (ts->mux_rate == 1) {
115 /* By default, for VBR we select the highest multiple of frame duration which is less than 100 ms. */
116 int64_t frame_period = 0;
117 if (pcr_st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
118 int frame_size = av_get_audio_frame_duration2(pcr_st->codecpar, 0);
120 + if (frame_size > 0)
121 + frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
123 av_log(s, AV_LOG_WARNING, "frame size not set\n");
126 - frame_period = av_rescale_rnd(frame_size, PCR_TIME_BASE, pcr_st->codecpar->sample_rate, AV_ROUND_UP);
127 } else if (pcr_st->avg_frame_rate.num) {
128 frame_period = av_rescale_rnd(pcr_st->avg_frame_rate.den, PCR_TIME_BASE, pcr_st->avg_frame_rate.num, AV_ROUND_UP);
130 - if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10)
131 - ts_st->pcr_period = frame_period * (PCR_TIME_BASE / 10 / frame_period);
133 - ts_st->pcr_period = 1;
134 + if (frame_period > 0 && frame_period <= PCR_TIME_BASE / 10) {
135 + int pcr_frames = (PCR_TIME_BASE / 10) / frame_period;
136 + if( pcr_frames > 0 )
137 + pcr_period = frame_period * pcr_frames;
141 + if( pcr_period < 0 )
142 + pcr_period = av_rescale(PCR_RETRANS_TIME, PCR_TIME_BASE, 1000);
143 + ts_st->pcr_period = pcr_period;
144 // output a PCR as soon as possible
145 - ts_st->last_pcr = ts->first_pcr - ts_st->pcr_period;
146 + ts_st->last_pcr = ts->first_pcr - pcr_period;
149 static void select_pcr_streams(AVFormatContext *s)
150 @@ -823,22 +818,32 @@ static void select_pcr_streams(AVFormatContext *s)
151 AVStream *pcr_st = NULL;
152 AVProgram *program = service->program;
153 int nb_streams = program ? program->nb_stream_indexes : s->nb_streams;
155 + /* find first video stream, or just use first stream */
156 for (int j = 0; j < nb_streams; j++) {
157 AVStream *st = s->streams[program ? program->stream_index[j] : j];
159 - pcr_st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
161 + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
167 + if (!pcr_st && s->nb_streams > 0)
168 + pcr_st = s->streams[0];
170 MpegTSWriteStream *ts_st = pcr_st->priv_data;
171 - service->pcr_pid = ts_st->pid;
172 + service->pcr_sid = ts_st->pid; /* stream id for pcr writes */
173 + service->pcr_pid = ts->m2ts_mode > 1 ? /* pcr pid */
174 + 0x1000 + ts->service_id : ts_st->pid;
175 enable_pcr_generation_for_stream(s, pcr_st);
176 av_log(s, AV_LOG_VERBOSE, "service %i using PCR in pid=%i, pcr_period=%"PRId64"ms\n",
177 service->sid, service->pcr_pid, av_rescale(ts_st->pcr_period, 1000, PCR_TIME_BASE));
178 + for (int j = 0; j < nb_streams; j++) {
179 + AVStream *st = s->streams[program ? program->stream_index[j] : j];
180 + MpegTSWriteStream *ts_st = st->priv_data;
181 + ts_st->service = service;
183 + if (service->pmt.pid == service->pcr_pid) {
184 + av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", service->pcr_pid);
189 @@ -860,6 +865,15 @@ static int mpegts_init(AVFormatContext *s)
191 if (s->max_delay < 0) /* Not set by the caller */
193 + ts->delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
195 + if (ts->m2ts_mode == -1) {
196 + if (av_match_ext(s->url, "m2ts")) {
203 // round up to a whole number of TS packets
204 ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14;
205 @@ -920,14 +934,11 @@ static int mpegts_init(AVFormatContext *s)
207 /* MPEG pid values < 16 are reserved. Applications which set st->id in
208 * this range are assigned a calculated pid. */
210 - ts_st->pid = ts->start_pid + i;
212 - ts_st->pid = st->id;
214 - if (ts_st->pid >= 0x1FFF) {
215 + ts_st->pid = ts->start_pid >= 0 ? ts->start_pid + i :
216 + st->id >= 16 ? st->id : FIRST_OTHER_PID + i;
217 + if (ts_st->pid < 16 || ts_st->pid >= 0x1FFF) {
218 av_log(s, AV_LOG_ERROR,
219 - "Invalid stream id %d, must be less than 8191\n", st->id);
220 + "Invalid stream id %d, must be in 16...8191\n", ts_st->pid);
221 ret = AVERROR(EINVAL);
224 @@ -998,8 +1009,8 @@ static int mpegts_init(AVFormatContext *s)
226 ts->last_pat_ts = AV_NOPTS_VALUE;
227 ts->last_sdt_ts = AV_NOPTS_VALUE;
228 - ts->pat_period = av_rescale(ts->pat_period_us, PCR_TIME_BASE, AV_TIME_BASE);
229 - ts->sdt_period = av_rescale(ts->sdt_period_us, PCR_TIME_BASE, AV_TIME_BASE);
230 + ts->pat_period = av_rescale(ts->pat_period_ms, PCR_TIME_BASE, 1000);
231 + ts->sdt_period = av_rescale(ts->sdt_period_ms, PCR_TIME_BASE, 1000);
233 if (ts->mux_rate == 1)
234 av_log(s, AV_LOG_VERBOSE, "muxrate VBR, ");
235 @@ -1022,20 +1033,16 @@ static void retransmit_si_info(AVFormatContext *s, int force_pat, int force_sdt,
237 MpegTSWrite *ts = s->priv_data;
240 - if ((pcr != AV_NOPTS_VALUE && ts->last_sdt_ts == AV_NOPTS_VALUE) ||
241 - (pcr != AV_NOPTS_VALUE && pcr - ts->last_sdt_ts >= ts->sdt_period) ||
244 - if (pcr != AV_NOPTS_VALUE)
245 - ts->last_sdt_ts = FFMAX(pcr, ts->last_sdt_ts);
246 + if (force_sdt || (ts->sdt_period >= 0 && pcr != AV_NOPTS_VALUE &&
247 + (ts->last_sdt_ts == AV_NOPTS_VALUE || (pcr - ts->last_sdt_ts >= ts->sdt_period)) )) {
248 + if (pcr > ts->last_sdt_ts)
249 + ts->last_sdt_ts = pcr;
252 - if ((pcr != AV_NOPTS_VALUE && ts->last_pat_ts == AV_NOPTS_VALUE) ||
253 - (pcr != AV_NOPTS_VALUE && pcr - ts->last_pat_ts >= ts->pat_period) ||
255 - if (pcr != AV_NOPTS_VALUE)
256 - ts->last_pat_ts = FFMAX(pcr, ts->last_pat_ts);
257 + if (force_pat || (ts->pat_period >= 0 && pcr != AV_NOPTS_VALUE &&
258 + (ts->last_pat_ts == AV_NOPTS_VALUE || (pcr - ts->last_pat_ts >= ts->pat_period)) )) {
259 + if (pcr > ts->last_pat_ts)
260 + ts->last_pat_ts = pcr;
262 for (i = 0; i < ts->nb_services; i++)
263 mpegts_write_pmt(s, ts->services[i]);
264 @@ -1076,13 +1083,14 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
266 MpegTSWrite *ts = s->priv_data;
267 MpegTSWriteStream *ts_st = st->priv_data;
268 + uint32_t pcr_pid = ts_st->service->pcr_pid;
270 uint8_t buf[TS_PACKET_SIZE];
274 - *q++ = ts_st->pid >> 8;
276 + *q++ = pcr_pid >> 8;
278 *q++ = 0x20 | ts_st->cc; /* Adaptation only */
279 /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */
280 *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */
281 @@ -1093,7 +1101,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st)
284 /* PCR coded into 6 bytes */
285 - q += write_pcr_bits(q, get_pcr(ts, s->pb));
286 + q += write_pcr_bits(q, ts->pcr);
289 memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
290 @@ -1161,7 +1169,6 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
292 int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;
293 int afc_len, stuffing_len;
294 - int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
295 int force_pat = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;
298 @@ -1178,67 +1185,46 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
301 while (payload_size > 0) {
302 - int64_t pcr = AV_NOPTS_VALUE;
303 - if (ts->mux_rate > 1)
304 - pcr = get_pcr(ts, s->pb);
305 - else if (dts != AV_NOPTS_VALUE)
306 - pcr = (dts - delay) * 300;
307 + ts->pcr = ts->first_pcr + (ts->mux_rate == 1 ?
308 + (dts == AV_NOPTS_VALUE ? 0 : (dts - ts->delay) * 300) :
309 + // add 11, pcr references the last byte of program clock reference base
310 + av_rescale(avio_tell(s->pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate));
312 - retransmit_si_info(s, force_pat, force_sdt, pcr);
313 + retransmit_si_info(s, force_pat, force_sdt, ts->pcr);
318 - if (ts->mux_rate > 1) {
319 - /* Send PCR packets for all PCR streams if needed */
320 - pcr = get_pcr(ts, s->pb);
321 - if (pcr >= ts->next_pcr) {
322 - int64_t next_pcr = INT64_MAX;
323 - for (int i = 0; i < s->nb_streams; i++) {
324 - /* Make the current stream the last, because for that we
325 - * can insert the pcr into the payload later */
326 - int st2_index = i < st->index ? i : (i + 1 == s->nb_streams ? st->index : i + 1);
327 - AVStream *st2 = s->streams[st2_index];
328 - MpegTSWriteStream *ts_st2 = st2->priv_data;
329 - if (ts_st2->pcr_period) {
330 - if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) {
331 - ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period);
333 - mpegts_insert_pcr_only(s, st2);
334 - pcr = get_pcr(ts, s->pb);
339 - next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period);
342 - ts->next_pcr = next_pcr;
344 - if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) {
345 - /* pcr insert gets priority over null packet insert */
347 - mpegts_insert_pcr_only(s, st);
349 - mpegts_insert_null_packet(s);
350 - /* recalculate write_pcr and possibly retransmit si_info */
353 - } else if (ts_st->pcr_period && pcr != AV_NOPTS_VALUE) {
354 - if (pcr - ts_st->last_pcr >= ts_st->pcr_period && is_start) {
355 - ts_st->last_pcr = FFMAX(pcr - ts_st->pcr_period, ts_st->last_pcr + ts_st->pcr_period);
358 + if (ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid &&
359 + ts->pcr - ts_st->last_pcr >= ts_st->pcr_period) {
360 + ts_st->last_pcr = ts->pcr;
363 + if (write_pcr && ts_st->service->pcr_sid != ts_st->service->pcr_pid) {
364 + /* pcr is on a seperate stream */
365 + mpegts_insert_pcr_only(s, st);
369 + if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
370 + (dts - ts->pcr / 300) > ts->delay) {
371 + /* pcr insert gets priority over null packet insert */
373 + mpegts_insert_pcr_only(s, st);
375 + mpegts_insert_null_packet(s);
376 + /* recalculate write_pcr and possibly retransimit si_info */
380 /* prepare packet header */
383 val = ts_st->pid >> 8;
384 - if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
388 + if (ts->m2ts_mode && st->codecpar->codec_id == AV_CODEC_ID_AC3)
392 ts_st->cc = ts_st->cc + 1 & 0xf;
393 @@ -1250,7 +1236,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
395 if (key && is_start && pts != AV_NOPTS_VALUE) {
396 // set Random Access for key frames
397 - if (ts_st->pcr_period)
398 + if ( ts_st->pcr_period > 0 && ts_st->pid == ts_st->service->pcr_sid )
400 set_af_flag(buf, 0x40);
401 q = get_ts_payload_start(buf);
402 @@ -1258,10 +1244,9 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
404 set_af_flag(buf, 0x10);
405 q = get_ts_payload_start(buf);
406 - // add 11, pcr references the last byte of program clock reference base
407 - if (dts != AV_NOPTS_VALUE && dts < pcr / 300)
408 + if (dts != AV_NOPTS_VALUE && dts < ts->pcr / 300)
409 av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");
410 - extend_af(buf, write_pcr_bits(q, pcr));
411 + extend_af(buf, write_pcr_bits(q, ts->pcr));
412 q = get_ts_payload_start(buf);
415 @@ -1362,11 +1347,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
418 if (pts != AV_NOPTS_VALUE) {
419 - write_pts(q, flags >> 6, pts);
420 + int64_t ts_pts = pts + ts->ts_offset;
421 + write_pts(q, flags >> 6, ts_pts);
424 if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {
425 - write_pts(q, 1, dts);
426 + int64_t ts_dts = dts + ts->ts_offset;
427 + write_pts(q, 1, ts_dts);
430 if (pes_extension && st->codecpar->codec_id == AV_CODEC_ID_DIRAC) {
431 @@ -1536,7 +1523,6 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
432 uint8_t *data = NULL;
433 MpegTSWrite *ts = s->priv_data;
434 MpegTSWriteStream *ts_st = st->priv_data;
435 - const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) * 2;
436 const int64_t max_audio_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE) / 2;
437 int64_t dts = pkt->dts, pts = pkt->pts;
438 int opus_samples = 0;
439 @@ -1552,9 +1538,9 @@ static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
441 if (ts->copyts < 1) {
442 if (pts != AV_NOPTS_VALUE)
444 + pts += ts->delay * 2;
445 if (dts != AV_NOPTS_VALUE)
447 + dts += ts->delay * 2;
450 if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) {
451 @@ -1904,10 +1890,13 @@ static const AVOption options[] = {
452 { .i64 = 0x1000 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
453 { "mpegts_start_pid", "Set the first pid.",
454 offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT,
455 - { .i64 = 0x0100 }, FIRST_OTHER_PID, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
456 + { .i64 = -1 }, -1, LAST_OTHER_PID, AV_OPT_FLAG_ENCODING_PARAM },
457 { "mpegts_m2ts_mode", "Enable m2ts mode.",
458 - offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_BOOL,
459 - { .i64 = -1 }, -1, 1, AV_OPT_FLAG_ENCODING_PARAM },
460 + offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT,
461 + { .i64 = -1 }, -1, 2, AV_OPT_FLAG_ENCODING_PARAM },
462 + { "mpegts_pcr_offset", "clock offset.",
463 + offsetof(MpegTSWrite, ts_offset), AV_OPT_TYPE_BOOL,
464 + { .i64 = 0 }, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
466 offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT,
467 { .i64 = 1 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
468 @@ -1941,15 +1930,15 @@ static const AVOption options[] = {
469 { "omit_video_pes_length", "Omit the PES packet length for video packets",
470 offsetof(MpegTSWrite, omit_video_pes_length), AV_OPT_TYPE_BOOL,
471 { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
472 - { "pcr_period", "PCR retransmission time in milliseconds",
473 - offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_INT,
474 - { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
475 - { "pat_period", "PAT/PMT retransmission time limit in seconds",
476 - offsetof(MpegTSWrite, pat_period_us), AV_OPT_TYPE_DURATION,
477 - { .i64 = PAT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
478 - { "sdt_period", "SDT retransmission time limit in seconds",
479 - offsetof(MpegTSWrite, sdt_period_us), AV_OPT_TYPE_DURATION,
480 - { .i64 = SDT_RETRANS_TIME * 1000LL }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM },
481 + { "pcr_period", "PCR retransmission time limit in msecs",
482 + offsetof(MpegTSWrite, pcr_period_ms), AV_OPT_TYPE_DOUBLE,
483 + { .dbl = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
484 + { "pat_period", "PAT/PMT retransmission time limit in msecs",
485 + offsetof(MpegTSWrite, pat_period_ms), AV_OPT_TYPE_DOUBLE,
486 + { .dbl = PAT_RETRANS_TIME }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
487 + { "sdt_period", "SDT retransmission time limit in msecs",
488 + offsetof(MpegTSWrite, sdt_period_ms), AV_OPT_TYPE_DOUBLE,
489 + { .dbl = SDT_RETRANS_TIME }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },