aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mpegtsenc.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-01-14 02:20:26 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-01-14 02:20:26 +0000
commitb5931348bc0b9e94a4ba19a2b762c3ee6d5633dd (patch)
tree2513eba697bd34c3efb9ff4893a2080dfc877f60 /libavformat/mpegtsenc.c
parentc91662ce8323f7e9fabd10631eeffb9e49200583 (diff)
downloadffmpeg-b5931348bc0b9e94a4ba19a2b762c3ee6d5633dd.tar.gz
compute pcr more accurately, regression tests need update
Originally committed as revision 16596 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mpegtsenc.c')
-rw-r--r--libavformat/mpegtsenc.c60
1 files changed, 34 insertions, 26 deletions
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);
}