5

I'm used to use VirtualDub to encode a video to AVI container with DivX-codec (and MP3 for audio). Now I'm planning to use ffmpeg to encode videos to MP4 container with h264-codec. What I've figured out is that I need to use libx264 and one of those presets to make anything work. However, I'm amazed about the video bitrate ffmpeg uses for encoding.

What I currently have is this little batch file:

@ECHO OFF

SETLOCAL

SET IN=source.avs
SET FFMPEG_PATH=C:\Program Files (x86)\ffmpeg
SET PRESET=-fpre "%FFMPEG_PATH%\presets\libx264-lossless_slow.ffpreset" 
SET AUDIO=-acodec libmp3lame -ab 128000
SET VIDEO=-vcodec libx264 -vb 1978000

"%FFMPEG_PATH%\ffmpeg.exe" -i %IN% %AUDIO% %VIDEO% %PRESET% test.mp4

ENDLOCAL

With this I tell ffmpeg to use 1978k as the bitrate, but ffmpeg uses 15000k+! I tried other presets, but they don't use my specified bitrate. Here are the presets I have:

  • libx264-baseline.ffpreset
  • libx264-ipod320.ffpreset
  • libx264-ipod640.ffpreset
  • libx264-lossless_fast.ffpreset
  • libx264-lossless_max.ffpreset
  • libx264-lossless_medium.ffpreset
  • libx264-lossless_slow.ffpreset
  • libx264-lossless_slower.ffpreset
  • libx264-lossless_ultrafast.ffpreset

ffmpeg version:

FFmpeg git-N-29181-ga304071
libavutil    50. 40. 1 / 50. 40. 1
libavcodec   52.120. 0 / 52.120. 0
libavformat  52.108. 0 / 52.108. 0
libavdevice  52.  4. 0 / 52.  4. 0
libavfilter   1. 79. 0 /  1. 79. 0
libswscale    0. 13. 0 /  0. 13. 0

Note that I don't use the latest version as it has problems with spaces in filenames.

Here's what seems to be the full parameter list DivX 6.9.2 uses:

-bvnn 1978000 -vbv 218691200,100663296,100663296 -dir "C:\Users\sjngm\AppData\Roaming\DivX\DivX Codec" -w -b 1 -use_presets=1 -preset=10 -windowed_fullsearch=2 -thread_delay=1

What command line parameters would that be for ffmpeg?


EDIT:

Going with slhck's suggestion I tried a new 32-bit version. I have no idea if that is 0.9 or newer, I can't find that info.

ffmpeg version N-36890-g67f5650
libavutil      51. 34.100 / 51. 34.100
libavcodec     53. 56.105 / 53. 56.105
libavformat    53. 30.100 / 53. 30.100
libavdevice    53.  4.100 / 53.  4.100
libavfilter     2. 59.100 /  2. 59.100
libswscale      2.  1.100 /  2.  1.100
libswresample   0.  6.100 /  0.  6.100
libpostproc    51.  2.100 / 51.  2.100

I reworked my batch file to look like this (interestingly enough I can't find parameter -vprofile in the documentation):

@ECHO OFF

SETLOCAL

SET IN=VTS_01_1.avs
SET FFMPEG_PATH=C:\Program Files (x86)\ffmpeg
SET PRESET=-vprofile high -preset veryslow
SET AUDIO=-acodec libmp3lame -ab 128000
SET VIDEO=-vcodec libx264 -vb 1978000

"%FFMPEG_PATH%\ffmpeg.exe" -i %IN% %AUDIO% %PRESET% %VIDEO% test.mp4

ENDLOCAL

I see that it now uses the bitrate properly (thanks to LongNeckbeard for pointing out that the lossless-stuff ignores the bitrate!).

Just in case you wonder how I came up with the 1978000, I'm using this formula which I found valid for DivX-files (I'm guessing the bitrate won't change that much for h264):

width * height * 25 * 0.22 / 1000

I'm not sure if the 0.22 correlates with the CRF somehow.

Overall I forgot to say the I will use a two-pass scenario, which is why I don't use the CRF here. I will try to read more about this. Currently I'm just trying to get something running that shows me that I'm doing something right (ffmpeg isn't the easiest tool to understand ;)).

C:\Program Files (x86)\ffmpeg\ffmpeg.exe" -i VTS_01_1.avs -acodec libmp3lame -ab 128000 -vcodec libx264 -vb 1978000 -vprofile high -preset veryslow test.mp4

The output is now:

ffmpeg version N-36890-g67f5650 Copyright (c) 2000-2012 the FFmpeg developers
  built on Jan 16 2012 21:57:13 with gcc 4.6.2
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-runtime-cpudetect --enable-avisynth --enable-bzlib --enable-frei0r --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
  libavutil      51. 34.100 / 51. 34.100
  libavcodec     53. 56.105 / 53. 56.105
  libavformat    53. 30.100 / 53. 30.100
  libavdevice    53.  4.100 / 53.  4.100
  libavfilter     2. 59.100 /  2. 59.100
  libswscale      2.  1.100 /  2.  1.100
  libswresample   0.  6.100 /  0.  6.100
  libpostproc    51.  2.100 / 51.  2.100
Input #0, avs, from 'VTS_01_1.avs':
  Duration: 00:58:46.12, start: 0.000000, bitrate: 0 kb/s
    Stream #0:0: Video: rawvideo (YV12 / 0x32315659), yuv420p, 576x448, 77414 kb/s, 25 tbr, 25 tbn, 25 tbc
    Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 48000 Hz, 2 channels, s16, 1536 kb/s
File 'test.mp4' already exists. Overwrite ? [y/N] y
w:576 h:448 pixfmt:yuv420p tb:1/1000000 sar:0/1 sws_param:
[libx264 @ 05A2C400] using cpu capabilities: MMX2 SSE2Fast FastShuffle SSEMisalign LZCNT
[libx264 @ 05A2C400] profile High, level 3.1
[libx264 @ 05A2C400] 264 - core 120 r2120 0c7dab9 - H.264/MPEG-4 AVC codec - Copyleft 2003-2011 - http://www.videolan.org/x264.html - options: cabac=1 ref=16 deblock=1:0:0 analyse=0x3:0x133 me=umh subme=10 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=24 chroma_me=1 trellis=2 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=3 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=8 b_pyramid=2 b_adapt=2 b_bias=0 direct=3 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=60 rc=abr mbtree=1 bitrate=1978 ratetol=1.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'test.mp4':
  Metadata:
    encoder         : Lavf53.30.100
    Stream #0:0: Video: h264 (![0][0][0] / 0x0021), yuv420p, 576x448, q=-1--1, 1978 kb/s, 25 tbn, 25 tbc
    Stream #0:1: Audio: mp3 (i[0][0][0] / 0x0069), 48000 Hz, 2 channels, s16, 128 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo -> libx264)
  Stream #0:1 -> #0:1 (pcm_s16le -> libmp3lame)
Press [q] to stop, [?] for help
frame=    0 fps=  0 q=0.0 size=       0kB time=00:00:00.00 bitrate=   0.0kbits/s
frame=    0 fps=  0 q=0.0 size=       0kB time=00:00:00.00 bitrate=   0.0kbits/s
frame=    0 fps=  0 q=0.0 size=       0kB time=00:00:00.00 bitrate=   0.0kbits/s
frame=    3 fps=  1 q=22.0 size=      39kB time=00:00:00.04 bitrate=8063.8kbits/
frame=    8 fps=  2 q=22.0 size=      82kB time=00:00:00.24 bitrate=2801.3kbits/
frame=   13 fps=  3 q=23.0 size=     120kB time=00:00:00.44 bitrate=2229.5kbits/
frame=   16 fps=  4 q=23.0 size=     147kB time=00:00:00.56 bitrate=2156.7kbits/
frame=   20 fps=  4 q=22.0 size=     175kB time=00:00:00.72 bitrate=1987.4kbits/
:
video:4387kB audio:273kB global headers:0kB muxing overhead 0.260038%
[libx264 @ 05A2C400] frame I:2     Avg QP:19.53  size: 29850
[libx264 @ 05A2C400] frame P:76    Avg QP:22.24  size: 19541
[libx264 @ 05A2C400] frame B:359   Avg QP:25.93  size:  8210
[libx264 @ 05A2C400] consecutive B-frames:  0.5%  0.5%  0.0%  8.2% 17.2% 52.2% 16.0%  5.5%  0.0%
[libx264 @ 05A2C400] mb I  I16..4:  5.4% 75.3% 19.3%
[libx264 @ 05A2C400] mb P  I16..4:  1.3% 16.5%  2.2%  P16..4: 36.3% 28.6% 12.7% 1.8%  0.2%    skip: 0.4%
[libx264 @ 05A2C400] mb B  I16..4:  0.4%  3.8%  0.3%  B16..8: 40.0% 18.4%  4.7% direct:18.5%  skip:13.9%  L0:45.4% L1:38.1% BI:16.5%
[libx264 @ 05A2C400] final ratefactor: 20.35
[libx264 @ 05A2C400] 8x8 transform intra:83.1% inter:68.5%
[libx264 @ 05A2C400] direct mvs  spatial:99.2% temporal:0.8%
[libx264 @ 05A2C400] coded y,uvDC,uvAC intra: 64.9% 83.4% 49.2% inter: 49.0% 50.4% 4.4%
[libx264 @ 05A2C400] i16 v,h,dc,p: 25% 22% 27% 26%
[libx264 @ 05A2C400] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 10%  7% 23%  9% 10% 10% 10%10% 13%
[libx264 @ 05A2C400] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 12% 11% 13%  9% 12% 11% 10% 9% 12%
[libx264 @ 05A2C400] i8c dc,h,v,p: 42% 28% 16% 14%
[libx264 @ 05A2C400] Weighted P-Frames: Y:18.4% UV:7.9%
[libx264 @ 05A2C400] ref P L0: 29.1% 11.3% 15.7%  7.3%  6.9%  4.9%  5.1%  3.4%3.9%  2.7%  2.8%  1.8%  1.7%  1.2%  1.4%  0.9%
[libx264 @ 05A2C400] ref B L0: 68.8% 11.4%  5.5%  2.9%  2.3%  1.9%  1.5%  1.1%1.1%  1.0%  0.9%  0.7%  0.5%  0.3%  0.1%
[libx264 @ 05A2C400] ref B L1: 91.9%  8.1%
[libx264 @ 05A2C400] kb/s:2055.88

As far as I'm concerned it doesn't look that bad to me.

2
  • 2
    Lossless presets will ignore your declared -b.
    – llogan
    Jan 21, 2012 at 0:26
  • 1
    I found a nice doc to help with finding good options.
    – sjngm
    Jan 21, 2012 at 18:39

1 Answer 1

10

You should first upgrade to at least FFmpeg 0.9. vpre is not really encouraged to be used for preset control anymore. This is why the ffpreset files have been removed from newer versions. Preset control for libx264 now happens through x264 itself, not through FFmpeg.

That being said, setting an average bitrate for x264 is the worst rate control mode there is. Rather than an average bitrate, you should consider using two-pass encoding if you are targeting a specific output file size, or setting a Constant Rate Factor (CRF) if you just care about achieving a specific quality. If in doubt, use CRF.


You generally want the following syntax for using FFmpeg and x264:

ffmpeg -i in.mp4 -vcodec libx264 <options> out.mp4

… with the following non-mandatory options. It is important to specify them before the output and after the vcodec switch. Those are just some (see also the options mapping for more):

  • -vprofile: Set h.264 profile constraints, e.g. baseline, main, high

  • -preset: Set an encoding preset, which generally enables optimization strategies. You can choose from veryslow, slow, fast, ultrafast, and many more. Slower presets result in better compression at a cost of slower encoding. You generally use the slowest preset you have patience for.

  • -tune: Set a special tune factor, e.g. for movies: film

  • -b: Set the bitrate. As already said, this is not really what you want with a one-pass encoding, but if you need to, this should work. Possible values are in Bits, or rather 500K, 1M, et cetera.

  • -crf: Set quality. Mutually exclusive with -b. A good starting value is 24. A lower value is higher quality. Use the highest value that still looks good to you.


Two-pass example, H.264 video, AAC audio in MP4:

ffmpeg -i input -c:v libx264 -preset slow -b:v 500k -pass 1 -an -f mp4 -y NUL
ffmpeg -i input -c:v libx264 -preset slow -b:v 500k -pass 2 -c:a libfaac -b:a 128k output.mp4

CRF example, H.264 video, MP3 audio in MKV:

ffmpeg -i input -c:v libx264 -preset medium -crf 24 -c:a libmp3lame -q:a 4 output.mkv

10
  • Also, if you still experience any problems, please post the full command line and the full FFmpeg / x264 output you get.
    – slhck
    Jan 20, 2012 at 23:45
  • Thanks a lot, that showed some new info to me! Please read my question as I appended my recent findings into it. It looks okay to me.
    – sjngm
    Jan 21, 2012 at 18:02
  • Regarding two-pass: if I use -vcodec libx264 as the only video-specific option for the second pass I get an error (maybe incorrect parameters such as bit_rate, rate, width or height). It works if I add -vb 1978k. So I have to add a bitrate-option. -minrate and -maxrate seem a little vague to me. Or is -vb okay for two-pass?
    – sjngm
    Jan 21, 2012 at 19:10
  • Some comments on your updated question: 1) MP3 isn't officially supported in MP4. 2) Use two-pass encoding if you are targeting a specific output file size and don't care about quality. Use CRF if you want to target a specific quality and don't care about file size.
    – llogan
    Jan 21, 2012 at 20:06
  • @LordNeckbeard Thanks for the edit. /dev/null won't work in Windows I guess, do you know what to use instead?
    – slhck
    Jan 21, 2012 at 21:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .