[Ffmpeg-devel] lavc crash & qprd plus bframes = low quality
Sat Dec 9 08:06:53 CET 2006
Trent Piepho wrote:
> On Fri, 8 Dec 2006, Corey Hickey wrote:
>>> Ok, I've simplified the lavcopts:
>>> vcodec=mpeg4:vbitrate=6950:mbd=2 + vmax_b_frames=2 and/or qprd
>> ...and vpass=1/vpass=2, I presume?
> I was trying to simplify, so I just did one pass encoding.
For reproducing the crash, that's just fine; for comparing quality,
using only a single pass can be problematic because different options
can result in much more bitrate variation--not only can the overall
average differ somewhat, but, more importantly, the ratecontrol can
locally allocate bitrate rather differently. Using a second pass tends
to smooth such variation out.
> I have produced a sample clip compressed with ffv1 that can be used to see
> these problems. It also works for the crash I posted about earlier. It's
> 156MB, but if I re-scale, compress with mjpeg or nuv, clip more out, etc.
> the same problems don't happen.It was a major PITA just to get it this
> small. I've uploaded it to:
> Using latest svn mencoder, unmodified, I get a crash with this command:
> mencoder -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=7000:dia=-4:v4mv:qpel:vqmin=2:mbd=2:trell:cbp:sc_factor=4:vmax_b_frames=2:qprd -o /dev/null crash_in_mvsearch.avi
> About 16 seconds in, lavc crashes with:
> mencoder: motion_est_template.c:1044: epzs_motion_search_internal: Assertion `(P>>shift) <= xmax' failed.
I can confirm that on amd64. Michael, are you watching? Is there
anything more you need to debug the assertion failure?
> I also tried, again using unmodified mencoder, these options:
> mencoder -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=7000:mbd=2 -o test.avi crash_in_mvsearch.avi
> with qprd, or vmax_b_frames=2, or vmax_b_frames=2:qprd
I can't really give you a solution, but I may be able to give you a
better understanding of what is happening.
I encoded your clip with several different options. Since we're
comparing different options of the same codec, and the options don't
have a "psychovisual" effect, PSNR should be a reasonable representation
or relative quality.
All of these encodes were two pass, like this:
$ for i in 1 2 ; do mencoder -ovc lavc -lavcopts
vcodec=mpeg4:vbitrate=7000:mbd=2:psnr:vpass=$i -o lavc_neither.avi
crash_in_mvsearch.avi ; done
The options listed are additions to the above lavcopts. The bitrate and
PSNR reported is for the second pass.
(no other options)
Video stream: 7007.917 kbit/s (875989 B/s) size: 20204444 bytes
PSNR: Y:44.54, Cb:49.85, Cr:50.15, All:45.73
Video stream: 7002.222 kbit/s (875277 B/s) size: 20188026 bytes
PSNR: Y:44.77, Cb:49.91, Cr:50.16, All:45.93
qprd seems to help.
Video stream: 6462.474 kbit/s (807809 B/s) size: 18631883 bytes
PSNR: Y:43.71, Cb:49.28, Cr:49.55, All:44.92
With B-frames, the PSNR is about the same, but note that the bitrate is
much lower. lavc printed a notice about that: "Using all of requested
bitrate is not necessary for this video with these parameters." The
reason, here, is that lavc uses higher quantizers to encode B-frames,
and, hence, a lower bitrate. With this clip, 7000 kbits/sec is so high
that lavc can't reallocate the saved bitrate by lowering the quantizers
of enough non B-frames--once all the I- and P-frames have a quantizer of
2, the minimum allowed, the rest of the bitrate cannot be used.
Video stream: 5961.748 kbit/s (745218 B/s) size: 17188246 bytes
PSNR: Y:43.52, Cb:49.10, Cr:49.36, All:44.73
With both B-frames and qprd, the PSNR is somewhat lower, and the bitrate
is even lower than with B-frames alone. Unfortunately, I can't give you
any explanation for why this is. The results do reveal, however, that
the combination isn't simply lowering quality--it's lowering bitrate
usage as well. Just like in the last test, if there weren't already so
many low quantizers, the bitrate could be put to better use elsewhere
for a net quality gain.
So, what should you do? It's probably possible to mess around with lmin,
mblmin, vmax_b_frames, vb_qfactor, vb_qoffset, and vb_strategy to make
B-frames work well in this situation. Once they do, qprd would probably
help as well. I'll leave it to you to decide whether you want to do that
or just avoid B-frames here. Personally, I always encode at bitrates
that are low enough to benefit from B-frames without any extra work.
> I also made a sample with xvid (1.1.2):
> mencoder -ovc xvid -xvidencopts bitrate=7000:vhq=2:notrellis:noqpel:me_quality=5:bvhq=1:bquant_offset=50:quant_type=mpeg
> I turned off stuff like trellis to try to make the comparison more fair,
> since the lavc options were simlified to the minimum needed. Still, xvid
> does considerably better than lavc.
Directly comparing lavc and xvid can be difficult, and flamewars
occasionally ensue when somebody says "xvid rox and lavc sux". I will
definitely grant that the default options of xvid result in a much
better-looking video than the default options of lavc; however, in my
experience, it is possible to tweak lavc until it looks a bit better
than xvid (though at the expense of somewhat slower encoding speed).
There are several specific reasons, I think, for why your particular
xvid encode looks better.
1. Your xvidencopts specify MPEG quantizers and your lavcopts do not.
MPEG quantizers are reputed to look better when the target bitrate is
high relative to the resolution and complexity of the video. In this
case, using them does make the video look a bit better to me.
2. As I'm sure you're aware, lavc's defaults tend much more toward speed
rather than quality. I don't know xvid well enough to say precisely, but
I think a more fair comparison would also allow lavc at least some of
3. xvid avoids B-frames in high-motion scenes. lavc, by default, always
uses the maximum number, which (along with what I describe in the next
paragraph) leads to some ugly frames with very high quantizers. For best
placement and a much slower first pass, use vb_strategy=2. For almost as
good placement, and encoding that is a bit faster instead, use
4. xvid's ratecontrol is willing to use very high bitrates to make
high-motion scenes look good. For a while now, I've advocated
vrc_eq=(tex+10^8*mcVar)^0.6, which makes lavc's ratecontrol respond to
motion much more.
More information about the ffmpeg-devel