diff options
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r-- | libavformat/mpegtsenc.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index cc4074338a..1eb935c182 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -2,20 +2,20 @@ * MPEG2 transport stream (aka DVB) muxer * Copyright (c) 2003 Fabrice Bellard * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -75,6 +75,7 @@ typedef struct MpegTSWrite { int pmt_start_pid; int start_pid; + int m2ts_mode; } MpegTSWrite; static const AVOption options[] = { @@ -85,9 +86,12 @@ static const AVOption options[] = { { "mpegts_service_id", "Set service_id field.", offsetof(MpegTSWrite, service_id), FF_OPT_TYPE_INT, {.dbl = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", - offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x1000, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, + offsetof(MpegTSWrite, pmt_start_pid), FF_OPT_TYPE_INT, {.dbl = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, { "mpegts_start_pid", "Set the first pid.", offsetof(MpegTSWrite, start_pid), FF_OPT_TYPE_INT, {.dbl = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM}, + {"mpegts_m2ts_mode", "Enable m2ts mode.", + offsetof(MpegTSWrite, m2ts_mode), FF_OPT_TYPE_INT, {.dbl = -1 }, + -1,1, AV_OPT_FLAG_ENCODING_PARAM}, { NULL }, }; @@ -184,7 +188,7 @@ static int mpegts_write_section1(MpegTSSection *s, int tid, int id, /*********************************************/ /* mpegts writer */ -#define DEFAULT_PROVIDER_NAME "Libav" +#define DEFAULT_PROVIDER_NAME "FFmpeg" #define DEFAULT_SERVICE_NAME "Service01" /* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */ @@ -434,9 +438,28 @@ static MpegTSService *mpegts_add_service(MpegTSWrite *ts, return service; } +static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) +{ + return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + + ts->first_pcr; +} + +static void mpegts_prefix_m2ts_header(AVFormatContext *s) +{ + MpegTSWrite *ts = s->priv_data; + if (ts->m2ts_mode) { + int64_t pcr = get_pcr(s->priv_data, s->pb); + uint32_t tp_extra_header = pcr % 0x3fffffff; + tp_extra_header = AV_RB32(&tp_extra_header); + avio_write(s->pb, (unsigned char *) &tp_extra_header, + sizeof(tp_extra_header)); + } +} + static void section_write_packet(MpegTSSection *s, const uint8_t *packet) { AVFormatContext *ctx = s->opaque; + mpegts_prefix_m2ts_header(ctx); avio_write(ctx->pb, packet, TS_PACKET_SIZE); } @@ -584,6 +607,14 @@ static int mpegts_write_header(AVFormatContext *s) service->pcr_packet_period, ts->sdt_packet_period, ts->pat_packet_period); + if (ts->m2ts_mode == -1) { + if (av_match_ext(s->filename, "m2ts")) { + ts->m2ts_mode = 1; + } else { + ts->m2ts_mode = 0; + } + } + avio_flush(s->pb); return 0; @@ -616,12 +647,6 @@ static void retransmit_si_info(AVFormatContext *s) } } -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) -{ - return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + - ts->first_pcr; -} - static int write_pcr_bits(uint8_t *buf, int64_t pcr) { int64_t pcr_low = pcr % 300, pcr_high = pcr / 300; @@ -648,6 +673,7 @@ static void mpegts_insert_null_packet(AVFormatContext *s) *q++ = 0xff; *q++ = 0x10; memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf)); + mpegts_prefix_m2ts_header(s); avio_write(s->pb, buf, TS_PACKET_SIZE); } @@ -673,6 +699,7 @@ 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); } @@ -909,6 +936,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, memcpy(buf + TS_PACKET_SIZE - len, payload, len); payload += len; payload_size -= len; + mpegts_prefix_m2ts_header(s); avio_write(s->pb, buf, TS_PACKET_SIZE); } avio_flush(s->pb); @@ -1054,7 +1082,7 @@ AVOutputFormat ff_mpegts_muxer = { .name = "mpegts", .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 transport stream format"), .mime_type = "video/x-mpegts", - .extensions = "ts,m2t", + .extensions = "ts,m2t,m2ts", .priv_data_size = sizeof(MpegTSWrite), .audio_codec = CODEC_ID_MP2, .video_codec = CODEC_ID_MPEG2VIDEO, |