Signed-off-by: Marton Balint <c...@passwd.hu> --- libavformat/mpegtsenc.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 2191c134ac..d8a74f4fe1 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -36,6 +36,8 @@ #define PCR_TIME_BASE 27000000 #define M2TS_DEFAULT_MUXRATE 54000000 +#define M2TS_PCR_PID 0x1001 +#define M2TS_PCR_RETRANS_TIME 50 /* write DVB SI sections */ @@ -99,6 +101,8 @@ typedef struct MpegTSWrite { int m2ts_audio_pid; int m2ts_subtitle_pid; int m2ts_other_pid; + int64_t m2ts_pcr_period; + int64_t m2ts_last_pcr; int pcr_period_ms; #define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01 @@ -769,7 +773,7 @@ static MpegTSService *mpegts_add_service(AVFormatContext *s, int sid, return NULL; service->pmt.pid = ts->pmt_start_pid + ts->nb_services; service->sid = sid; - service->pcr_pid = 0x1fff; + service->pcr_pid = ts->m2ts_mode ? M2TS_PCR_PID : 0x1fff; if (encode_str8(service->provider_name, provider_name) < 0 || encode_str8(service->name, service_name) < 0) { av_log(s, AV_LOG_ERROR, "Too long service or provider name\n"); @@ -1031,7 +1035,11 @@ static int mpegts_init(AVFormatContext *s) if (ts->copyts < 1) ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); - select_pcr_streams(s); + ts->m2ts_pcr_period = av_rescale(ts->pcr_period_ms == -1 ? M2TS_PCR_RETRANS_TIME : ts->pcr_period_ms, PCR_TIME_BASE, 1000); + ts->m2ts_last_pcr = ts->first_pcr - ts->m2ts_pcr_period; + + if (!ts->m2ts_mode) + select_pcr_streams(s); ts->last_pat_ts = AV_NOPTS_VALUE; ts->last_sdt_ts = AV_NOPTS_VALUE; @@ -1115,24 +1123,23 @@ static void mpegts_insert_null_packet(AVFormatContext *s, int force) } /* Write a single transport stream packet with a PCR and no payload */ -static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) +static void mpegts_insert_pcr_only(AVFormatContext *s, int pid, int cc, int *discontinuity) { MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; uint8_t *q; uint8_t buf[TS_PACKET_SIZE]; q = buf; *q++ = 0x47; - *q++ = ts_st->pid >> 8; - *q++ = ts_st->pid; - *q++ = 0x20 | ts_st->cc; /* Adaptation only */ + *q++ = pid >> 8; + *q++ = pid; + *q++ = 0x20 | cc; /* Adaptation only */ /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ *q++ = 0x10; /* Adaptation flags: PCR present */ - if (ts_st->discontinuity) { + if (discontinuity && *discontinuity) { q[-1] |= 0x80; - ts_st->discontinuity = 0; + *discontinuity = 0; } /* PCR coded into 6 bytes */ @@ -1143,6 +1150,12 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) write_packet(s, buf); } +static void mpegts_insert_pcr_only_for_stream(AVFormatContext *s, AVStream *st) +{ + MpegTSWriteStream *ts_st = st->priv_data; + mpegts_insert_pcr_only(s, ts_st->pid, ts_st->cc, &ts_st->discontinuity); +} + static void write_pts(uint8_t *q, int fourbits, int64_t pts) { int val; @@ -1237,6 +1250,11 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, pcr = get_pcr(ts, s->pb); if (pcr >= ts->next_pcr) { int64_t next_pcr = INT64_MAX; + if (ts->m2ts_mode) { + mpegts_insert_pcr_only(s, M2TS_PCR_PID, 0, NULL); + ts->m2ts_last_pcr = FFMAX(pcr - ts->m2ts_pcr_period, ts->m2ts_last_pcr + ts->m2ts_pcr_period); + next_pcr = FFMIN(next_pcr, ts->m2ts_last_pcr + ts->m2ts_pcr_period); + } else { for (int i = 0; i < s->nb_streams; i++) { /* Make the current stream the last, because for that we * can insert the pcr into the payload later */ @@ -1247,7 +1265,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, if (pcr - ts_st2->last_pcr >= ts_st2->pcr_period) { ts_st2->last_pcr = FFMAX(pcr - ts_st2->pcr_period, ts_st2->last_pcr + ts_st2->pcr_period); if (st2 != st) { - mpegts_insert_pcr_only(s, st2); + mpegts_insert_pcr_only_for_stream(s, st2); pcr = get_pcr(ts, s->pb); } else { write_pcr = 1; @@ -1256,12 +1274,13 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, next_pcr = FFMIN(next_pcr, ts_st2->last_pcr + ts_st2->pcr_period); } } + } ts->next_pcr = next_pcr; } if (dts != AV_NOPTS_VALUE && (dts - pcr / 300) > delay) { /* pcr insert gets priority over null packet insert */ if (write_pcr) - mpegts_insert_pcr_only(s, st); + mpegts_insert_pcr_only_for_stream(s, st); else mpegts_insert_null_packet(s, 0); /* recalculate write_pcr and possibly retransmit si_info */ -- 2.16.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".