ekisu / mpv-webm

Simple WebM maker for mpv, with no external dependencies.
MIT License
571 stars 33 forks source link

Encoding with CRF does not work as expected #21

Closed averms closed 6 years ago

averms commented 6 years ago

mpv version and platform

git commit d828887 and macOS (write OS and version)

mpv d828887 Copyright © 2000-2018 mpv/MPlayer/mplayer2 projects
 built on Thu May 24 10:23:23 EDT 2018
ffmpeg library versions:
   libavutil       56.18.102
   libavcodec      58.19.102
   libavformat     58.16.100
   libswscale      5.2.100
   libavfilter     7.24.100
   libswresample   3.2.100
ffmpeg version: N-45620-g50df4c958

Description

VP9 has a constant quality mode that should be enabled when one uses 0 for target_filesize. According to the ffmpeg wiki

To trigger this mode, you must use a combination of -crf and -b:v 0. -b:v MUST be 0

Describe the problem, what steps you did, what happened and what you expected to happen.

I noticed that in my encodes using 0 for target_filesize, the bitrate option was not passed to mpv's encode. I solved it on my own by editing around line 774 in webm.lua.

Expected: pass in ovcopts-add=b=0 to mpv in the command Outcome: mpv Shelter.mkv --start=0:00:02.586 --end=0:00:03.045 --ovc=libvpx-vp9 --oac=libopus --loop-file=no --vid=1 --aid=1 --sid=1 --sub-ass-override=yes --sub-auto=exact --vf-add=lavfi-crop=1920:1080:0:0 --ovcopts-add=threads=4 --oset-metadata=title=%7%Shelter --ovcopts-add=crf=10,qmax=40 -o=./Shelter-[00.02.586-00.03.045]-audio.webm

Note that I did change the script to use opus but that shouldn't have an impact on the issue.

Log file

https://pastebin.com/TiAA3FDm

ekisu commented 6 years ago

I'm not sure how to implement this. Interpreting target_filesize = 0 as -b:v 0, instead of just disabling bitrates overall, doesn't seem to be very intuitive - zero bitrate works for VP9, and seems to produce a decent encode with VP8, but I'm not sure for other codecs.

Just as a reference:

averms commented 6 years ago

The reason that no bitrate flag works is that ffmpeg uses 256k (or 200k I'm not sure) as the default -b value when nothing is passed in. Only a -b of 0 will disable having a target filesize. I agree completely with your sentiment that it is unintuitive. Unfortunately, that's just how ffmpeg works.

This article, from the official webm wiki, explains it better than I do

Try man ffmpeg-codecs,

b integer (encoding,audio,video)
    Set bitrate in bits/s. Default value is 200K.
ekisu commented 6 years ago

Apparently, setting "-b:v 0" falls back to "-b:v 1000M" on VP8 - I also got binary-exact files for both -b:v 0 and -b:v 1000M.

Unfortunately, it doesn't work the same way for other codecs. libx264 and libx265, for example, completely disregard the -b:v flag when crf is set.

As it works in similar ways for both "officially supported" codecs, I'll just let target_filesize <= 0 be -b:v 0 then, and add some comments about it. Hopefully it will clear some of the confusion.