++ struct MpegTSService *service;
+ int pid; /* stream associated pid */
+ int cc;
+ int discontinuity;
+@@ -236,10 +237,7 @@ typedef struct MpegTSWriteStream {
+ int payload_flags;
+ uint8_t *payload;
+ AVFormatContext *amux;
+- int data_st_warning;
+-
+- int64_t pcr_period; /* PCR period in PCR time base */
+- int64_t last_pcr;
++ AVRational user_tb;
+
+ /* For Opus */
+ int opus_queued_samples;
+@@ -259,7 +257,7 @@ static void mpegts_write_pat(AVFormatContext *s)
+ put16(&q, service->sid);
+ put16(&q, 0xe000 | service->pmt.pid);
+ }
+- mpegts_write_section1(&ts->pat, PAT_TID, ts->transport_stream_id, ts->tables_version, 0, 0,
++ mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, ts->tables_version, 0, 0,
+ data, q - data);
+ }
+
+@@ -281,148 +279,6 @@ static void put_registration_descriptor(uint8_t **q_ptr, uint32_t tag)
+ *q_ptr = q;
+ }
+
+-static int get_dvb_stream_type(AVFormatContext *s, AVStream *st)
+-{
+- MpegTSWrite *ts = s->priv_data;
+- MpegTSWriteStream *ts_st = st->priv_data;
+- int stream_type;
+-
+- switch (st->codecpar->codec_id) {
+- case AV_CODEC_ID_MPEG1VIDEO:
+- case AV_CODEC_ID_MPEG2VIDEO:
+- stream_type = STREAM_TYPE_VIDEO_MPEG2;
+- break;
+- case AV_CODEC_ID_MPEG4:
+- stream_type = STREAM_TYPE_VIDEO_MPEG4;
+- break;
+- case AV_CODEC_ID_H264:
+- stream_type = STREAM_TYPE_VIDEO_H264;
+- break;
+- case AV_CODEC_ID_HEVC:
+- stream_type = STREAM_TYPE_VIDEO_HEVC;
+- break;
+- case AV_CODEC_ID_CAVS:
+- stream_type = STREAM_TYPE_VIDEO_CAVS;
+- break;
+- case AV_CODEC_ID_DIRAC:
+- stream_type = STREAM_TYPE_VIDEO_DIRAC;
+- break;
+- case AV_CODEC_ID_VC1:
+- stream_type = STREAM_TYPE_VIDEO_VC1;
+- break;
+- case AV_CODEC_ID_MP2:
+- case AV_CODEC_ID_MP3:
+- if ( st->codecpar->sample_rate > 0
+- && st->codecpar->sample_rate < 32000) {
+- stream_type = STREAM_TYPE_AUDIO_MPEG2;
+- } else {
+- stream_type = STREAM_TYPE_AUDIO_MPEG1;
+- }
+- break;
+- case AV_CODEC_ID_AAC:
+- stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM)
+- ? STREAM_TYPE_AUDIO_AAC_LATM
+- : STREAM_TYPE_AUDIO_AAC;
+- break;
+- case AV_CODEC_ID_AAC_LATM:
+- stream_type = STREAM_TYPE_AUDIO_AAC_LATM;
+- break;
+- case AV_CODEC_ID_AC3:
+- stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B)
+- ? STREAM_TYPE_PRIVATE_DATA
+- : STREAM_TYPE_AUDIO_AC3;
+- break;
+- case AV_CODEC_ID_EAC3:
+- stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B)
+- ? STREAM_TYPE_PRIVATE_DATA
+- : STREAM_TYPE_AUDIO_EAC3;
+- break;
+- case AV_CODEC_ID_DTS:
+- stream_type = STREAM_TYPE_AUDIO_DTS;
+- break;
+- case AV_CODEC_ID_TRUEHD:
+- stream_type = STREAM_TYPE_AUDIO_TRUEHD;
+- break;
+- case AV_CODEC_ID_OPUS:
+- stream_type = STREAM_TYPE_PRIVATE_DATA;
+- break;
+- case AV_CODEC_ID_TIMED_ID3:
+- stream_type = STREAM_TYPE_METADATA;
+- break;
+- case AV_CODEC_ID_DVB_SUBTITLE:
+- case AV_CODEC_ID_DVB_TELETEXT:
+- stream_type = STREAM_TYPE_PRIVATE_DATA;
+- break;
+- case AV_CODEC_ID_SMPTE_KLV:
+- if (st->codecpar->profile == FF_PROFILE_KLVA_SYNC) {
+- stream_type = STREAM_TYPE_METADATA;
+- } else {
+- stream_type = STREAM_TYPE_PRIVATE_DATA;
+- }
+- break;
+- default:
+- av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning,
+- "Stream %d, codec %s, is muxed as a private data stream "
+- "and may not be recognized upon reading.\n", st->index,
+- avcodec_get_name(st->codecpar->codec_id));
+- stream_type = STREAM_TYPE_PRIVATE_DATA;
+- break;
+- }
+-
+- return stream_type;
+-}
+-
+-static int get_m2ts_stream_type(AVFormatContext *s, AVStream *st)
+-{
+- int stream_type;
+- MpegTSWriteStream *ts_st = st->priv_data;
+-
+- switch (st->codecpar->codec_id) {
+- case AV_CODEC_ID_MPEG2VIDEO:
+- stream_type = STREAM_TYPE_VIDEO_MPEG2;
+- break;
+- case AV_CODEC_ID_H264:
+- stream_type = STREAM_TYPE_VIDEO_H264;
+- break;
+- case AV_CODEC_ID_VC1:
+- stream_type = STREAM_TYPE_VIDEO_VC1;
+- break;
+- case AV_CODEC_ID_HEVC:
+- stream_type = STREAM_TYPE_VIDEO_HEVC;
+- break;
+- case AV_CODEC_ID_PCM_BLURAY:
+- stream_type = 0x80;
+- break;
+- case AV_CODEC_ID_AC3:
+- stream_type = 0x81;
+- break;
+- case AV_CODEC_ID_DTS:
+- stream_type = (st->codecpar->channels > 6) ? 0x85 : 0x82;
+- break;
+- case AV_CODEC_ID_TRUEHD:
+- stream_type = 0x83;
+- break;
+- case AV_CODEC_ID_EAC3:
+- stream_type = 0x84;
+- break;
+- case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
+- stream_type = 0x90;
+- break;
+- case AV_CODEC_ID_HDMV_TEXT_SUBTITLE:
+- stream_type = 0x92;
+- break;
+- default:
+- av_log_once(s, AV_LOG_WARNING, AV_LOG_DEBUG, &ts_st->data_st_warning,
+- "Stream %d, codec %s, is muxed as a private data stream "
+- "and may not be recognized upon reading.\n", st->index,
+- avcodec_get_name(st->codecpar->codec_id));
+- stream_type = STREAM_TYPE_PRIVATE_DATA;
+- break;
+- }
+-
+- return stream_type;
+-}
+-
+ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
+ {
+ MpegTSWrite *ts = s->priv_data;
+@@ -436,14 +292,6 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
+ q += 2; /* patched after */
+
+ /* put program info here */
+- if (ts->m2ts_mode) {
+- put_registration_descriptor(&q, MKTAG('H', 'D', 'M', 'V'));
+- *q++ = 0x88; // descriptor_tag - hdmv_copy_control_descriptor
+- *q++ = 0x04; // descriptor_length
+- put16(&q, 0x0fff); // CA_System_ID
+- *q++ = 0xfc; // private_data_byte
+- *q++ = 0xfc; // private_data_byte
+- }
+
+ val = 0xf000 | (q - program_info_length_ptr - 2);
+ program_info_length_ptr[0] = val >> 8;
+@@ -472,8 +320,72 @@ static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
+ err = 1;
+ break;
+ }
+-
+- stream_type = ts->m2ts_mode ? get_m2ts_stream_type(s, st) : get_dvb_stream_type(s, st);
++ switch (st->codecpar->codec_id) {
++ case AV_CODEC_ID_MPEG1VIDEO:
++ case AV_CODEC_ID_MPEG2VIDEO:
++ stream_type = STREAM_TYPE_VIDEO_MPEG2;
++ break;
++ case AV_CODEC_ID_MPEG4:
++ stream_type = STREAM_TYPE_VIDEO_MPEG4;
++ break;
++ case AV_CODEC_ID_H264:
++ stream_type = STREAM_TYPE_VIDEO_H264;
++ break;
++ case AV_CODEC_ID_HEVC:
++ stream_type = STREAM_TYPE_VIDEO_HEVC;
++ break;
++ case AV_CODEC_ID_CAVS:
++ stream_type = STREAM_TYPE_VIDEO_CAVS;
++ break;
++ case AV_CODEC_ID_DIRAC:
++ stream_type = STREAM_TYPE_VIDEO_DIRAC;
++ break;
++ case AV_CODEC_ID_VC1:
++ stream_type = STREAM_TYPE_VIDEO_VC1;
++ break;
++ case AV_CODEC_ID_MP2:
++ case AV_CODEC_ID_MP3:
++ if ( st->codecpar->sample_rate > 0
++ && st->codecpar->sample_rate < 32000) {
++ stream_type = STREAM_TYPE_AUDIO_MPEG2;
++ } else {
++ stream_type = STREAM_TYPE_AUDIO_MPEG1;
++ }
++ break;
++ case AV_CODEC_ID_AAC:
++ stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM)
++ ? STREAM_TYPE_AUDIO_AAC_LATM
++ : STREAM_TYPE_AUDIO_AAC;
++ break;
++ case AV_CODEC_ID_AAC_LATM:
++ stream_type = STREAM_TYPE_AUDIO_AAC_LATM;
++ break;
++ case AV_CODEC_ID_AC3:
++ stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B)
++ ? STREAM_TYPE_PRIVATE_DATA
++ : STREAM_TYPE_AUDIO_AC3;
++ break;
++ case AV_CODEC_ID_EAC3:
++ stream_type = (ts->flags & MPEGTS_FLAG_SYSTEM_B)
++ ? STREAM_TYPE_PRIVATE_DATA
++ : STREAM_TYPE_AUDIO_EAC3;
++ break;
++ case AV_CODEC_ID_DTS:
++ stream_type = STREAM_TYPE_AUDIO_DTS;
++ break;
++ case AV_CODEC_ID_TRUEHD:
++ stream_type = STREAM_TYPE_AUDIO_TRUEHD;
++ break;
++ case AV_CODEC_ID_OPUS:
++ stream_type = STREAM_TYPE_PRIVATE_DATA;
++ break;
++ case AV_CODEC_ID_TIMED_ID3:
++ stream_type = STREAM_TYPE_METADATA;
++ break;
++ default:
++ stream_type = STREAM_TYPE_PRIVATE_DATA;
++ break;
++ }
+
+ *q++ = stream_type;
+ put16(&q, 0xe000 | ts_st->pid);
+@@ -736,7 +648,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
+ int i, running_status, free_ca_mode, val;
+
+ q = data;
+- put16(&q, ts->original_network_id);
++ put16(&q, ts->onid);
+ *q++ = 0xff;
+ for (i = 0; i < ts->nb_services; i++) {
+ service = ts->services[i];
+@@ -762,7 +674,7 @@ static void mpegts_write_sdt(AVFormatContext *s)
+ desc_list_len_ptr[0] = val >> 8;
+ desc_list_len_ptr[1] = val;
+ }
+- mpegts_write_section1(&ts->sdt, SDT_TID, ts->transport_stream_id, ts->tables_version, 0, 0,
++ mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, ts->tables_version, 0, 0,
+ data, q - data);
+ }
+
+@@ -802,49 +714,12 @@ invalid:
+ return 0;
+ }
+
+-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 write_packet(AVFormatContext *s, const uint8_t *packet)
+-{
+- 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));
+- }
+- avio_write(s->pb, packet, TS_PACKET_SIZE);
+-}
+-
+-static void section_write_packet(MpegTSSection *s, const uint8_t *packet)
+-{
+- AVFormatContext *ctx = s->opaque;
+- write_packet(ctx, packet);
+-}
+-
+ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,
+- const AVDictionary *metadata,
+- AVProgram *program)
++ const char *provider_name,
++ const char *name)
+ {
+ MpegTSWrite *ts = s->priv_data;
+ MpegTSService *service;
+- AVDictionaryEntry *title, *provider;
+- char default_service_name[32];
+- const char *service_name;
+- const char *provider_name;
+-
+- title = av_dict_get(metadata, "service_name", NULL, 0);
+- if (!title)
+- title = av_dict_get(metadata, "title", NULL, 0);
+- snprintf(default_service_name, sizeof(default_service_name), "%s%02d", DEFAULT_SERVICE_NAME, ts->nb_services + 1);
+- service_name = title ? title->value : default_service_name;
+- provider = av_dict_get(metadata, "service_provider", NULL, 0);
+- provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME;
+
+ service = av_mallocz(sizeof(MpegTSService));
+ if (!service)
+@@ -852,92 +727,57 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid,