MPEG-2 muxer overshoots and corrects with undershoot in CBR mode (-muxrate)
|Reported by:||Warren Young||Owned by:|
|Blocking:||Reproduced by developer:||no|
|Analyzed by developer:||no|
If you use the -muxrate option with -c copy to turn a VBR file into a CBR output, ffmpeg's MPEG-TS muxer can approximately achieve your goals if you set the mux rate high enough to cover all of the peaks, but it has a bug that causes it to occasionally overshoot — sometimes massively — followed by an immediate undershoot correction.
This is a problem because when you need CBR, you really do need CBR, not CBR-ish. My local need is to allow Live555's media server (http://live555.com/mediaServer/) to smoothly stream files, and it requires CBR in order to schedule a smooth output frame rate based on the input bit rate. Smooth streaming with VBR requires clever algorithms that simply aren't in Live555.
I've prepared some files and charts to show the problem:
The file input.mp4 is a highly-variable bitrate output from PowerPoint, since it's mostly still frames with occasional transitions. The input.png file shows the bit rate of this stream. Each bar represents 2 seconds of the video.
(These charts were created by etr-bv, an MIT-licensed tool I created based on ffprobe -show_frames: https://github.com/wyoung/etr-bv)
The file output.ts was created by a straightforward remux command. Something like:
$ ffmpeg -f mpegts -i input.mp4 -c copy -muxrate 13.5M output.ts
The -muxrate value was chosen to be +10% or so over the highest peak found in input.mp4.
This results in output.ts and output.png in the above-linked Google Drive folder. As you can see, it's mostly CBR, but it overshot the limit I gave it 4 times, with 4 immediate compensating corrections.
When this is bad enough, it causes buffer overruns and such in memory-constrained decoders, causing bad decodes.
If you modify the windowSize value in the etr-bv.R script from its default of 2 seconds, you can blur out these faults, but it isn't until you get to 10 seconds that it looks like it's truly CBR. That means you need at least 10 seconds worth of video buffering in the decoder to compensate for these overshoots! That's asking way too much for many embedded hardware decoders, particularly at such high bit rates.
How to reproduce: Take the files in the Google Drive and use my command above along with etr-bv to replicate the symptom. See the instructions on the GitHub home page for this project if you've never used R or RStudio.
This is an ongoing problem, probably first seen in the early 3.x series, and I just replicated it with tip-of-master. I've been hoping someone would notice and fix it before now, but since that apparently isn't going to happen, I've gathered the data to show the problem clearly here.