Your guide for achiving a "strict" CBR with obs.

If you're browsing this thread chances are you're not satisfied with the CBR that still spikes to very unpredictable bitrates resulting in ping problems or dropped frames, this is a guide to achieve a more "strict" CBR aswell as an explanation to why each setting would be helpful in this scenario.

Basically the setting we want to control/change here is the bufsize. we want to find a custom bufsize that the encoder is most aware of how to efficiently calculate CBR without blindly often dropping quality to try and keep the bitrate more less fluctuate.

(bitrate/fps) x (rc-lookahead - 1) = bufsize

What is rc-lookahead and how can i find this value ?
this describe the number of next frames the encoder consider as well as other factors before making a decision on the current frame size type and quality, you can directly control this setting by adding the custom encoder option rc-lookahead=number

Higher values/numbers are slower and the default used value depend on the preset you're using.
ultrafast 0, superfast 0, veryfast 10, faster 20, fast 30, medium 40.

So here's an example of a strict CBR 3000 bitrate 40fps stream,

3000/40 x 10 - 1 = 675

You can clearly see how the encoder started utilizing more of the small bframes and reducing frame sizes in general way before and as well as holding more data for the upcoming big key frame.

In general and in a constraint CBR scenario the more the bframes and lookahead the better, if you don't know how much is enough try adding tune=animation as a custom setting or you can control the maximum the encoder allow sequentially with the custom value bframes=number the maximum number you should ever use is 16 the default is 3.

tune=animation will allow the use of a couple more than the current but also tweaks other settings which also help with the motion scenes such as doubling the number of reference frames for the presets above "veryfast".

Also note that each additional bframe and lookahead frame you allow those also count as latency frames, So for example an rc-lookahead of 60 and bframes 16 on a 60 fps stream means about 1 second more delay.

(bitrate/fps) x (rc-lookahead - 1) = use the result as a custom bufsize
then add tune=animation as a custom encoder setting.
The suggestions here can be answered with a little experimentation on real video rather than guessing. I'm busy this weekend but I'm interested in this question generally. I'll try putting together some experiments to test these theories.

That said, At veryfast preset, changing the bframes setting has little effect. The default bframe algorithm (b-adapt=1) will almost always select 1 consecutive B-frame. That is, it usually produces IPBPBPBPBPBPBPBPBIPBPBPBPBPBPB... etc. b-adapt=2 does not kick in until slow preset, which is really only advised when streaming using a separate piece PC that's not involved in playing games, or for very low-resolution content (i.e. old SNES games played on an emulator).

Also believe setting bufsize so low would result in severely reduced quality (the encoder would end up dropping quality on a huge number of frames) and that a higher rc-lookahead will always produce a more stable bitrate holding all else constant. But I can answer these questions experimentally. ... handbrake/
tune=animation has greater effects on the slower presets because when used with +veryfast and aside from the quality increase the pframes can reference to more than just one frame, tune=animation will double the number if it's higher than 1 otherwise it doesn't change it that's why there's a significant change between the veryfast and slower presets (1 vs 2x2=4 and so on).

the b-adapt parameter is not a setting to define the maximum bframes to ever be used sequentially the bframes parameter is. What the b-adapt argument does is smartly check whether the next bframe is supposed to be placed or not. both the (1 and 2 ) algorithms will place up to 16 sequentially bframes if need be and allowed.. (check the graph i allowed 2+tune with b-adapt=1 for example). b-adapt 0 will always place 16 if you allow 16 bframes b-adapt=1 will do a quick check and place as much as it see's fit up 16 before inserting an iframe or pframe, b-adapt=2 is smarter and slower (how slow depends on the number you allow for it to check).


Active Member
I've been experimenting with this guide, and for rc-lookahead's greater than the default (at medium, which means > 40), it seems to result in more variability in bit rate, not less. I've tried rc-lookahead of 120, which at 3000 bitrate and 30 fps, results in a buffer size of 119000, and at rc-lookahead of 60, which at 3000 bitrate and 30 fps, results in a buffer size of 5900. The results are worse than just leaving the rc-lookahead at the default for medium, which means a buffer size of 3900 for a bitrate of 3000 and fps of 30.

The reason I've been trying rc-lookahead's greater than default is that the OpenCL feature is supposed to give free or reduced cost rc-lookahead, and for OBS that's all I'm aware that it does. Given that, it makes sense to try to increase it. But it results in more frames dropped than the default setting.
At 25/30 fps it's not really worth it going over rc-lookahead 60 for streaming, So in your example the 120 one looked better and spiked up to 8900 kbps compared to 6200 for the default.. but you'd better off instead increasing the bitrate/bufsize to 3500/1050 or even 4000/1200 and increase the lookahead to whatever you can afford because it'll still be helpful in deciding the frame quality ratio.


Active Member
I need to keep my bitrate at 3000 so that my tested 4200 upload won't be exceeded and I have plenty left over for the game communications and unavoidable bitrate variance. I simply plugged and chugged into your formula using 30 fps and 120 or 60 lookahead, with surprisingly poor results. Under what conditions would you say that your formula results in a more strict CBR rather than a more bursty one?
Like i said try the 3500/1050 if you want less bitrate variance while still having plenty left over for the game communications, the rc-lookahead parameter role in the formula is not for keeping the frames sizes more constant but more for making scenecut's and IDR frames not look too bad in combination with low bufsizes as explained earlier. a "formula" usually is composed of factors and if you raise a certain factor too much under a certain condition you should experience the negative effect.

Likewise with enough sustainable upload/bitrate factor you can easily ignore the lookahead part of the formula and achieve a 100% flat cbr instead but like you said you're limited by your upload so you still have to use "some" variance to achieve better results.

Also forget about speedtests set your bufsize to 1 (x264 will adjust automatically) and keep increasing the the bitrate by 200 increments until you notice a red flag, that should be your max sustainable upload for streaming to that ingest. or run shaper probe to get an idea of why your line get affected by burst's.
Is this method still worth using, or should we be just doing the following:
Enable CBR: Yes
Enable CBR Padding: Yes
Custom Buffer Size: No
The guide is worth using if you want to achieve a more strict CBR; the default settings (which you posted) do work just fine but are less strict in nature.
Kharay said:
The guide is worth using if you want to achieve a more strict CBR; the default settings (which you posted) do work just fine but are less strict in nature.
So then, to achieve a more strict CBR, would it be recommended to do the current guide's setup and enable CBR padding or leave CBR padding disabled with this setup? Also, which has better quality.


heros in an halfshel
The padding only does something if the encoded result is of less bit rate than the target bit rate you've set, and does not affect quality in any way. Also, the non-strict CBR is slightly better quality.

Read the tooltip for CBR padding, and act based on that information.
I tested setting recommended here for strict cbr. Result is very strange.
My settings:
CBR, CBR padding - enabled
CFR - enabled
bitrate 2300
bufsize 2668 = (2300/25)*(30-1)
fps 25
preset fast

Test video:
Twitch warning: The broadcast is not set to constant bitrate (CBR). [Current average: 1949 kbps, current max: 3399.0 kbps]
Bitrate floating from 703k to 3405k. Is it strict CBR?

11:34:31: Settings::Video: Disabling Aero
11:37:44: Settings::Video: Disabling Aero
11:38:58: Open Broadcaster Software v0.552b - 64bit ( ^ω^)
11:38:58: -------------------------------
11:38:58: CPU Name: Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz
11:38:58: CPU Speed: 3300MHz
11:38:58: Physical Memory:  16254MB Total, 13173MB Free
11:38:58: stepping id: 7, model 10, family 6, type 0, extmodel 1, extfamily 0, HTT 1, logical cores 4, total cores 4
11:38:58: monitor 1: pos={0, 0}, size={1920, 1080}
11:38:58: monitor 2: pos={-1280, 0}, size={1280, 1024}
11:38:58: monitor 3: pos={-2304, 0}, size={1024, 768}
11:38:58: Windows Version: 6.1 Build 7601 S
11:38:58: Aero is Disabled
11:38:58: -------------------------------
11:38:58: OBS Modules:
11:38:58: Base Address     Module
11:38:58: 000000003F940000 OBS.exe
11:38:58: 00000000E7590000 OBSApi.dll
11:38:58: 00000000E7550000 DShowPlugin.dll
11:38:58: 00000000E79D0000 GraphicsCapture.dll
11:38:58: 00000000E7530000 NoiseGate.dll
11:38:58: 00000000E7510000 PSVPlugin.dll
11:38:58: ------------------------------------------
11:38:58: Adapter 1
11:38:58:   Video Adapter: NVIDIA GeForce GTX 570 
11:38:58:   Video Adapter Dedicated Video Memory: 1293352960
11:38:58:   Video Adapter Shared System Memory: 2952671232
11:38:58: ------------------------------------------
11:38:58: Adapter 2
11:38:58:   Video Adapter: Intel(R) HD Graphics 3000
11:38:58:   Video Adapter Dedicated Video Memory: 67108864
11:38:58:   Video Adapter Shared System Memory: 1711276032
11:38:58: =====Stream Start: 2013-08-24, 11:38:58===============================================
11:38:58:   Multithreaded optimizations: Off
11:38:58:   Base resolution: 1920x1080
11:38:58:   Output resolution: 1280x720
11:38:58: ------------------------------------------
11:38:58: Loading up D3D10 on NVIDIA GeForce GTX 570...
11:38:58: Playback device {}.{57cf455d-1699-45c4-a653-35f138f6e200}
11:38:58: ------------------------------------------
11:38:58: Using desktop audio input: Line 2 (Virtual Audio Cable)
11:38:58: ------------------------------------------
11:38:58: Using auxilary audio input: Микрофон (5- Logitech G35 Headset)
11:38:58: ------------------------------------------
11:38:58: Audio Encoding: AAC
11:38:58:     bitrate: 160
11:38:58: Using Monitor Capture
11:38:58: ------------------------------------------
11:38:58: Video Encoding: x264
11:38:58:     fps: 25
11:38:58:     width: 1280, height: 720
11:38:58:     preset: fast
11:38:58:     CBR: yes
11:38:58:     CFR: yes
11:38:58:     max bitrate: 2300
11:38:58: ------------------------------------------
11:38:58: MMDeviceAudioSource: Frequency for device 'Line 2 (Virtual Audio Cable)' is 352800, samples per sec is 44100
11:38:58: MMDeviceAudioSource: Frequency for device 'Микрофон (5- Logitech G35 Headset)' is 176400, samples per sec is 44100
11:38:58: Bad timestamp detected, syncing audio to video time
11:39:01: Using RTMP service: Twitch /
11:39:01:   Server selection: rtmp://
11:39:01:   Interface: Intel(R) 82579V Gigabit Network Connection (ethernet, 1000 mbps)
11:39:03: SO_SNDBUF was at 8192
11:39:03: SO_SNDBUF is now 65536
11:39:33: Total frames rendered: 849, number of late frames: 3 (0.35%) (it's okay for some frames to be late)
11:39:33: Total duplicated frames to ensure constant framerate: 0 (0.00%)
11:39:33: RTMPPublisher::SocketLoop: Graceful loop exit
11:39:33: Number of times waited to send: 0, Waited for a total of 0 bytes
11:39:33: Number of b-frames dropped: 0 (0%), Number of p-frames dropped: 0 (0%), Total 0 (0%)
11:39:33: Profiler results:
11:39:33: ==============================================================
11:39:33: frame - [100%] [avg time: 5.059 ms (cpu time: avg 3.289 ms, total 2792.42 ms)] [avg calls per frame: 1] [children: 99.9%] [unaccounted: 0.0593%]
11:39:33: | frame preprocessing and rendering - [71.9%] [avg time: 3.638 ms (cpu time: avg 1.984 ms, total 1684.81 ms)] [avg calls per frame: 1] [children: 63.1%] [unaccounted: 8.84%]
11:39:33: | | scene->Preprocess - [63.1%] [avg time: 3.191 ms (cpu time: avg 1.8 ms, total 1528.81 ms)] [avg calls per frame: 1]
11:39:33: | video encoding and uploading - [28%] [avg time: 1.418 ms (cpu time: avg 1.304 ms, total 1107.61 ms)] [avg calls per frame: 1] [children: 26.6%] [unaccounted: 1.42%]
11:39:33: | | flush - [1.44%] [avg time: 0.073 ms (cpu time: avg 0.11 ms, total 93.602 ms)] [avg calls per frame: 1]
11:39:33: | | CopyResource - [0.158%] [avg time: 0.008 ms (cpu time: avg 0 ms, total 0 ms)] [avg calls per frame: 0]
11:39:33: | | conversion to 4:2:0 - [11.7%] [avg time: 0.591 ms (cpu time: avg 0.643 ms, total 546.003 ms)] [avg calls per frame: 0]
11:39:33: | | call to encoder - [12.8%] [avg time: 0.646 ms (cpu time: avg 0.459 ms, total 390.004 ms)] [avg calls per frame: 0]
11:39:33: | | sending stuff out - [0.553%] [avg time: 0.028 ms (cpu time: avg 0.073 ms, total 62.4 ms)] [avg calls per frame: 0]
11:39:33: ==============================================================
11:39:33: =====Stream End: 2013-08-24, 11:39:33=================================================
dodgepong said:
According to that log, you are not using a custom buffer size.
No. I used custom buffer size. It sounds like bug in OBS log, because x264 settings of file downloaded from twitch are following:

cabac=1 / ref=2 / deblock=1:0:0 / analyse=0x3:0x113 / me=hex / subme=6 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=1 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=3 / b_pyramid=2 / b_adapt=1 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=1 / keyint=50 / keyint_min=5 / scenecut=40 / intra_refresh=0 / rc_lookahead=30 / rc=cbr / mbtree=1 / bitrate=2300 / ratetol=1.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / vbv_maxrate=2300 / vbv_bufsize=2668 / nal_hrd=cbr / ip_ratio=1.40 / aq=1:1.00

You can check it very easy. Just use following guide Then switch several times between any static screen and script from that guide. It will generate huge difference between bitrate. I found only one path to strict cbr - set buffer size to bitrate/fps and don't understand how possible to achieve strict cbr by multiplying to (rc_lookahead-1).
Your fps is very low for the frames to lookahead especially when considering the new small GOP requirement and the extreme bitrate test of that scene, as a result the settings should end up achieving a higher quality not a more strict bitrate.

Use ratetol=0.01 and 2300=>bufsize if you want to get ride if the twitch warning at the cost of quality.