xObsAsyncImageSource - Asynchronous image source

xObsAsyncImageSource - Asynchronous image source v1.0

Supported Bit Versions
  1. 64-bit
Source Code URL
https://github.com/YorVeX/xObsAsyncImageSource
Minimum OBS Studio Version
29.0.0
Supported Platforms
  1. Windows
  2. Linux

xObsAsyncImageSource​

OBS plugin providing an image source that loads images asynchronously (causing a lot less lag on load).
1676874830796.png


Prerequisites​

  • OBS 29+ 64 bit
  • Windows
    • tested only on Windows 10, but Windows 11 should also work
  • Linux
    • occasionally tested, but not regularly
    • binary build created on Ubuntu 20.04 WSL environment, therefore linked against glibc 2.31

Comparison to original image source​

Less lag and dropped frames​

The original image source can cause short freezes of OBS (aka lags) when loading images, to be more precise it will often make OBS drop frames and cause the counter "Frames missed due to rendering lag" to increase, you can view this statistic in the window shown by selecting "View" and "Stats" from the OBS main window.

The async image source will be a lot less likely to cause this.

Loading behavior​

While the async image source is still busy loading an image it simply keeps on showing whatever it was showing previously.

If it was hidden or didn't have any image file configured (or an invalid/missing file) it will show nothing, if it was showing a different image then it will keep on showing this image until it finished loading the new image.

This behavior will ensure a smooth transition from one image to another (as opposed to causing flickering if the old image would always be hidden while loading a new one).

If another image load is already triggered while the previous image load wasn't finished the previous load will be aborted in favor of the new one.

If loading fails the async image source will keep on trying to load the image every second. This way if the file was locked during the last load attempt (e.g. happens when it is updated at the exact time the image source tries to read the file) it will be updated a second later (whereas the original image source would never recover from this until the image file is updated once more).

Usage scenarios​

You should prefer this image source over the original one whenever images are not only (re-)loaded once on startup of OBS but also during runtime. This is the case when:

  • you have "Unload image when not showing" activated on one or more images and hide/show these images during a session
  • image files shown by an image source change during a session
  • you sometimes add new image sources during a session
  • you sometimes open the properties of image sources during a session (changing nothing and clicking cancel triggers a reload)
If you only use images that were loaded at startup and are either visible all the time or have "Unload image when not showing" unchecked if you hide/show them throughout a session this async source doesn't give you any benefits. Well, almost. Even during initial load with OBS startup the original image source can cause unnecessary audio buffering increases (the infamous "adding X milliseconds of audio buffering" in your log) while the async image source is a lot less likely to trigger this.

Technical background​

The original image source loads images on the main thread, blocking all rendering in OBS while it is busy loading the image. 30 FPS mean that OBS has ((1 / 30) * 1000 =) 33,33... ms time to render each frame, with 60 FPS this drops to 16,66... ms and so on. In my tests loading even relatively small images took anything from 40 to 80 ms, an animated image even 200+ ms.

This means that while loading an image OBS will almost certainly have to drop frames because it cannot render them on time. Combine this with the fact that OBS doesn't react well to rendering lag and you're in trouble, even more so if you use secondary outputs like NDI or Teleport. When reporting OBS problems caused by lag the first advice you will get is most probably that you should eliminate the source of the lag. This advice of course is correct, but what do you do if it's caused by loading images that you need to be loaded?

This async image source uses exactly the same OBS internal loading/decoding/rendering functions for the images (in fact large chunks of the code are a 1:1 copy of the original image source code), with the one difference that the functions which take the most time during loading an image are executed asynchronously on a separate thread instead of the main OBS thread. Also working multi-threaded introduces some complexity, i.e. extra code to eventually synchronize things back to the main thread after loading was finished.

Usage​

Installation​

Before installing make sure that OBS is not running.

For portable mode simply extract the .7z file into the root directory of the portable folder structure. For regular OBS installations see the operating system specific instructions below.

For automatic installation just run the provided installer, then restart OBS.

For manual installation extract the downloaded .7z file (= copy the contained obs-plugins and data folders) into the OBS Studio installation directory. The default location for this is
C:\Program Files\obs-studio
This needs admin permissions.

The folder structure in the downloaded .7z file is prepared so that you can extract the file (= copy the contained files) into your user home and on many systems this will just work already.

However, depending on the distribution and OBS installation method (manual, distro repo, snap, flatpak...) the location of this folder can vary, so if it doesn't work from the user home you might have to look around a bit.

Example locations for the plugin .so (and .so.dbg) file are:
~/.config/obs-studio/plugins/ (The structure the .7z is prepared for)
/usr/lib/obs-plugins/
/usr/lib/x86_64-linux-gnu/obs-plugins/
/usr/share/obs/obs-plugins/
~/.local/share/flatpak/app/com.obsproject.Studio/x86_64/stable/active/files/lib/obs-plugins/
/var/lib/flatpak/app/com.obsproject.Studio/x86_64/stable/active/files/lib/obs-plugins/

Unfortunately the expected location of the locale, which can be found in the data folder, can vary also.
If you get missing locale errors from the plugin you can try to copy the "locale" folder found inside the data folder to:
/usr/share/obs/obs-plugins/<plugin name>/locale
~/.local/share/flatpak/app/com.obsproject.Studio/x86_64/stable/active/files/share/obs/obs-plugins/<plugin name>/locale
/var/lib/flatpak/app/com.obsproject.Studio/x86_64/stable/active/files/share/obs/obs-plugins/<plugin name>/locale

If in doubt, please check where other "en-US.ini" files are located on your system.

The steps to update an older version of the plugin to a newer version are the same, except that during file extraction you need to confirm overwriting existing files in addition.

Settings​

After installation add a source just like you would add the original image source, but instead select "Image (Async)" from the list of available source types.

image

Configuration is exactly the same as for the original image source.

Convert all existing image sources​

If you want to convert all your existing standard image sources to async image sources at once

  • close OBS in case it is running
  • make a backup of your scenes .json file
  • open your scenes .json file in a text editor and replace all occurrences of "image_source" with "xObsAsyncImageSource" (in both cases including the quotes)
  • start OBS and your image sources should have been converted
To verify whether the conversion was actually applied click the plus icon to add a new source, select "Image (Async)" and check the list under "Add Existing", it should list your existing image sources.

FAQ​

  • Q: Will my OBS completely stop dropping frames when loading images with this source?
    A: Under ideal conditions yes, but that depends a lot on your system and configuration. If your computer is already maxing out its CPU usage even before the image load and/or you load a really large image you could still get lags/dropped frames, albeit a lot less compared to the original image source. E.g. in my tests when running OBS at 60 FPS and loading an unusually complex and big 5000x5000 .png file the original source would drop ~50 frames while the async image source would drop 5.

  • Q: Why is the plugin file so big compared to other plugins for the little bit it does, will this cause issues?
    A: Unlike other plugins it's not written directly in C++ but in C# using .NET 7 and NativeAOT (for more details read on in the section for developers). This produces some overhead in the actual plugin file, however, the code that matters for functionality of this plugin should be just as efficient and fast as code directly written in C++ so there's no reason to worry about performance on your system.

  • Q: Wow, that's cool, can I also have this for image slide show sources?
    A: OBS 30.1.X or higher has a reworked slideshow that also loads images asynchronously. If you don't want to wait, you can get the current beta of it from here.


  • Q: Will there be a 32 bit version of this plugin?
    A: No. Feel free to try and compile it for x86 targets yourself, last time I checked it wasn't fully supported in NativeAOT.

For developers​

C#​

OBS Classic still had a CLR Host Plugin, but with OBS Studio writing plugins in C# wasn't possible anymore. This has changed as of recently with the release of .NET 7 and NativeAOT it is possible to produce native code that can be linked with OBS.

Source code is available, I hope it can be a starting point for other C# developers who also want to look into OBS plugin programming using .NET 7 and NativeAOT.

Credits​

Many thanks to kostya9 for laying the groundwork of C# OBS Studio plugin creation, without him this plugin (and hopefully many more C# plugins following in the future) wouldn't exist. Read about his ventures into this area in his blog posts here and here.
Author
YorVeX
Downloads
6,767
Views
10,259
First release
Last update
Rating
5.00 star(s) 6 ratings

More resources from YorVeX

Latest updates

  1. Added Windows installer

    Added an installer for Windows to the downloads
  2. Version 1.0

    - Bumped version to v1.0 since this has been stable and reliable long enough now - Added text...
  3. Version 0.4

    Added Linux support

Latest reviews

I will test this and strongly believe that this is needed to further reduce the main causes of stuttering. 5 stars indeed!
I just downloaded and didn't test it yet, but I want to thank you even before testing it. I have a really complex OBS setup (hundreds of scenes with stages the people can interact with) and I can't get rid of frame drops when loading sources. Please, take in consideration expanding this concept to do a replacement of Multimedia Source, it's also a pain in the ass. Let's hope someday OBS developers update their pipeline to make all source load async. Thank you a thousand times! You're legend!
This thing is amazing!
If you are running a lot of Pictures and use the "Unload image when not showing" option, this Plugin is a must-have!

Same as @dynamiteandy, would love to have this for Media-Sources too, as i use these mostly for some GIF's instead of image-source.

Would even pay for it :D
Amazing! I have been looking for this for a long time!
Just registered to give you a 5 star rating for this and thank you for this! Any plans to do it for a media source too :D?
YorVeX
YorVeX
Thanks a lot, much appreciated! Since I am also suffering from similar issues with the media source the thought has crossed my mind, but I haven't looked into it yet to figure out how much effort it would take, so no promises at this point.
Top