13

I'm trying to encode a video with ffmpeg into H.264 (via the libx264 library) with a constant bit rate. I know, I know, VBR is often preferred, but for this specific job I'm required to use CBR (just as long as it's so many kilobytes per second; it doesn't have to be an exact kilobytes per frame, afaik). My sample video I'm using to test is from here: http://a1408.g.akamai.net/5/1408/1388/2005110403/1a1a1ad948be278cff2d96046ad90768d848b41947aa1986/sample_iTunes.mov.zip (it comes from http://support.apple.com/kb/HT1425)

I can get a constant bit rate when encoding the video with MPEG-4 Video (using the commands ffmpeg -i sample_iTunes.mov -b 819968 -minrate 819968 -maxrate 819968 out.mov), and the bit rate is as expected. Reading the video's specs via the QuickTime Inspector, it's got a data rate of 844.94 kbit/s. Cool.

However, when I change the codec to libx264, it seems to completely ignore my bitrate requests! The command I'm trying is "ffmpeg -i sample_iTunes.mov -vcodec libx264 -vpre medium -b 819968 -vb 819968 -minrate 819968 -maxrate 819968 -bufsize 400000 test.mov". But when I check the video's specs via the QuickTime Inspector, it's got a data rate of 254.74 kbit/s. WTF? That's not even close!

I've tried changing so many parameters and adding tons of different things, and I've spent 2 days googling this, but I can't seem to get it to work. If I encode the video with the MainConcept H.264 encoder, I can get a constant bitrate, but I need this to work with ffmpeg.

If someone can help me figure out how to do CBR H.264 encoding with FFmpeg, I will love you forever!

Cornstalks
  • 131
  • 1
  • 1
  • 3

4 Answers4

7

I too have been working on trying to get CBR out of x264. I found this blog post by Dark Shakari quite interesting.

Here is what I have for low-latency CBR video to an MPEG tranport stream:

ffmpeg -i sintel_trailer-720p.mp4 -an -tune zerolatency \
       -x264opts bitrate=4000:vbv-maxrate=4000:vbv-bufsize=166 \
       -vcodec libx264 -f mpegts -muxrate 4000K -y trailer.ts

According the x264 developer's blog you set:

  • vbv-maxrate = bitrate = B = target bitrate
  • vbv-bufsize = B / fps (in this video's case that's 24 fps)

Finally, set the ffmpeg switch for x264 of -tune zerolatency.

Hope that's helpful. And, if anyone has improvements to this please do let me know!

David Riccitelli
  • 7,491
  • 5
  • 42
  • 56
mevatron
  • 13,911
  • 4
  • 55
  • 72
  • 3
    I'm still seeing considerable variability with those options. However, +1 because it lead me to the one option that actually helps in my situation, `-muxrate`. This adds null-stuffing to the transport stream to try and achieve your CBR goals. It's not perfect, but it gets me close enough. As far as I can tell, `ffmpeg` really doesn't support CBR at all. Min=avg=max doesn't work, either. Null-stuffing is as close as you can get. – Warren Young Sep 20 '12 at 01:55
  • I am able to get close to a CBR using these options so +1. When set to 4000K, I'm getting 4000, 3999.9 and 3999.8, so not quite CBR but damn close! – zgr024 Nov 07 '13 at 20:00
  • What if you need 23.976 FPS for audio sync issues? Your command creates a file with out of sync audio – Freedo Mar 30 '21 at 08:34
4

Specify -nal-hrd cbr after -bufsize 400000.

Timothy003
  • 2,348
  • 5
  • 28
  • 33
0

This may be a clue (assuming you have a bitrate set) "CBR is when maxrate == bitrate and bufsize is set" http://ffmpeg-users.933282.n4.nabble.com/Does-constant-bitrate-exist-in-libx264-td2255554.html

bufsize is supposed to be the "receiving client's" max buffer size.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
0

Ok, so I think I may have found part of the problem. Making -bufsize greater than the data rate seems to have solved the problem. Of course, I don't know if it's encoding real CBR, but the data rate that Quick Time Inspector reads looks right now.

Cornstalks
  • 131
  • 1
  • 1
  • 3