[FFmpeg-devel] [PATCH] Fix output rate of mpegts CBR muxer
Dan Dennedy
dan
Wed Apr 21 09:28:33 CEST 2010
Hi,
Currently, the mpegts muxer outputs a higher rate than requested using
-muxrate due to the cur_pcr accumulating division truncation errors.
For a 10 mbps stream, I see about 172 kbps higher than I requested.
This fixes it by simply counting packets and then taking the division
only when PCR is actually needed.
Index: libavformat/mpegtsenc.c
===================================================================
--- libavformat/mpegtsenc.c (revision 22926)
+++ libavformat/mpegtsenc.c (working copy)
@@ -60,6 +60,7 @@
int nb_services;
int onid;
int tsid;
+ uint64_t pcr_delay;
uint64_t cur_pcr;
int mux_rate; ///< set to 1 when VBR
} MpegTSWrite;
@@ -110,7 +111,7 @@
buf_ptr += len1;
len -= len1;
- ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate;
+ ts->cur_pcr++;
}
}
@@ -458,7 +459,7 @@
ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) /
(TS_PACKET_SIZE * 8 * 1000);
- ts->cur_pcr = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
+ ts->pcr_delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);
} else {
/* Arbitrary values, PAT/PMT could be written on key frames */
ts->sdt_packet_period = 200;
@@ -536,7 +537,7 @@
*q++ = 0x10;
memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf));
put_buffer(s->pb, buf, TS_PACKET_SIZE);
- ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate;
+ ts->cur_pcr++;
}
/* Write a single transport stream packet with a PCR and no payload */
@@ -545,7 +546,7 @@
MpegTSWrite *ts = s->priv_data;
MpegTSWriteStream *ts_st = st->priv_data;
uint8_t *q;
- uint64_t pcr = ts->cur_pcr;
+ uint64_t pcr = ts->pcr_delay + ts->cur_pcr *
TS_PACKET_SIZE*8*90000LL/ts->mux_rate;
uint8_t buf[TS_PACKET_SIZE];
q = buf;
@@ -568,7 +569,7 @@
/* stuffing bytes */
memset(q, 0xFF, TS_PACKET_SIZE - (q - buf));
put_buffer(s->pb, buf, TS_PACKET_SIZE);
- ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate;
+ ts->cur_pcr++;
}
static void write_pts(uint8_t *q, int fourbits, int64_t pts)
@@ -619,7 +620,8 @@
}
if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&
- (dts - (int64_t)ts->cur_pcr) > delay) {
+ (dts - (int64_t)(ts->pcr_delay + ts->cur_pcr *
+ TS_PACKET_SIZE*8*90000LL/ts->mux_rate)) > delay) {
/* pcr insert gets priority over null packet insert */
if (write_pcr)
mpegts_insert_pcr_only(s, st);
@@ -641,7 +643,8 @@
if (write_pcr) {
// add 11, pcr references the last byte of program clock
reference base
if (ts->mux_rate > 1)
- pcr = ts->cur_pcr + (4+7)*8*90000LL / ts->mux_rate;
+ pcr = ts->pcr_delay + ((4+7) + ts->cur_pcr *
+ TS_PACKET_SIZE *8*90000LL) / ts->mux_rate;
else
pcr = dts - delay;
if (dts != AV_NOPTS_VALUE && dts < pcr)
@@ -768,7 +771,7 @@
payload += len;
payload_size -= len;
put_buffer(s->pb, buf, TS_PACKET_SIZE);
- ts->cur_pcr += TS_PACKET_SIZE*8*90000LL/ts->mux_rate;
+ ts->cur_pcr++;
}
put_flush_packet(s->pb);
}
--
+-DRD-+
More information about the ffmpeg-devel
mailing list