With this change module loading in the application is managed by the
plugin manager and allows the application to explicitly load core
modules independantly from 3rd party (plugin) modules.
The implementation is split into separate files for different platforms
to allow for cleaner code handling the different possible locations and
path schemes used, including all possible legacy locations and plugin
bundle formats.
This change introduces new locations and directory formats for plugins:
* WINDOWS: Portable plugins need to be placed in a directory called
"plugins" adjacent to the "bin" directory of an OBS Studio
installation.
* WINDOWS: Plugins need to be packaged into their own directory
"bundles", with the associated DLL in the root of the bundle and the
associated "data" directory next to it.
* WINDOWS: The "obs-plugins" directory adjacent to the "bin" directory
is deprecated and considered a legacy location for all plugins.
* MACOS: No changes in locations or formats.
* LINUX: Plugins distributed via system package managers now need to use
the "obs-modules/plugins" directory in the system library directory
for binaries, and the "obs/obs-modules/plugins" directory in the
system data directory for resources.
* LINUX: The "obs-plugins" directories in the system library and system
data directories are deprecated.
* LINUX: Plugins distributed outside of system packages need to use the
same directory format as plugins for Windows (see above).
* LINUX: A "portable" plugin location like on Windows is not supported.
* LINUX: Proper XDG directory locations are scanned for plugins, using
XDG_CONFIG_HOME for the legacy plugin format and XDG_DATA_HOME for the
new plugin structure.
* LINUX: Changes Flatpak plugin loading to use the new plugin structure
(while still supporting the legacy structure), and moves Flatpak
specific plugin loading to its own source files.
* ALL PLATFORMS: A single environment variable "OBS_PLUGINS_PATH" can
now be used to provide a highest-priority location from which to load
plugins. This directory needs to contain plugin bundles per the new
format. The one exception is Flatpak which does not support loading
plugins from an env provided location.
* ALL PLATFORMS: A custom legacy plugin locations can still be provided
via the "OBS_LEGACY_PLUGINS_PATH" and "OBS_LEGACY_PLUGINS_DATA_PATH"
environment variables. These are only compatible with plugins using
the legacy format and are considered deprecated. The one exception is
Flatpak which does not support loading plugins from an env provided
location.
Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Adds a separate code path just for loading core modules based on the
list of modules created at build system generation. Paths to load core
modules from is platform-specific, but not changeable for users and is
thus not changeable by a caller.
Instead path discovery is implemented for each platform separately,
generating the necessary module loading package directly before handing
it over to the existing module load callback function.
Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Moves first-party runtime modules into the "core" directory rather than
the "obs-plugins" directory to better differentiate them from legacy
plugins as well as existing 3rd-party plugins.
This change also requires the existing plugin directory to be explicitly
added as a possible module search path by application logic, as libobs's
internal logic will not add this path anymore and thus third-party
plugins would not be discovered anymore.
Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Core modules are main OBS Studio functionality implemented as runtime
modules, but are conceptually considered mandatory and the application
is incomplete without them.
This change also introduces a configure-time dependency of core modules
on "libobs" (already a generation-time dependency) and produces a
library target with the names of all core modules available at build
system generation.
Co-authored-by: PatTheMav <PatTheMav@users.noreply.github.com>
Should always call `gs_leave_context` after `gs_enter_context` or it
might cause a lock leave.
This commit makes sure all code paths will call `gs_leave_context` if
it called `gs_enter_context`.
obs_module_unload was never properly documented, so some plugins use it
to free resources, some use it to save data, etc. While libobs tries to
ensure all objects are shut down and destroyed before calling unload, if
another plugin is holding a strong reference, or if a reference leak has
occurred, libobs may need to call back into a plugin-provided object's
destroy function even after obs_module_unload has returned. If the
plugin has freed memory or other resources needed for the callback then
this likely results in a crash.
Going forward, we should document that obs_module_unload is now intended
only for saving data and releasing references, and that calling libobs
after it returns is not allowed. For cases where resource cleanup is
actually needed (for example, an external out of process helper needs to
be shut down or a release call to a hardware driver), a new
obs_module_destroy callback is intended to be added in a future version.
The `OBS_ENCODER_CAP_DYN_BITRATE` flag indicates if an encoder is
capable of supporting dynamic bitrate changes without disturbing
the stream. In the case of multitrack video, dynamic bitrate changes
are also possible, however the encoder must be able to change bitrates
for multiple renditions and multiple codecs and maintain IDR alignment.
Add the `OBS_ENCODER_CAP_MULTITRACK_DYN_BITRATE` to specify this
capability for the encoder.
This aligns obs_canvas_get_video_info() and obs_get_video_info() and
ensures the frame-rate is correct rather than returning the
potentially stale data stored in the canvas itself.
These calls introduce pipeline stalls in OpenGL on low end machines
which can contribute to a fairly significant 10-30% of total rendering
time.
The driver already needs to synchronize events within the context so
these calls are not needed for correctness for OpenGL.
With v1 of this function, it's unclear where exactly the data pointer
comes from or what it is. In fact, this is not determined by libobs, but
the consumer. libobs assumes that the caller of
obs_property_button_clicked passes an obs_context_data pointer, and then
passes the data pointer of that obs_context_data as the data pointer to
the callback.
In OBS Studio, this is always the private data of the associated object.
However, this assumes that there even is such an object (source/encoder/
etc), even though properties are meant to be free-standing. This is not
just philosophical, because with obs_get_source_properties you can
actually get an obs_properties_t that isn't associated with any specific
source, at which point you have no idea what the data pointer will be.
For this reason, obs_properties_add_button v1 needs to go.
obs_properties_add_button2 can be used as a drop-in replacement.
With v2, it's well-defined that the pointer you're passing as priv is
the pointer you get back in the callback as data. If you don't care
about it, simply pass NULL/nullptr.
Once v1 is removed in the future, obs_property_button_clicked should be
replaced with a variant that doesn't take a second argument, as that
argument will no longer be used anywhere.