Signed-off-by: Fredrik Axelsson <fraxbe@gmail.com>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -75,6 +75,7 @@ typedef struct MpegTSWrite { |
75 | 75 |
|
76 | 76 |
int pmt_start_pid; |
77 | 77 |
int start_pid; |
78 |
+ int m2ts_mode; |
|
78 | 79 |
} MpegTSWrite; |
79 | 80 |
|
80 | 81 |
static const AVOption options[] = { |
... | ... |
@@ -88,6 +89,9 @@ static const AVOption options[] = { |
88 | 88 |
offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, |
89 | 89 |
{ "mpegts_start_pid", "Set the first pid.", |
90 | 90 |
offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM}, |
91 |
+ {"mpegts_m2ts_mode", "Enable m2ts mode.", |
|
92 |
+ offsetof(MpegTSWrite, m2ts_mode), FF_OPT_TYPE_INT, {.dbl = -1 }, |
|
93 |
+ -1,1, AV_OPT_FLAG_ENCODING_PARAM}, |
|
91 | 94 |
{ NULL }, |
92 | 95 |
}; |
93 | 96 |
|
... | ... |
@@ -434,9 +438,28 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts, |
434 | 434 |
return service; |
435 | 435 |
} |
436 | 436 |
|
437 |
+static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) |
|
438 |
+{ |
|
439 |
+ return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + |
|
440 |
+ ts->first_pcr; |
|
441 |
+} |
|
442 |
+ |
|
443 |
+static void mpegts_prefix_m2ts_header(AVFormatContext *s) |
|
444 |
+{ |
|
445 |
+ MpegTSWrite *ts = s->priv_data; |
|
446 |
+ if (ts->m2ts_mode) { |
|
447 |
+ int64_t pcr = get_pcr(s->priv_data, s->pb); |
|
448 |
+ uint32_t tp_extra_header = pcr % 0x3fffffff; |
|
449 |
+ tp_extra_header = AV_RB32(&tp_extra_header); |
|
450 |
+ avio_write(s->pb, (unsigned char *) &tp_extra_header, |
|
451 |
+ sizeof(tp_extra_header)); |
|
452 |
+ } |
|
453 |
+} |
|
454 |
+ |
|
437 | 455 |
static void section_write_packet(MpegTSSection *s, const uint8_t *packet) |
438 | 456 |
{ |
439 | 457 |
AVFormatContext *ctx = s->opaque; |
458 |
+ mpegts_prefix_m2ts_header(ctx); |
|
440 | 459 |
avio_write(ctx->pb, packet, TS_PACKET_SIZE); |
441 | 460 |
} |
442 | 461 |
|
... | ... |
@@ -584,6 +607,14 @@ static int mpegts_write_header(AVFormatContext *s) |
584 | 584 |
service->pcr_packet_period, |
585 | 585 |
ts->sdt_packet_period, ts->pat_packet_period); |
586 | 586 |
|
587 |
+ if (ts->m2ts_mode == -1) { |
|
588 |
+ if (av_match_ext(s->filename, "m2ts")) { |
|
589 |
+ ts->m2ts_mode = 1; |
|
590 |
+ } else { |
|
591 |
+ ts->m2ts_mode = 0; |
|
592 |
+ } |
|
593 |
+ } |
|
594 |
+ |
|
587 | 595 |
avio_flush(s->pb); |
588 | 596 |
|
589 | 597 |
return 0; |
... | ... |
@@ -616,12 +647,6 @@ static void retransmit_si_info(AVFormatContext *s) |
616 | 616 |
} |
617 | 617 |
} |
618 | 618 |
|
619 |
-static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) |
|
620 |
-{ |
|
621 |
- return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + |
|
622 |
- ts->first_pcr; |
|
623 |
-} |
|
624 |
- |
|
625 | 619 |
static int write_pcr_bits(uint8_t *buf, int64_t pcr) |
626 | 620 |
{ |
627 | 621 |
int64_t pcr_low = pcr % 300, pcr_high = pcr / 300; |
... | ... |
@@ -648,6 +673,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s) |
648 | 648 |
*q++ = 0xff; |
649 | 649 |
*q++ = 0x10; |
650 | 650 |
memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf)); |
651 |
+ mpegts_prefix_m2ts_header(s); |
|
651 | 652 |
avio_write(s->pb, buf, TS_PACKET_SIZE); |
652 | 653 |
} |
653 | 654 |
|
... | ... |
@@ -673,6 +699,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) |
673 | 673 |
|
674 | 674 |
/* stuffing bytes */ |
675 | 675 |
memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); |
676 |
+ mpegts_prefix_m2ts_header(s); |
|
676 | 677 |
avio_write(s->pb, buf, TS_PACKET_SIZE); |
677 | 678 |
} |
678 | 679 |
|
... | ... |
@@ -909,6 +936,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, |
909 | 909 |
memcpy(buf + TS_PACKET_SIZE - len, payload, len); |
910 | 910 |
payload += len; |
911 | 911 |
payload_size -= len; |
912 |
+ mpegts_prefix_m2ts_header(s); |
|
912 | 913 |
avio_write(s->pb, buf, TS_PACKET_SIZE); |
913 | 914 |
} |
914 | 915 |
avio_flush(s->pb); |
... | ... |
@@ -1054,7 +1082,7 @@ AVOutputFormat ff_mpegts_muxer = { |
1054 | 1054 |
.name = "mpegts", |
1055 | 1055 |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), |
1056 | 1056 |
.mime_type = "video/x-mpegts", |
1057 |
- .extensions = "ts,m2t", |
|
1057 |
+ .extensions = "ts,m2t,m2ts", |
|
1058 | 1058 |
.priv_data_size = sizeof(MpegTSWrite), |
1059 | 1059 |
.audio_codec = CODEC_ID_MP2, |
1060 | 1060 |
.video_codec = CODEC_ID_MPEG2VIDEO, |