[FFmpeg-trac] #9201(ffmpeg:new): -c:v mpeg2video ignoring -qmin+qmax

FFmpeg trac at avcodec.org
Mon Apr 26 21:45:31 EEST 2021


#9201: -c:v mpeg2video ignoring -qmin+qmax
-------------------------------------+-------------------------------------
             Reporter:  Warren       |                     Type:  defect
  Young                              |
               Status:  new          |                 Priority:  normal
            Component:  ffmpeg       |                  Version:  4.2.4
             Keywords:  mpeg2video   |               Blocked By:
  qscale                             |
             Blocking:               |  Reproduced by developer:  0
Analyzed by developer:  0            |
-------------------------------------+-------------------------------------
 I'm trying to get around a problem where setting a too-low -q:v with -f
 mpeg2video results in "rc buffer underflow" errors when setting -maxrate.

 I realize that -q is a constant-quality mode and that this allows bit rate
 to go arbitrarily high, potentially hitting my -maxrate ceiling. The
 problem then is, what to do about it?

 1. Increase -q, reducing quality for all files, even though they mostly
 don't hit the ceiling, just to account for the fact that occasionally I do
 get a file that does hit the ceiling, resulting in an encoding failure
 with these settings. This works, but results in bad quality across the
 board, just to cover the worst-case conditions.

 2. Give up on constant-quality mode, letting Q vary between 2 and 31 per
 the encoder's defaults. This works, but unless I use 2-pass encoding, it
 gives worse quality than an optimally-chosen -q value.

 3. Try to use -qmin and -qmax together to achieve both desires: -qmin set
 to my prior fixed -q value, plus -qmax set to the largest value I ever see
 a need for in testing, which is well under the default, 31.

 The problem when I take route 3 is that ffmpeg appears to ignore it. This
 despite the fact that I'm just doing what ffmpeg itself suggests: "max
 bitrate possibly too small or try trellis with large lmax or increase
 qmax". Currently, giving -q + -qmax + -maxrate doesn't change anything.

 Reproduction command line:

 {{{
 ffmpeg -i in.mp4 -f mpegts -c:v mpeg2video -maxrate 18M -bufsize 9M
 -qmin:v 8 -qmax:v 20 ... -y out.ts
 }}}

 The 18M maxrate value is from the ATSC/QAM limitations for broadcast
 video, which is why I'm using MPEG-TS as a container here. I ''have'' to
 get in under this limit or I'll overrun my hardware MPEG-2 decoders'
 buffers.

 (The hard limit from the spec is more like 19.4 Mbit/sec, but I also need
 space for audio + mux overhead. Pathological cases aside, 18 should be
 plenty, even for 1080p at 29.97 MPEG-2 video.)

 You don't need any particular input file to show the problem. Although
 only certain inputs will give the "rc buffer overflow" symptom, you can
 see with ''any'' input that the output isn't constrained as the command
 line specifies. With ffmpeg 4.4 (current Homebrew build), I see output
 lines like this:

 {{{
 frame=  360 fps=132 q=31.0 Lsize=    4332kB time=00:00:11.97
 bitrate=2962.5kbits/s speed= 4.4x
 }}}

 It mostly shows q=31 with occasional flickers to q=24.8. Why those two
 values, and how can it get to them anyway when they're both above qmax?

 Why doesn't it ever go down to 8, even though in the line above, it shows
 that it's achieved 3 Mbps, well under my 18 Mbps max?

 I realize that you can't combine a constant-quality mode in ffmpeg with
 2-pass encoding, but with the above combination of 3 bitrate control
 options (qmin+qmax+maxrate) I'd expect it to try qmin, then if that blew
 the maxrate budget, try qmax, and error out if that also fails. If
 encoding at qmax instead succeeds, try a binary search to find the highest
 q value that does fit inside the maxrate limit.

 I'm expecting it to repeat this algorithm over each "chunk" of video,
 presumably set based on my -bufsize value, though possibly based on other
 limits, such as GOP size.

 There would have to be a maximum number of iterations, but it should be
 able to find a near-optimal Q value for each chunk of video with a small
 number of tries:

 * 2 steps: just try qmax if qmin fails, oscillating between the two as
 necessary
 * 3 steps: try `qmin+(qmax-qmin)/2` if qmin fails but qmax succeeds
 * 4-5 steps: also try the quarter steps; only 4 steps if `qmin+(qmax-
 qmin)/4` succeeds, but 5 if that fails, since you then need to try the ¾
 step: `qmin+(3*((qmax-qmin)/4))`
 * 9 steps: same algorithm as above, but for eighth-interval steps

 For easy-to-encode video, Q should ride along at qmin, giving the effect
 of a constant-quality mode (-q=qmin) but by giving -qmax, I'm allowing the
 encoder to retry at lower qualities to get the video under my -maxrate
 limit.

 I've seen this behavior on versions from 4.2.1 to 4.4. I've chosen the
 lowest value available in your Version drop-down.
-- 
Ticket URL: <https://trac.ffmpeg.org/ticket/9201>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list