[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