Building OBS Studio (Windows 10, 64-bit)

  • Download Visual Studio 2017 Community Edition
  • Download the VS2017 dependencies zip file: https://obsproject.com/downloads/dependencies2017.zip.
  • Extract the contents of the zip file to C:\obs-deps
  • Download Qt version >= 5.9, and install in C:\Qt
  • Follow the official OBS Studio Windows install instructions here: https://github.com/obsproject/obs-studio/wiki/Install-Instructions#windows-build-directions.
  • Open up cmake-gui.
  • Where is the source code: /path/to/obs-studio
  • Where to build the binaries: /path/to/newly/created/build/directory
  • Click + Add Entry. Add the following entries:
    • DepsPath, PATH, C:\obs-deps\win64\include
    • QTDIR64, PATH, C:\Qt\5.x\msvc2017_64
    • (Optional) FFmpegPath, PATH, C:\obs-deps\win64\include
    • (Optional) x264Path, PATH, C:\obs-deps\win64\include
    • (Optional) curlPath, PATH, C:\obs-deps\win64\include
  • Press Configure. IMPORTANT Select the generator corresponding to both Visual Studio 2017 and Win64, Visual Studio 15 2017 Win64. If you don’t select the Win64 version, the build won’t work properly because you’ll be targeting a 32-bit architecture.
  • Press Generate.
  • Go to the build directory that you specified. Open up ALL_BUILD.vcxproj.
  • In the Solution Explorer, right click the Solution called obs-studio. Click Build Solution.
  • Once the Output window indicates that the Build: 41 succeeded, 0 failed, 0 up-to-date, 0 skipped, go to /path/to/build/rundir/Debug/bin/64bit/. Inside, you’ll find obs64. Open that executable file to run OBS Studio. Congrats!

Building OBS Studio (macOS)

cd obs-studio
mkdir build
cd build
cmake .. && make

If this doesn’t work, you might need to set CMAKE_PREFIX_PATH. See link.

Video Subsystem

Question

I’m using 1fps, zerolatency, and 1 second key frames. When streaming a dummy video directly to my server with ffmpeg using the same x264 settings, the delay is almost non-existent. Can someone point me to the parts of OBS source code so I can maybe recompile and make OBS work for my (weird) use case?

From Jim, creator of OBS

not sure, the audio latency is already as minimal as can be, although you may gain up to a second of audio latency depending on what you do. the audio latency is designed to dynamically increase, but only as needed kind of a complex system I wrote to ensure minimal audio latency

what’s probably getting you there is the video subsystem. running OBS at 1fps means that you’re going to see an effect there, because it waits a frame between certain video subsystem actions(edited)

first it renders the backbuffer, then waits a frame. then it converts the backbuffer to YUV, which may require another frame or two to process in full

basically, it’s solely the fact that you’re running at 1fps that’s causing the problem, and due to the fact that there’s always a minimum of 2-4 frames buffering

unless you performed every one of the video subsystem actions all at once (which would stall the graphics pipeline), you’re not going to be able to do anything about it

rendering, conversion, queueing

unless you’re educated with graphics programming it’s probably not going to be something that you’re going to be able to fix easily on your own for FFmpeg, it does not need to do any of those things. it can just decode whatever you’re doing and convert on the spot, typically via CPU there is no waiting for the GPU

so you’re going to naturally get a more instant result there that 1fps thing is just what’s getting you

oh, and it waits a frame for frame download from the GPU so it’s 1FPS in conjunction with the compositor’s graphics render/conversion/download actions

at least 3-4 frames are going to be buffered so at 1fps, always going to have 3-4 seconds of latency

you could get it all done in one frame on-the-spot, just would require graphics knowledge and some tinkering with the backend.

obs.c, obs-video.c and obs-internal.h I would be willing to point you to the variables and lines, but after that I’d have to let you take it from there

Question:

does that mean if I use like 5fps i’ll get better latency?

Jim:

https://github.com/obsproject/obs-studio/blob/master/libobs/obs-internal.h#L230-L237 these are the key variables. Yes, higher FPS would give you lower latency just due to that nature

search for those variables in this file: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-video.c the file is only 700 lines, so the video backend isn’t too terribly complicated. you’ll note lines like this: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-video.c#L218

this is how it waits initially: prev_texture and cur_texture. Each buffer has two textures.

frame 1 for example would render the backbuffer to obs_core_video::render_textures[0], then it would stop action.

frame 2 would render the backbuffer to obs_core_video::render_textures[1], then would convert obs_core_video::render_textures[0] to YUV to obs_core_video::convert_textures[0].

frame 3 would render the backbuffer again in to obs_core_video::render_textures[0], then would convert obs_core_video::render_textures[1] to YUV to obs_core_video::convert_textures[1], and then would download obs_core_video::convert_textures[0] to obs_core_video::output_textures[0].

frame 4 would render the backbuffer again in to obs_core_video::render_textures[1], then would convert obs_core_video::render_textures[0] to YUV to obs_core_video::convert_textures[0], then would download obs_core_video::convert_textures[1] to obs_core_video::output_textures[1], and finally queue obs_core_video::output_textures[0] in the encoder thread to be sent to the video encoder and then output so you can see how it alternates

you could change #define NUM_TEXTURES 2 to #define NUM_TEXTURES 1 at the top of obs-internal.h, and then modify the back-end to do everything all at once in obs-video.c

without waiting a frame each time for the previous action to complete

although just be warned – it will stall the graphics pipeline. but for 1fps output, I suppose it wouldn’t be a huge deal for you. might even just be able to set NUM_TEXTURES to 1 and have it function like that automatically. although I don’t think it’s really programmed to handle values less than 2, aka 1

everything that’s done in the graphics thread is done to minimize any potential GPU stalling, and maximize performance at the cost of that latency people don’t normally run the program below 30 FPS, so that latency is typically no more than 133 milliseconds

Question:

In this 4-frame process, wouldn’t at any given moment starting on the 4th frame, the GPU is doing all 4 steps at once anyways?

Jim:

you mean is it doing all four steps after the fourth? yea. because it’s reached full cycle of alternation

Question:

yeah, so then why won’t the GPU stall at the 4th frame?

Jim:

because the frames for each buffer have been filled the previous frame at step one, it can only render the backbuffer, but it cannot perform the next step without stalling the GPU or rather, without risking a stall each step requires at least one frame of breathing room, so to speak one it’s reached the fourth frame, it can just alternate between the frames for each step to have that breathing room. no matter what, the last step will always work on frame data that is essentially four frames old

when you call graphics functions, internally they are put in a queue on the graphics card. when you do all four steps at once, it requires it to execute all actions that have been queued up until that point. the program itself will have to sit there and wait for the GPU to execute those actions causing the program to stall for your case it’ll probably be fine, but at higher framerates, it would basically ruin performance because the program will be sitting there waiting for the graphics card, and the graphics card will have a lot of inefficient idle time a better way to make an analogy may be to think of a factory: let’s say you have a conveyer belt to build items

and now let’s say the product requires multiple steps to complete. like let’s say you need to build the product, and that requires four steps a factory normally has it to where each step is performed separate on the conveyer belt that way it can perform each step on a different item at the same time rather than have it stop the entire conveyer belt and force it to wait while it does all four steps on a single item at a time it improves the efficiency of the line same thing for rendering

Glossary

  • Solution - A solution is a structure for organizing projects in Visual Studio. Suffix is .sln. https://msdn.microsoft.com/en-us/library/bb165951.aspx
  • Project - a project contains of all the source code files, icons, images, data files and anything else that will be compiled into an executable program or web site. Suffix is .vxproj. https://msdn.microsoft.com/en-us/library/b142f8e7.aspx