[FFmpeg-trac] #8048(avformat:new): MPEG-2 muxer overshoots and corrects with undershoot in CBR mode (-muxrate)
FFmpeg
trac at avcodec.org
Mon Jul 29 20:53:34 EEST 2019
#8048: MPEG-2 muxer overshoots and corrects with undershoot in CBR mode (-muxrate)
-------------------------------------+-------------------------------------
Reporter: tangent | Type: defect
Status: new | Priority: normal
Component: avformat | Version: git-
Keywords: CBR | master
multiplexing overshoot | Blocked By:
Blocking: | Reproduced by developer: 0
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
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:
https://drive.google.com/drive/folders/1TKvC1_Mn8OvifsLPcG7tEhwWnq94iPE6?usp=sharing
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.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/8048>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list