OBS Studio
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 upALL_BUILD.vcxproj
. - In the
Solution Explorer
, right click the Solution calledobs-studio
. ClickBuild Solution
. - Once the
Output
window indicates that theBuild: 41 succeeded, 0 failed, 0 up-to-date, 0 skipped
, go to/path/to/build/rundir/Debug/bin/64bit/
. Inside, you’ll findobs64
. 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
andcur_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 convertobs_core_video::render_textures[0]
toYUV
toobs_core_video::convert_textures[0]
.
frame 3 would render the backbuffer again in to
obs_core_video::render_textures[0]
, then would convertobs_core_video::render_textures[1]
toYUV
toobs_core_video::convert_textures[1]
, and then would downloadobs_core_video::convert_textures[0]
toobs_core_video::output_textures[0]
.
frame 4 would render the backbuffer again in to
obs_core_video::render_textures[1]
, then would convertobs_core_video::render_textures[0]
toYUV
toobs_core_video::convert_textures[0]
, then would downloadobs_core_video::convert_textures[1]
toobs_core_video::output_textures[1]
, and finally queueobs_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 ofobs-internal.h
, and then modify the back-end to do everything all at once inobs-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