Thanks to the workaround in obs::tools, gfx::shader::shader now supports dynamically rebuilding the properties with new properties without crashing OBS Studio. This effectively allows you to have an up to date view of the current parameters for the shader technique.
Additionally with file watching, live development of shaders is possible at very little cost. Currently only file times and size is looked at every 333ms, but in the future it is possible to also watch for file renames and more.
The current implementation of obs_properties_remove_by_name corrupts the obs_properties_t object whenever it is called on the first or last property in the list. This leads to rapid unscheduled disassembly, and therefore must be fixed in order for this function to be used.
Fixed by upstream PR https://github.com/obsproject/obs-studio/pull/2257.
Removes the stutter when re-opening the properties dialog which was caused by recompiling the same exact shader every time this happened. Also paves the way for simple file watching.
Getting the resolution of a source is very expensive in libOBS, as libOBS does not cache it and instead always calls into the filters and sources to determine the actual source. This also leads to potential lockups due to the filter list mutex being locked for the target source.
Therefore instead of calling it multiple times, cache the result of the call, if that result is even necessary. This reduces the need to synchronize lightly parallelized work (UI and libOBS code) and helps against the potential race condition in libOBS.
Prevents the use of get() and reset() where not actually needed and forces us to actually implement all of the methods needed to interface with the object, leading to cleaner and safer code.
These two wrap the underlying gs_epass and gs_effect_technique objects, to allow direct and improved access to them without relying on the libobs API to provide this access for us. Additionally these make it safe for us to use them instead of relying on C-like code to deal with it.
This drastically improves stability and prevents all exceptions from leaking into libobs C code, which prevents crashes and unexpected freezes from exception handlers further down the stack.
Additionally minor work was done to further improve the quality and user experience for the filter.
Caching the output of a source is only necessary for really expensive to render sources, so it is disabled by default now. Thanks to that, most Source Mirrors are now "free" instead of requiring two context switches and a texture, while those really expensive can be manually set to cache.
The scaling mode is also set to disabled instead of point when rescaling is off to further improve performance. The previous method would incorrectly cause an extra texture to be used.
Additionally we now have support for debug markers for graphics debugging, allowing us to exactly tell apart improvements in rendering cost for this source.
This class and template should be used to reduce the code clutter from repeatedly doing the same thing. It requires OBS v24.0 or newer since the get_properties2 and get_defaults2 API were fully implemented with it.
This is a massive improvement to stability and safety when using the plugin, as all exceptions should now no longer be leaked into C controlled code, which can't actually handle exceptions at all.
Warnings fixed:
* Potentially throwing exception during library load.
* Possibly throwing function passed to C.
* Statement does nothing.
* Variable is initialized but not referenced.
* Variable overloads variable in parent scope.
It is extremely problematic to throw C++ exceptions into C code, especially because C code usually does not handle C++ exceptions at all. Therefore we have to prevent any exception from leaving the function and define it as noexcept.
The util::event code suffers from the problem that it could call into a class that no longer exists, corrupting memory or even crashing. By tracking lifetime using std::weak_ptr<void> this can be avoided and the dead listeners can be automatically removed.
This fixes the case where the effect vanishes, but we still hold an invalid pointer to a parameter of that effect. With the new code, the effect will not vanish as long as an effect pointer exists.
However, all effects must be created either through std::shared_ptr or std::make_shared. If they were not made through one of those means, the code will crash on the ->shared_from_this() call.
Adds a new property to control the alignment of the source within the calculated boundary when rescaling the source. Also fixes the permanently left aligned mirror at the same time.
Similar to the one used in enc-amf, allows looking up string containing other strings, thus drastically simplifying the necessary time to build translated strings, while also caching them for future use.
When copying or re-ordering filters, an occasional crash can be observed due to the rendering not being possible yet. With this, it will simply revert back to the original source instead of crashing.
Fixes the bug that rendering an outline would remove all other effects not directly under the outline, while also improving the rendering speed drastically by only initializing and clearing the rendertarget once instead of for each effect.
This filter allows the use of another source as a mask, allowing complex filter graphs and trippy effects, such as creating a text source with three animated videos, each using a different color channel as the mask.
Fixes#18.
When a source was renamed, obs::source_tracker did not use the new name and instead relied on the old name. This caused source lists with this feature to slowly degrade over time as sources were renamed, until libobs was restarted.
With this fix the renamed sources are now properly tracked, updating as expected.
Related Issue: #64
Clang on Windows and Clang on Linux behave differently, and of course GCC on Windows (MinGW) and GCC on Linux do too. This is the point where using either compiler on either platform should successfully compile the project without any issues.
Clang and GCC have a ton of warnings however, which definitely need to be fixed in the near future. Some of them are great warnings, like old C style casts, others are non-sense like suggest brackets.
Fixes#47Fixes#60
Automatically updates the long description (hover text) if the Type or Subtype field is changed, allowing for more contextual information about what the selected information does.
This refactors the SDF Effects to use a normal blend function instead of doing the blend in the effect itself, improving quality and reducing problematic sampling issues. In addition to this, the effect files have been cleaned up slightly and renamed to their proper names. Glow and Stroke are now supported, which solves both #2 and #4 in one go.
The caching optimization has also now been implemented, reducing the number of renders for this filter to 1 for each tick.
This fixes a dead lock due to attempting to lock the same filter mutex twice, causing libOBS to completely lock up on every mutex. This extends the fix for 4fc25cfd8d.
Additionally this switches to a proper queue system for audio, so we no longer cause audio stuttering or audio skipping.
To further distance the code from having to do too much manually, the graphics context is now available as a managed class. All places that previously used obs_enter_graphics and obs_leave_graphics are now using the new gs::context class instead.
libOBS will simply forget to unlock a mutex if you set the boundary size to zero, resulting in the filters dialog for that source simply getting stuck. Why video rendering can affect the audio filter dialogs is a question for another time, but it's best to just accept it and move on.
Previously this would not do anything correctly, as the call to obs_source_get_flags does not return anything for most sources. Instead obs_source_get_output_flags should be used to verify that we actually have a video or audio capable source to work with.
obs::source_tracker allows us to do more over more versions of OBS Studio, so we are able to enumerate any and all Sources, Scenes and Transitions that weren't created private. If we were to rely on libOBS for this, we would need to limit ourselves to version 23 or higher, but with this we can go very far back - as far back as the global event system was fully supported.
Audio capture previously needed an additional class, however there is no need for this if this can be done together with the actual obs::source object. So obs::source now has a new audio_data event that can be listened to, which handles capturing audio data if requested.
Additionally all other events are now selectively listened to, instead of permanently listening to them. This should drastically reduce the overhead of using obs::source.
Dual Filtering (or Dual Kawase) is an approximation of Gaussian Blur that can reach much higher Blur sizes at a much lower cost. However it is locked to a 2^n size, which means that currently it isn't possible to use it for blur sizes like 19, 24 and 31.
The Blur works by using the linear sampling of a GPU, combined with down- and upsampling and carefully placed sampling points. This means that there is no need for a linear optimized version of this Blur.
Related: #45, #6
While Gaussian Blur is not a Blur type that really benefits much from linear sampling, it can be used for a slight quality and gpu usage reduction. However for Area and Directional Blur there is a better alternative: Dual Filtering Blur. And as with all other currently implement Linear versions of Blur, only Area and Directional Blur are supported.
This type of Gaussian Blur also has the loading hitch that exists in normal Gaussian Blur.
Related: #45, #6
Gaussian Blur is another Blur that now supports the new system, increasing the maxium Blur size to 128 and adding support for Rotational and Zoom blur. Various optimizations were done to the actual shader code which further reduced the GPU usage.
Currently the Gaussian curve is recalculated when the blur is first created, which can lead to a short hitch due to it having to search for the correct kernels. This is currently unavoidable and expected behavior until a better solution is found.
Related: #45, #6
Box Blur is a prime candidate for Linear optimizations, and as such reducing the total necessary samples by about half. However due to the reduction in samples, only Area and Directional Blur are supported.
Related: #45, #6
Box Blur is the first to be on the new system and has received all the new features and optimizations available. The maximum Blur size has been increased to 128, Rotational and Zoom Blur are supported and a small optimization has been done to the shader.
Related: #45, #6
This is the new code base for blur effects, which is much more effective at being re-usable than the old code base. It allows for much better extendable behavior and uses an interface and factory pattern, instead of hardcoding supported features.
Small performance optimization as this removes the extra texture render that would be done by libobs which we don't actually need as we already have a texture to render to for it.
Rendering happens with cached Geometry that is only updated when necessary, such as when the user changes settings. This optimization was necessary to reduce CPU and GPU usage as we can simply re-use the same geomtry instead of recalculating it.
However, the actual source size was never checked. That meant that when a source changed size through any means, the filter would not update the geomtry accordingly, and the result was a squished or stretched image.
With this, the source size is now checked each tick.
Fixes#48
The number of files in the source directory was a little bit much and just made file naming more complex than it had to be. Therefore all files were moved into subdirectories where it matters.
Filters now reside in source/filters/, Sources in source/sources/, OBS Wrappers in obs/, OBS GS Wrappers in obs/gs/, Transitions will reside in source/transitions, Graphics Helpers will be in gfx/.
MipGenerator.Strength was renamed to MipGenerator.Intensity, which better fits the actual intention of the property. Additionally all the mipmap generator options are now correctly named.
Gaussian blur used to have a hard edge which was caused by the filter width being wider than the actual sampling range, which is what is determined by the size option. In order to fix this, we have to figure out the proper filter width for a sampling range, so that we avoid any and all hard edges.
Additionally removes the old texture method entirely.
Fixes#44
Source Mirror would incorrectly crash if an Audio only source was selected, as it expected a video frame to be present of any size. This fixes the problem by first testing if there is any video information to render and then just catching any exception that happens during rendering.