diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 0e892e99d8..dc8916baa6 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -36,9 +36,35 @@ typedef struct MpegTSSection { void *opaque; } MpegTSSection; +typedef struct MpegTSService { + MpegTSSection pmt; /* MPEG2 pmt table context */ + int sid; /* service ID */ + char *name; + char *provider_name; + int pcr_pid; + int pcr_packet_count; + int pcr_packet_freq; +} MpegTSService; + +typedef struct MpegTSWrite { + MpegTSSection pat; /* MPEG2 pat table */ + MpegTSSection sdt; /* MPEG2 sdt table context */ + MpegTSService **services; + int sdt_packet_count; + int sdt_packet_freq; + int pat_packet_count; + int pat_packet_freq; + int nb_services; + int onid; + int tsid; + uint64_t cur_pcr; + int mux_rate; +} MpegTSWrite; + /* NOTE: 4 bytes must be left at the end for the crc32 */ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) { + MpegTSWrite *ts = ((AVFormatContext*)s->opaque)->priv_data; unsigned int crc; unsigned char packet[TS_PACKET_SIZE]; const unsigned char *buf_ptr; @@ -80,6 +106,8 @@ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) buf_ptr += len1; len -= len1; + + ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; } } @@ -149,29 +177,6 @@ typedef struct MpegTSWriteStream { uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; } MpegTSWriteStream; -typedef struct MpegTSService { - MpegTSSection pmt; /* MPEG2 pmt table context */ - int sid; /* service ID */ - char *name; - char *provider_name; - int pcr_pid; - int pcr_packet_count; - int pcr_packet_freq; -} MpegTSService; - -typedef struct MpegTSWrite { - MpegTSSection pat; /* MPEG2 pat table */ - MpegTSSection sdt; /* MPEG2 sdt table context */ - MpegTSService **services; - int sdt_packet_count; - int sdt_packet_freq; - int pat_packet_count; - int pat_packet_freq; - int nb_services; - int onid; - int tsid; -} MpegTSWrite; - static void mpegts_write_pat(AVFormatContext *s) { MpegTSWrite *ts = s->priv_data; @@ -439,6 +444,8 @@ static int mpegts_write_header(AVFormatContext *s) total_bit_rate, ts->sdt_packet_freq, ts->pat_packet_freq); #endif + ts->mux_rate = total_bit_rate; + /* write info at the start of the file, so that it will be fast to find them */ mpegts_write_sdt(s); @@ -497,6 +504,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, int64_t pts, int64_t dts) { MpegTSWriteStream *ts_st = st->priv_data; + MpegTSWrite *ts = s->priv_data; uint8_t buf[TS_PACKET_SIZE]; uint8_t *q; int val, is_start, len, header_len, write_pcr, private_code, flags; @@ -514,9 +522,6 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, ts_st->service->pcr_packet_freq) { ts_st->service->pcr_packet_count = 0; write_pcr = 1; - /* XXX: this is incorrect, but at least we have a PCR - value */ - pcr = pts; } } @@ -531,6 +536,8 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, *q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0); ts_st->cc = (ts_st->cc + 1) & 0xf; if (write_pcr) { + // add 11, pcr references the last byte of program clock reference base + pcr = ts->cur_pcr + (4+7)*8*90000LL / ts->mux_rate; *q++ = 7; /* AFC length */ *q++ = 0x10; /* flags: PCR present */ *q++ = pcr >> 25; @@ -651,6 +658,7 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, payload += len; payload_size -= len; put_buffer(s->pb, buf, TS_PACKET_SIZE); + ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate; } put_flush_packet(s->pb); }