File: build-aux/README.md
`build-aux` folder
This folder contains:
- Various formatting scripts:
run-clang-formatwhich formats C/C++/ObjC/ObjC++ filesrun-gersemiwhich formats CMake filesrun-swift-formatwhich formats Swift filesformat-manifest.pywhich formats Flatpak manifest JSON files
- The Flatpak manifest used to build OBS Studio
- Files used for Steam packaging
Formatting scripts
`run-clang-format`
This script allows to check the formatting and/or format of C/C++/ObjC/ObjC++ files and requires ZSH and a specific version of clang-format.
If the script does not find the latter it will return the required version, we provide clang-format Homebrew formulas in our homebrew-tools repo.
Example of use:
./build-aux/run-clang-format`run-gersemi`
This script allows to check the formatting and/or format of the CMake files and requires ZSH and gersemi Python package.
Example of use:
./build-aux/run-gersemi`run-swift-format`
This script allows to check the formatting and/or format of the Swift files and requires ZSH and swift-format.
Example of use:
./build-aux/run-swift-format`format-manifest.py`
This script allows to check the formatting and/or format of the Flatpak manifest and its modules.
Example of use:
python3 ./build-aux/format-manifest.py com.obsproject.Studio.jsonFile: deps/libcaption/README.md
version
v0.8
Matthew Szatmary [email protected] / [email protected]
libcaption
libcaption is a library written in C to aid in the creating and parsing of closed caption data, open sourced under the MIT license to use within community developed broadcast tools. To maintain consistency across platforms libcaption aims to implement a subset of EIA608, CEA708 as supported by the Apple iOS platform.
608 support is currently limited to encoding and decoding the necessary control and preamble codes as well as support for the Basic North American, Special North American and Extended Western European character sets.
708 support is limited to encoding the 608 data in NTSC field 1 user data type structure.
In addition, utility functions to create h.264 SEI (Supplementary enhancement information) NALUs (Network Abstraction Layer Unit) for inclusion into an h.264 elementary stream are provided.
H.264 utility functions are limited to wrapping the 708 payload into a SEI NALU. This is accomplished by prepending the 708 payload with 3 bytes (nal_unit_type = 6, payloadType = 4, and PayloadSize = variable), and appending a stop bit encoded into a full byte (with a value of 127). In addition if the 708 payload contains an emulated start code, a three byte sequence equaling 0,0,1 an emulation prevention byte (3) is inserted. Functions to reverse this operation are also provided.
Characters
| BNA | ! | " | # | $ | % | & | โ | ( | ) | รก | + | , | - | . | / | |
| BNA | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
| BNA | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
| BNA | P | Q | R | S | T | U | V | W | X | Y | Z | [ | รฉ | ] | รญ | รณ |
| BNA | รบ | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
| BNA | p | q | r | s | t | u | v | w | x | y | z | รง | รท | ร | รฑ | โ |
| SNA | ยฎ | ยฐ | ยฝ | ยฟ | โข | ยข | ยฃ | โช | ร | รจ | รข | รช | รฎ | รด | รป | |
| WES | ร | ร | ร | ร | ร | รผ | โ | ยก | * | ' | โ | ยฉ | โ | โข | โ | โ |
| WEF | ร | ร | ร | ร | ร | ร | รซ | ร | ร | รฏ | ร | ร | รน | ร | ยซ | ยป |
| WEP | ร | รฃ | ร | ร | รฌ | ร | รฒ | ร | รต | { | } | \ | ^ | _ | | | ~ |
| WEG | ร | รค | ร | รถ | ร | ยฅ | ยค | ยฆ | ร | รฅ | ร | รธ | โ | โ | โ | โ |
- BNA = Basic North American character set
- SNA = Special North American character set
- WES = Extended Western European character set : Extended Spanish/Miscellaneous
- WEF = Extended Western European character set : Extended French
- WEP = Extended Western European character set : Portuguese
- WEG = Extended Western European character set : German/Danish
Limitations
Current B-frame support for caption creation is minimal. libcaption ensures no re-ordering of captions is required
on playback.
Build Directions
Mac Os/Linux
Install build dependencies (git, cmake, a compiler such as xcode, gcc or clang and optionally re2c and ffmpeg)
- run
cmake . && make - or to compile without re2c
cmake -DENABLE_RE2C=OFF . && make - finally
sudo make installto install
Windows
I have never tested libcaption in windows. It is written in pure C with no dependencies,
so there is no reason it would not work.
File: docs/sphinx/backend-design.rst
OBS Studio Backend Design
The OBS Studio backend is powered by the library libobs. Libobs
provides the main pipeline, the video/audio subsystems, and the general
framework for all plugins.
Libobs Plugin Objects
Libobs is designed to be modular, where adding modules will add custom
functionality. There are four libobs objects that you can make plugins
for:
:ref:
plugins_sources-- Sources are used to render video and/or
audio on stream. Things such as capturing displays/games/audio,
playing a video, showing an image, or playing audio. Sources can also
be used to implement audio and video filters.:ref:
plugins_outputs-- Outputs allow the ability to output the
currently rendering audio/video. Streaming and recording are two
common examples of outputs, but not the only types of outputs.
Outputs can receive the raw data or receive encoded data.:ref:
plugins_encoders-- Encoders are OBS-specific implementations
of video/audio encoders, which are used with outputs that use
encoders. x264, NVENC, Quicksync are examples of encoder
implementations.:ref:
plugins_services-- Services are custom implementations of
streaming services, which are used with outputs that stream. For
example, you could have a custom implementation for streaming to
Twitch, and another for YouTube to allow the ability to log in and use
their APIs to do things such as get the RTMP servers or control the
channel.
(Author's note: the service API is incomplete as of this writing)
Libobs Threads
There are three primary threads spawned by libobs on initialization:
The obs_graphics_thread_ function used exclusively for rendering in
libobs/obs-video.c_The video_thread_ function used exclusively for video encoding/output
inlibobs/media-io/video-io.c_The audio_thread_ function used for all audio
processing/encoding/output inlibobs/media-io/audio-io.c_
(Author's note: obs_graphics_thread was originally named
obs_video_thread; it was renamed as of this writing to prevent confusion
with video_thread)
.. _output_channels:
Output Channels
Rendering video or audio starts from output channels. You assign a
source to an output channel via the :c:func:obs_set_output_source()
function. The channel parameter can be any number from
0..(MAX_CHANNELS_-1). You may initially think that this is how you
display multiple sources at once; however, sources are hierarchical.
Sources such as scenes or transitions can have multiple sub-sources, and
those sub-sources in turn can have sub-sources and so on (see
:ref:displaying_sources for more information). Typically, you would
use scenes to draw multiple sources as a group with specific transforms
for each source, as a scene is just another type of source. The
"channel" design allows for highly complex video presentation setups.
The OBS Studio front-end has yet to even fully utilize this back-end
design for its rendering, and currently only uses one output channel to
render one scene at a time. It does however utilize additional channels
for things such as global audio sources which are set in audio settings.
(Author's note: "Output channels" are not to be confused with output
objects or audio channels. Output channels are used to set the sources
you want to output, and output objects are used for actually
streaming/recording/etc.)
General Video Pipeline Overview
The video graphics pipeline is run from two threads: a dedicated
graphics thread that renders preview displays as well as the final mix
(the obs_graphics_thread_ function in libobs/obs-video.c), and a
dedicated thread specific to video encoding/output (the video_thread
function in libobs/media-io/video-io.c_).
Sources assigned to output channels will be drawn from channels
0..(MAX_CHANNELS_-1). They are drawn on to the final texture which will
be used for output [1]. Once all sources are drawn, the final
texture is converted to whatever format that libobs is set to (typically
a YUV format). After being converted to the back-end video format, it's
then sent along with its timestamp to the current video handler,obs_core_video::video.
It then puts that raw frame in a queue of MAX_CACHE_SIZE_ in the video output handler. A semaphore is posted, then the video-io thread will
process frames as it's able. If the video frame queue is full, it will
duplicate the last frame in the queue in an attempt to reduce video
encoding complexity (and thus CPU usage) [2]. This is why you may
see frame skipping when the encoder can't keep up. Frames are sent to
any raw outputs or video encoders that are currently active [3]_.
If it's sent to a video encoder object (libobs/obs-encoder.c), it
encodes the frame and sends the encoded packet off to the outputs that
encoder is connected to (which can be multiple). If the output takes
both encoded video/audio, it puts the packets in an interleave queue to
ensure encoded packets are sent in monotonic timestamp order [4].
The encoded packet or raw frame is then sent to the output.
General Audio Pipeline Overview
The audio pipeline is run from a dedicated audio thread in the audio
handler (the audio_thread_ function in libobs/media-io/audio-io.c);
assuming that AUDIO_OUTPUT_FRAMES is set to 1024, the audio thread
"ticks" (processes audio data) once every 1024 audio samples (around
every 21 millisecond intervals at 48khz), and calls the audio_callback_
function in libobs/obs-audio.c_ where most of the audio processing is
accomplished.
A source with audio will output its audio via the
obs_source_output_audio_ function, and that audio data will be appended
or inserted in to the circular buffer obs_source::audio_input_buf.
If the sample rate or channel count does not match what the back-end is
set to, the audio is automatically remixed/resampled via swresample[5]. Before insertion, audio data is also run through any audio
filters attached to the source [6]_.
Each audio tick, the audio thread takes a reference snapshot of the
audio source tree (stores references of all sources that output/process
audio) [7]. On each audio leaf (audio source), it takes the closest
audio (relative to the current audio thread timestamp) stored in the
circular buffer obs_source::audio_input_buf, and puts it inobs_source::audio_output_buf_.
Then, the audio samples stored in obs_source::audio_output_buf_ of the
leaves get sent through their parents in the source tree snapshot for
mixing or processing at each source node in the hierarchy [8].
Sources with multiple children such as scenes or transitions will
mix/process their children's audio themselves via theobs_source_info::audio_render callback. This allows, for example,
transitions to fade in the audio of one source and fade in the audio of
a new source when they're transitioning between two sources. The mix or
processed audio data is then stored in obs_source::audio_output_buf_
of that node similarly, and the process is repeated until the audio
reaches the root nodes of the tree.
Finally, when the audio has reached the base of the snapshot tree, the
audio of all the sources in each output channel are mixed together for a
final mix [9]. That final mix is then sent to any raw outputs or
audio encoders that are currently active [10].
If it's sent to an audio encoder object (libobs/obs-encoder.c), it
encodes the audio data and sends the encoded packet off to the outputs
that encoder is connected to (which can be multiple). If the output
takes both encoded video/audio, it puts the packets in an interleave
queue to ensure encoded packets are sent in monotonic timestamp order[4].
The encoded packet or raw audio data is then sent to the output.
.. _obs_graphics_thread: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-video.c#L588-L651
.. _libobs/obs-audio.c: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-audio.c
.. _libobs/obs-video.c: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-video.c
.. _video_thread: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/video-io.c#L169-L195
.. _libobs/media-io/video-io.c: https://github.com/obsproject/obs-studio/blob/master/libobs/media-io/video-io.c
.. _video output handler: https://github.com/obsproject/obs-studio/blob/master/libobs/media-io/video-io.c
.. _audio_thread: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/audio-io.c#L241-L282
.. _libobs/media-io/audio-io.c: https://github.com/obsproject/obs-studio/blob/master/libobs/media-io/audio-io.c
.. _MAX_CHANNELS: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-defs.h#L20-L21
.. _[1]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-video.c#L99-L129
.. _obs_core_video::video: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-internal.h#L250
.. _MAX_CACHE_SIZE: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/video-io.c#L34
.. _[2]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/video-io.c#L431-L434
.. _[3]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/video-io.c#L115-L167
.. _libobs/obs-encoder.c: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-encoder.c
.. _[4]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-output.c#L1382-L1439
.. _AUDIO_OUTPUT_FRAMES: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/audio-io.h#L30
.. _audio_callback: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-audio.c#L367-L485
.. _obs_source_output_audio: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-source.c#L2578-L2608
.. _obs_source::audio_input_buf: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-source.c#L1280-L1283
.. _[5]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-source.c#L2561-L2563
.. _[6]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-source.c#L2591
.. _[7]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-audio.c#L393-L415
.. _obs_source::audio_output_buf: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-internal.h#L580
.. _[8]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-audio.c#L417-L423
.. _obs_source_info::audio_render: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-source.h#L410-L412
.. _[9]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/obs-audio.c#L436-L453
.. _[10]: https://github.com/obsproject/obs-studio/blob/2c58185af3c85f4e594a4c067c9dfe5fa4b5b0a9/libobs/media-io/audio-io.c#L144-L165
File: docs/sphinx/frontends.rst
Frontends
Initialization and Shutdown
To initialize libobs, you must call :c:func:obs_startup(),
:c:func:obs_reset_video(), and then :c:func:obs_reset_audio().
After that, modules typically should be loaded.
You can load individual modules manually by calling
:c:func:obs_open_module(). After loading, the
:c:func:obs_open_module() function, you must then call
:c:func:obs_init_module() to initialize the module.
You can load modules automatically via two functions:
:c:func:obs_add_module_path() and :c:func:obs_load_all_modules().
After all plugin modules have been loaded, call
:c:func:obs_post_load_modules().
Certain modules may optionally use a configuration storage directory,
which is set as a parameter to :c:func:obs_startup().
When it's time to shut down the frontend, make sure to release all
references to any objects, free any data, and then call
:c:func:obs_shutdown(). If for some reason any libobs objects have
not been released, they will be destroyed automatically and a warning
will be logged.
To detect if any general memory allocations have not been freed, call
the :c:func:bnum_allocs() to get the number of allocations remaining.
If the number remaining is above 0, there are memory leaks.
See :ref:obs_init_shutdown_reference for more information.
Reconfiguring Video
Any time after initialization, video settings can be reconfigured by
calling :c:func:obs_reset_video() as long as no outputs are active.
Audio was originally intended to have this capability as well, but
currently is not able to be reset once initialized; libobs must be fully
shutdown in order to reconfigure audio settings.
Displays
Displays as the name implies are used for display/preview panes. To use
displays, you must have a native window handle or identifier to draw on.
First you must call :c:func:obs_display_create() to initialize the
display, then you must assign a draw callback with
:c:func:obs_display_add_draw_callback(). If you need to remove a draw
callback, call :c:func:obs_display_remove_draw_callback() similarly.
When drawing, to draw the main preview window (if any), call
:c:func:obs_render_main_texture(). If you need to render a specific
source on a secondary display, you can increment its "showing" state
with :c:func:obs_source_inc_showing() while it's showing in the
secondary display, draw it with :c:func:obs_source_video_render() in
the draw callback, then when it's no longer showing in the secondary
display, call :c:func:obs_source_dec_showing().
If the display needs to be resized, call :c:func:obs_display_resize().
If the display needs a custom background color other than black, call
:c:func:obs_display_set_background_color().
If the display needs to be temporarily disabled, call
:c:func:obs_display_set_enabled() to disable, and
:c:func:obs_display_enabled() to get its enabled/disabled state.
Then call :c:func:obs_display_destroy() to destroy the display when
it's no longer needed.
(Important note: do not use more than one display widget within the
hierarchy of the same base window; this will cause presentation stalls
on macOS.)
For an example of how displays are used with Qt, seeUI/qt-display.hpp_ and UI/qt-display.cpp_.
See :ref:display_reference for more information.
Saving/Loading Objects and Object Management
The frontend is generally expected to manage its own objects, however
for sources, there are some helper functions to allow easier
saving/loading all sources: :c:func:obs_save_sources() and
:c:func:obs_load_sources(). With those functions, all sources that
aren't private will automatically be saved and loaded. You can also
save/load individual sources manually by using
:c:func:obs_save_source() and :c:func:obs_load_source().
(Author's note: I should not have written those helper functions; the
downside is I had to add "private" sources that aren't saveable via the
:c:func:obs_source_create_private() function. Just one of the many
minor design flaws that can occur during long-term development.)
For outputs, encoders, and services, there are no helper functions, so
usually you'd get their settings individually and save them as json.
(See :c:func:obs_output_get_settings()). You don't have to save each
object to different files individually; you'd save multiple objects
together in a bigger :c:type:obs_data_t object, then save that via
:c:func:obs_data_save_json_safe(), then load everything again via
:c:func:obs_data_create_from_json_file_safe().
Signals
The core, as well as scenes and sources, have a set of standard signals
that are used to determine when something happens or changes.
Typically the most important signals are the
:ref:output_signal_handler_reference: the start, stop,
starting, stopping, reconnect, reconnect_success
signals in particular.
Most other signals for scenes/sources are optional if you are the only
thing controlling their state. However, it's generally recommended to
watch most signals when possible for consistency. See
:ref:source_signal_handler_reference and :ref:scene_signal_reference
for more information.
For example, let's say you wanted to connect a callback to the stop
signal of an output. The stop signal has two parameters: output
and code. A callback for this signal would typically look something
like this:
.. code:: cpp
static void output_stopped(void *my_data, calldata_t *cd)
{
obs_output_t *output = calldata_ptr(cd, "output");
int code = calldata_int(cd, "code");
[...]}
(Note that callbacks are not thread-safe.)
Then to connect it to the stop signal, you use the
:c:func:signal_handler_connect() with the callback. In this case for
example:
.. code:: cpp
signal_handler_t *handler = obs_output_get_signal_handler(output);
signal_handler_connect(handler, "stop", output_stopped);
.. _displaying_sources:
Displaying Sources
Sources are displayed on stream/recording via :ref:output_channels
with the :c:func:obs_set_output_source() function. There are 64
channels that you can assign sources to, which will draw on top of each
other in ascending index order. Typically, a normal source shouldn't be
directly assigned with this function; you would use a scene or a
transition containing scenes.
To draw one or more sources together with a specific transform applied
to them, scenes are used. To create a scene, you call
:c:func:obs_scene_create(). Child sources are referenced using scene
items, and then specific transforms are applied to those scene items.
Scene items are not sources but containers for sources; the same source
can be referenced by multiple scene items within the same scene, or can
be referenced in multiple scenes. To create a scene item that
references a source, you call :c:func:obs_scene_add(), which returns a
new reference to a scene item.
To change the transform of a scene item, you typically would call a
function like :c:func:obs_sceneitem_set_pos() to change its position,
:c:func:obs_sceneitem_set_rot() to change its rotation, or
:c:func:obs_sceneitem_set_scale() to change its scaling. Scene items
can also force scaling in to a custom size constraint referred to as a
"bounding box"; a bounding box will force the source to be drawn at a
specific size and with specific scaling constraint within that size. To
use a bounding box, you call the
:c:func:obs_sceneitem_set_bounds_type(),
:c:func:obs_sceneitem_set_bounds(), and
:c:func:obs_sceneitem_set_bounds_alignment(). Though the easiest way
to handle everything related to transforms is to use the
:c:func:obs_sceneitem_set_info2() and
:c:func:obs_sceneitem_get_info2() functions. See
:ref:scene_item_reference for all the functions related to scene
items.
Usually, a smooth transition between multiple scenes is required. To do
this, transitions are used. To create a transition, you use
:c:func:obs_source_create() or :c:func:obs_source_create_private()
like any other source. Then, to activate a transition, you call
:c:func:obs_transition_start(). When the transition is not active and
is only displaying one source, it performs a pass-through to the current
displaying source. See :ref:transitions for more functions related to
using transitions.
The recommended way to set up your structure is to have a transition as
the source that is used as the main output source, then your scene as a
child of the transition, then your sources as children in the scene.
When you need to switch to a new scene, simply call
:c:func:obs_transition_start().
Outputs, Encoders, and Services
Outputs, encoders, and services are all used together, and managed a bit
differently than sources. There currently is no global function to
save/load them, that must be accomplished manually for now via their
settings if needed.
Encoders are used with outputs that expect encoded data (which is almost
all typical outputs), such as standard file recording or streaming.
Services are used with outputs to a stream; the RTMP output_ is the
quintessential example of this.
Here's an example of how an output would be used with encoders and
services:
.. code:: cpp
obs_encoder_set_video(my_h264_encoder, obs_get_video());
obs_encoder_set_audio(my_aac_encoder, obs_get_audio());
obs_output_set_video_encoder(my_output, my_h264_encoder);
obs_output_set_audio_encoder(my_output, my_aac_encoder);
obs_output_set_service(my_output, my_service); /* if a stream */
obs_output_start(my_output);
Once the output has started successfully, it automatically starts
capturing the video and/or audio from the current video/audio output
(i.e. any sources that are assigned to the :ref:output_channels).
If the output fails to start up, it will send the stop signal with
an error code in the code parameter, possibly accompanied by a
translated error message stored that can be obtained via the
:c:func:obs_output_get_last_error() function.
.. --------------------------------------------------------------------
.. _RTMP Output: https://github.com/obsproject/obs-studio/blob/master/plugins/obs-outputs/rtmp-stream.c
.. _UI/qt-display.hpp: https://github.com/obsproject/obs-studio/blob/master/UI/qt-display.hpp
.. _UI/qt-display.cpp: https://github.com/obsproject/obs-studio/blob/master/UI/qt-display.cpp
File: docs/sphinx/graphics.rst
Rendering Graphics
Libobs has a custom-made programmable graphics subsystem that wraps both
Direct3D 11 and OpenGL. The reason why it was designed with a custom
graphics subsystem was to accommodate custom capture features only
available on specific operating systems.
(Author's note: In retrospect, I probably should have used something
like ANGLE, but I would have to modify it to accommodate my specific
use-cases.)
Most rendering is dependent upon effects. Effects are used by all video
objects in libobs; they're used to easily bundle related vertex/pixel
shaders in to one file.
An effect file has a nearly identical syntax to Direct3D 11 HLSL effect
files. The only differences are as follows:
- Sampler states are named "sampler_state"
- Position semantic is called "POSITION" rather than "SV_Position"
- Target semantic is called "TARGET" rather than "SV_Target"
(Author's note: I'm probably missing a few exceptions here, if I am
please let me know)
The Graphics Context
Using graphics functions isn't possible unless the current thread has
entered a graphics context, and the graphics context can only be used by
one thread at a time. To enter the graphics context, use
:c:func:obs_enter_graphics(), and to leave the graphics context, use
:c:func:obs_leave_graphics().
Certain callback will automatically be within the graphics context:
:c:member:obs_source_info.video_render, and the draw callback
parameter of :c:func:obs_display_add_draw_callback(), and
:c:func:obs_add_main_render_callback().
Creating Effects
Effect Parameters
^^^^^^^^^^^^^^^^^
To create an effect, it's recommended to start with the uniforms
(parameters) of the effect.
There are a number of different types of uniforms:
+------------------+---------------+------------------+------------+------------+
| Floating points: | float | float2 | float3 | float4 |
+------------------+---------------+------------------+------------+------------+
| Matrices: | float3x3 | float4x4 | | |
+------------------+---------------+------------------+------------+------------+
| Integers: | int | int2 | int3 | int4 |
+------------------+---------------+------------------+------------+------------+
| Booleans: | bool | | | |
+------------------+---------------+------------------+------------+------------+
| Textures: | texture2d | texture_cube | | |
+------------------+---------------+------------------+------------+------------+
To get the effect uniform parameters, you use
:c:func:gs_effect_get_param_by_name() or
:c:func:gs_effect_get_param_by_idx().
Then the uniforms are set through the following functions:
- :c:func:
gs_effect_set_bool() - :c:func:
gs_effect_set_float() - :c:func:
gs_effect_set_int() - :c:func:
gs_effect_set_matrix4() - :c:func:
gs_effect_set_vec2() - :c:func:
gs_effect_set_vec3() - :c:func:
gs_effect_set_vec4() - :c:func:
gs_effect_set_texture() - :c:func:
gs_effect_set_texture_srgb()
There are two "universal" effect parameters that may be expected of
effects: ViewProj, and image. The ViewProj parameter
(which is a float4x4) is used for the primary view/projection matrix
combination. The image parameter (which is a texture2d) is a
commonly used parameter for the main texture; this parameter will be
used with the functions :c:func:obs_source_draw(),
:c:func:gs_draw_sprite(), :c:func:gs_draw_quadf(), and
:c:func:obs_source_process_filter_end().
Here is an example of effect parameters:
.. code:: cpp
uniform float4x4 ViewProj;
uniform texture2d image;
uniform float4 my_color_param;
uniform float my_float_param;
Effect parameters can also have default values. Default parameters of
elements that have multiple elements should be treated as an array.
Here are some examples of default parameters:
.. code:: cpp
uniform float4x4 my_matrix = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
uniform float4 my_float4 = {1.0, 0.5, 0.25, 0.0};
uniform float my_float = 4.0;
uniform int my_int = 5;
Effect Sampler States
^^^^^^^^^^^^^^^^^^^^^
Then, if textures are used, sampler states should be defined. Sampler
states have certain sub-parameters:
Filter - The type of filtering to use. Can be one of the
following values:- Anisotropy
- Point
- Linear
- MIN_MAG_POINT_MIP_LINEAR
- MIN_POINT_MAG_LINEAR_MIP_POINT
- MIN_POINT_MAG_MIP_LINEAR
- MIN_LINEAR_MAG_MIP_POINT
- MIN_LINEAR_MAG_POINT_MIP_LINEAR
- MIN_MAG_LINEAR_MIP_POINT
AddressU, AddressV - Specifies how to handle the sampling
when the coordinate goes beyond 0.0..1.0. Can be one of the following
values:- Wrap or Repeat
- Clamp or None
- Mirror
- Border (uses BorderColor to fill the color)
- MirrorOnce
BorderColor - Specifies the border color if using the "Border"
address mode. This value should be a hexadecimal value representing
the color, in the format of: AARRGGBB. For example, 7FFF0000 would
have its alpha value at 127, its red value at 255, and blue and green
at 0. If Border is not used as an addressing type, this value is
ignored.
Here is an example of writing a sampler state in an effect file:
.. code:: cpp
sampler_state defaultSampler {
Filter = Linear;
AddressU = Border;
AddressV = Border;
BorderColor = 7FFF0000;
};
This sampler state would use linear filtering, would use border
addressing for texture coordinate values beyond 0.0..1.0, and the border
color would be the color specified above.
When a sampler state is used, it's used identically to the HLSL form:
.. code:: cpp
[...]
uniform texture2d image;
sampler_state defaultSampler {
Filter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
[...]
float4 MyPixelShaderFunc(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
Effect Vertex/Pixel Semantics
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Then structures should be defined for inputs and outputs vertex
semantics.
Vertex components can have the following semantics:
- COLOR - Color value (float4).
- POSITION - Position value (float4).
- NORMAL - Normal value (float4).
- TANGENT - Tangent value (float4).
- TEXCOORD[0..7] - Texture coordinate value (float2, float3, or
float4).
Here is an example of a vertex semantic structure:
.. code:: cpp
struct VertexIn {
float4 my_position : POSITION;
float2 my_texcoord : TEXCOORD0;
};
These semantic structures are then passed in as a parameter to the
primary shader entry point, and used as a return value for the vertex
shader. Note that the vertex shader is allowed to return different
semantics than it takes in; but the return type of the vertex shader and
the parameter of the pixel shader must match.
The semantic structure used for the parameter to the vertex shader
function will require that the vertex buffer have those values, so if
you have POSITION and TEXCOORD0, the vertex buffer will have to have at
least a position buffer and a texture coordinate buffer in it.
For pixel shaders, they need to return with a TARGET semantic (which is
a float4 RGBA value). Here is an example of how it's usually used with
a pixel shader function:
.. code:: cpp
float4 MyPixelShaderFunc(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
Effect Techniques
^^^^^^^^^^^^^^^^^
Techniques are used to define the primary vertex/pixel shader entry
functions per pass. One technique can have multiple passes or custom
pass setup.
(Author's note: These days, multiple passes aren't really needed; GPUs
are powerful enough to where you can perform all actions in the same
shader. Named passes can be useful for custom draw setups, but even
then you can just make it a separate technique. For that reason, it's
best to just ignore the extra pass functionality.)
If you're making an effect filter for video sources, typically you'd
name the pass Draw, and then
:c:func:obs_source_process_filter_end() will automatically call that
specific effect name. However, you can also use
:c:func:obs_source_process_filter_tech_end() to make the filter use a
specific technique by its name.
The first parameter of the vertex/pixel shader functions in passes
should always be the name of its vertex semantic structure parameter.
For techniques, it's better to show some examples of how techniques
would be used:
.. code:: cpp
uniform float4x4 ViewProj;
uniform texture2d image;
struct VertInOut {
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
VertInOut MyVertexShaderFunc(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
float4 MyPixelShaderFunc(VertInOut vert_in) : TARGET
{
return image.Sample(def_sampler, vert_in.uv);
}
technique Draw
{
pass
{
vertex_shader = MyVertexShaderFunc(vert_in);
pixel_shader = MyPixelShaderFunc(vert_in);
}
};
Using Effects
The recommended way to use effects is like so:
.. code:: cpp
for (gs_effect_loop(effect, "technique")) {
[draw calls go here]
}
This will automatically handle loading/unloading of the effect and its
shaders for a given technique name.
Rendering Video Sources
A synchronous video source renders in its
:c:member:obs_source_info.video_render callback.
Sources can render with custom drawing (via the OBS_SOURCE_CUSTOM_DRAW
output capability flag), or without. When sources render without custom
rendering, it's recommended to render a single texture with
:c:func:obs_source_draw(). Otherwise the source is expected to
perform rendering on its own and manage its own effects.
Libobs comes with a set of default/standard effects that can be accessed
via the :c:func:obs_get_base_effect() function. You can use these
effects to render, or you can create custom effects with
:c:func:gs_effect_create_from_file() and render with a custom effect.
Rendering Video Effect Filters
For most video effect filters, it comprises of adding a layer of
processing shaders to an existing image in its
:c:member:obs_source_info.video_render callback. When this is the
case, it's expected that the filter has its own effect created, and to
draw the effect, one would simply use the
:c:func:obs_source_process_filter_begin() function, set the parameters
on your custom effect, then call either
:c:func:obs_source_process_filter_end() or
:c:func:obs_source_process_filter_tech_end() to finish rendering the
filter.
Here's an example of rendering a filter from the color key filter:
.. code:: cpp
static void color_key_render(void *data, gs_effect_t *effect)
{
struct color_key_filter_data *filter = data;
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
OBS_ALLOW_DIRECT_RENDERING))
return;
gs_effect_set_vec4(filter->color_param, &filter->color);
gs_effect_set_float(filter->contrast_param, filter->contrast);
gs_effect_set_float(filter->brightness_param, filter->brightness);
gs_effect_set_float(filter->gamma_param, filter->gamma);
gs_effect_set_vec4(filter->key_color_param, &filter->key_color);
gs_effect_set_float(filter->similarity_param, filter->similarity);
gs_effect_set_float(filter->smoothness_param, filter->smoothness);
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
UNUSED_PARAMETER(effect);}
File: docs/sphinx/index.rst
.. OBS Studio documentation master file, created by
sphinx-quickstart on Wed Oct 25 00:03:21 2017.
You can adapt this file completely to your liking, but it should at least
contain the root toctree directive.
.. _contents:
Welcome to OBS Studio's documentation!
- Setting up an OBS development environment? :wiki:
Use the Wiki - Developing your first OBS plugin?
Use the obs-plugintemplate <https://github.com/obsproject/obs-plugintemplate#obs-plugin-template>_
.. toctree::
:caption: Core Concepts
:maxdepth: 1
backend-design
plugins
frontends
graphics
scripting
.. toctree::
:caption: API Reference
:maxdepth: 2
OBS Core
Modules
Core API Object
Platform/Utility
Callbacks (libobs/callback)
Graphics (libobs/graphics)
Media I/O (libobs/media-io)
reference-frontend-api
.. toctree::
:caption: Additional Resources
:maxdepth: 1
:hidden:
Build Instructions https://obsproject.com/wiki/Install-Instructions
Plugin Template https://github.com/obsproject/obs-plugintemplate#obs-plugin-template
File: docs/sphinx/plugins.rst
Plugins
Almost all custom functionality is added through plugin modules, which
are typically dynamic libraries or scripts. The ability to capture
and/or output audio/video, make a recording, output to an RTMP stream,
encode in x264 are all examples of things that are accomplished via
plugin modules.
Plugins can implement sources, outputs, encoders, and services.
Writing your first plugin? We provide a basic template plugin <https://github.com/obsproject/obs-plugintemplate#obs-plugin-template>_
to get you started.
Plugin Module Headers
These are some notable headers commonly used by plugins:
libobs/obs-module.h_ -- The primary header used for creating plugin
modules. This file automatically includes the following files:libobs/obs.h_ -- The main libobs header. This file automatically
includes the following files:libobs/obs-source.h_ -- Used for implementing sources in plugin
moduleslibobs/obs-output.h_ -- Used for implementing outputs in plugin
moduleslibobs/obs-encoder.h_ -- Used for implementing encoders in
plugin moduleslibobs/obs-service.h_ -- Used for implementing services in
plugin moduleslibobs/obs-data.h_ -- Used for managing settings for libobs
objectslibobs/obs-properties.h_ -- Used for generating properties for
libobs objectslibobs/graphics/graphics.h_ -- Used for graphics rendering
Common Directory Structure and CMakeLists.txt
The common way source files are organized is to have one file for plugin
initialization, and then specific files for each individual object
you're implementing. For example, if you were to create a plugin called
'my-plugin', you'd have something like my-plugin.c where plugin
initialization is done, my-source.c for the definition of a custom
source, my-output.c for the definition of a custom output, etc. (This
is not a rule of course)
This is an example of a common directory structure for a native plugin
module::
my-plugin/data/locale/en-US.ini
my-plugin/CMakeLists.txt
my-plugin/my-plugin.c
my-plugin/my-source.c
my-plugin/my-output.c
my-plugin/my-encoder.c
my-plugin/my-service.c
This would be an example of a common CMakeLists.txt file associated with
these files::
my-plugin/CMakeLists.txt
project(my-plugin)
set(my-plugin_SOURCES
my-plugin.c
my-source.c
my-output.c
my-encoder.c
my-service.c)
add_library(my-plugin MODULE
${my-plugin_SOURCES})
target_link_libraries(my-plugin
libobs)
install_obs_plugin_with_data(my-plugin data)
Native Plugin Initialization
To create a native plugin module, you will need to include thelibobs/obs-module.h_ header, use :c:func:OBS_DECLARE_MODULE() macro,
then create a definition of the function :c:func:obs_module_load().
In your :c:func:obs_module_load() function, you then register any of
your custom sources, outputs, encoders, or services. See the
:doc:reference-modules for more information.
The following is an example of my-plugin.c, which would register one
object of each type:
.. code:: cpp
/* my-plugin.c */
#include <obs-module.h>
/* Defines common functions (required) */
OBS_DECLARE_MODULE()
/* Implements common ini-based locale (optional) */
OBS_MODULE_USE_DEFAULT_LOCALE("my-plugin", "en-US")
extern struct obs_source_info my_source; /* Defined in my-source.c /
extern struct obs_output_info my_output; / Defined in my-output.c /
extern struct obs_encoder_info my_encoder; / Defined in my-encoder.c /
extern struct obs_service_info my_service; / Defined in my-service.c */
bool obs_module_load(void)
{
obs_register_source(&my_source);
obs_register_output(&my_output);
obs_register_encoder(&my_encoder);
obs_register_service(&my_service);
return true;
}
.. _plugins_sources:
Sources
Sources are used to render video and/or audio on stream. Things such as
capturing displays/games/audio, playing a video, showing an image, or
playing audio. Sources can also be used to implement audio and video
filters as well as transitions. The libobs/obs-source.h_ file is the
dedicated header for implementing sources. See the
:doc:reference-sources for more information.
For example, to implement a source object, you need to define an
:c:type:obs_source_info structure and fill it out with information and
callbacks related to your source:
.. code:: cpp
/* my-source.c */
[...]
struct obs_source_info my_source {
.id = "my_source",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO,
.get_name = my_source_name,
.create = my_source_create,
.destroy = my_source_destroy,
.update = my_source_update,
.video_render = my_source_render,
.get_width = my_source_width,
.get_height = my_source_height
};
Then, in my-plugin.c, you would call :c:func:obs_register_source() in
:c:func:obs_module_load() to register the source with libobs.
.. code:: cpp
/* my-plugin.c */
[...]
extern struct obs_source_info my_source; /* Defined in my-source.c */
bool obs_module_load(void)
{
obs_register_source(&my_source);
[...]
return true;}
Some simple examples of sources:
- Synchronous video source: The
image source <https://github.com/obsproject/obs-studio/blob/master/plugins/image-source/image-source.c>_ - Asynchronous video source: The
random texture test source <https://github.com/obsproject/obs-studio/blob/master/test/test-input/test-random.c>_ - Audio source: The
sine wave test source <https://github.com/obsproject/obs-studio/blob/master/test/test-input/test-sinewave.c>_ - Video filter: The
test video filter <https://github.com/obsproject/obs-studio/blob/master/test/test-input/test-filter.c>_ - Audio filter: The
gain audio filter <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-filters/gain-filter.c>_
.. _plugins_outputs:
Outputs
Outputs allow the ability to output the currently rendering audio/video.
Streaming and recording are two common examples of outputs, but not the
only types of outputs. Outputs can receive the raw data or receive
encoded data. The libobs/obs-output.h_ file is the dedicated header
for implementing outputs. See the :doc:reference-outputs for more
information.
For example, to implement an output object, you need to define an
:c:type:obs_output_info structure and fill it out with information and
callbacks related to your output:
.. code:: cpp
/* my-output.c */
[...]
struct obs_output_info my_output {
.id = "my_output",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED,
.get_name = my_output_name,
.create = my_output_create,
.destroy = my_output_destroy,
.start = my_output_start,
.stop = my_output_stop,
.encoded_packet = my_output_data,
.get_total_bytes = my_output_total_bytes,
.encoded_video_codecs = "h264",
.encoded_audio_codecs = "aac"
};
Then, in my-plugin.c, you would call :c:func:obs_register_output() in
:c:func:obs_module_load() to register the output with libobs.
.. code:: cpp
/* my-plugin.c */
[...]
extern struct obs_output_info my_output; /* Defined in my-output.c */
bool obs_module_load(void)
{
obs_register_output(&my_output);
[...]
return true;}
Some examples of outputs:
Encoded video/audio outputs:
- The
FLV output <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-outputs/flv-output.c>_ - The
FFmpeg muxer output <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-ffmpeg/obs-ffmpeg-mux.c>_ - The
RTMP stream output <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-outputs/rtmp-stream.c>_
- The
Raw video/audio outputs:
- The
FFmpeg output <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-ffmpeg/obs-ffmpeg-output.c>_
- The
.. _plugins_encoders:
Encoders
Encoders are OBS-specific implementations of video/audio encoders, which
are used with outputs that use encoders. x264, NVENC, Quicksync are
examples of encoder implementations. The libobs/obs-encoder.h_ file
is the dedicated header for implementing encoders. See the
:doc:reference-encoders for more information.
For example, to implement an encoder object, you need to define an
:c:type:obs_encoder_info structure and fill it out with information
and callbacks related to your encoder:
.. code:: cpp
/* my-encoder.c */
[...]
struct obs_encoder_info my_encoder_encoder = {
.id = "my_encoder",
.type = OBS_ENCODER_VIDEO,
.codec = "h264",
.get_name = my_encoder_name,
.create = my_encoder_create,
.destroy = my_encoder_destroy,
.encode = my_encoder_encode,
.update = my_encoder_update,
.get_extra_data = my_encoder_extra_data,
.get_sei_data = my_encoder_sei,
.get_video_info = my_encoder_video_info
};
Then, in my-plugin.c, you would call :c:func:obs_register_encoder()
in :c:func:obs_module_load() to register the encoder with libobs.
.. code:: cpp
/* my-plugin.c */
[...]
extern struct obs_encoder_info my_encoder; /* Defined in my-encoder.c */
bool obs_module_load(void)
{
obs_register_encoder(&my_encoder);
[...]
return true;}
IMPORTANT NOTE: Encoder settings currently have a few expected
common setting values that should have a specific naming convention:
- "bitrate" - This value should be used for both video and audio
encoders: bitrate, in kilobits. - "rate_control" - This is a setting used for video encoders.
It's generally expected to have at least a "CBR" rate control.
Other common rate controls are "VBR", "CQP". - "keyint_sec" - For video encoders, sets the keyframe interval
value, in seconds, or closest possible approximation. (Author's
note: This should have have been "keyint", in frames.)
Examples of encoders:
Video encoders:
- The
x264 encoder <https://github.com/obsproject/obs-studio/tree/master/plugins/obs-x264>_ - The
FFmpeg NVENC encoder <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c>_ - The
Quicksync encoder <https://github.com/obsproject/obs-studio/tree/master/plugins/obs-qsv11>_
- The
Audio encoders:
- The
FFmpeg AAC/Opus encoder <https://github.com/obsproject/obs-studio/blob/master/plugins/obs-ffmpeg/obs-ffmpeg-audio-encoders.c>_
- The
.. _plugins_services:
Services
Services are custom implementations of streaming services, which are
used with outputs that stream. For example, you could have a custom
implementation for streaming to Twitch, and another for YouTube to allow
the ability to log in and use their APIs to do things such as get the
RTMP servers or control the channel. The libobs/obs-service.h_ file
is the dedicated header for implementing services. See the
:doc:reference-services for more information.
(Author's note: the service API is incomplete as of this writing)
For example, to implement a service object, you need to define an
:c:type:obs_service_info structure and fill it out with information
and callbacks related to your service:
.. code:: cpp
/* my-service.c */
[...]
struct obs_service_info my_service_service = {
.id = "my_service",
.get_name = my_service_name,
.create = my_service_create,
.destroy = my_service_destroy,
.encode = my_service_encode,
.update = my_service_update,
.get_url = my_service_url,
.get_key = my_service_key
};
Then, in my-plugin.c, you would call :c:func:obs_register_service() in
:c:func:obs_module_load() to register the service with libobs.
.. code:: cpp
/* my-plugin.c */
[...]
extern struct obs_service_info my_service; /* Defined in my-service.c */
bool obs_module_load(void)
{
obs_register_service(&my_service);
[...]
return true;}
The only two existing services objects are the "common RTMP services"
and "custom RTMP service" objects in plugins/rtmp-services <https://github.com/obsproject/obs-studio/tree/master/plugins/rtmp-services>_
Settings
Settings (see libobs/obs-data.h_) are used to get or set settings data
typically associated with libobs objects, and can then be saved and
loaded via Json text. See the :doc:reference-settings for more
information.
The obs_data_t is the equivalent of a Json object, where it's a string
table of sub-objects, and the obs_data_array_t is similarly used to
store an array of obs_data_t objects, similar to Json arrays (though
not quite identical).
To create an obs_data_t or obs_data_array_t object, you'd call the
:c:func:obs_data_create() or :c:func:obs_data_array_create()
functions. obs_data_t and obs_data_array_t objects are reference
counted, so when you are finished with the object, call
:c:func:obs_data_release() or :c:func:obs_data_array_release() to
release those references. Any time an obs_data_t or
obs_data_array_t object is returned by a function, their references
are incremented, so you must release those references each time.
To set values for an obs_data_t object, you'd use one of the following
functions:
.. code:: cpp
/* Set functions */
EXPORT void obs_data_set_string(obs_data_t *data, const char *name, const char *val);
EXPORT void obs_data_set_int(obs_data_t *data, const char *name, long long val);
EXPORT void obs_data_set_double(obs_data_t *data, const char *name, double val);
EXPORT void obs_data_set_bool(obs_data_t *data, const char *name, bool val);
EXPORT void obs_data_set_obj(obs_data_t *data, const char *name, obs_data_t *obj);
EXPORT void obs_data_set_array(obs_data_t *data, const char *name, obs_data_array_t *array);
Similarly, to get a value from an obs_data_t object, you'd use one of
the following functions:
.. code:: cpp
/* Get functions */
EXPORT const char *obs_data_get_string(obs_data_t *data, const char *name);
EXPORT long long obs_data_get_int(obs_data_t *data, const char *name);
EXPORT double obs_data_get_double(obs_data_t *data, const char *name);
EXPORT bool obs_data_get_bool(obs_data_t *data, const char *name);
EXPORT obs_data_t *obs_data_get_obj(obs_data_t *data, const char *name);
EXPORT obs_data_array_t *obs_data_get_array(obs_data_t *data, const char *name);
Unlike typical Json data objects, the obs_data_t object can also set
default values. This allows the ability to control what is returned if
there is no value assigned to a specific string in an obs_data_t
object when that data is loaded from a Json string or Json file. Each
libobs object also has a get_defaults callback which allows setting
the default settings for the object on creation.
These functions control the default values are as follows:
.. code:: cpp
/* Default value functions. */
EXPORT void obs_data_set_default_string(obs_data_t *data, const char *name, const char *val);
EXPORT void obs_data_set_default_int(obs_data_t *data, const char *name, long long val);
EXPORT void obs_data_set_default_double(obs_data_t *data, const char *name, double val);
EXPORT void obs_data_set_default_bool(obs_data_t *data, const char *name, bool val);
EXPORT void obs_data_set_default_obj(obs_data_t *data, const char *name, obs_data_t *obj);
Properties
Properties (see libobs/obs-properties.h_) are used to automatically
generate user interface to modify settings for a libobs object (if
desired). Each libobs object has a get_properties callback which is
used to generate properties. The properties API defines specific
properties that are linked to the object's settings, and the front-end
uses those properties to generate widgets in order to allow the user to
modify the settings. For example, if you had a boolean setting, you
would use :c:func:obs_properties_add_bool() to allow the user to be
able to change that setting. See the :doc:reference-properties for
more information.
An example of this:
.. code:: cpp
static obs_properties_t *my_source_properties(void *data)
{
obs_properties_t *ppts = obs_properties_create();
obs_properties_add_bool(ppts, "my_bool",
obs_module_text("MyBool"));
UNUSED_PARAMETER(data);
return ppts;
}
[...]
struct obs_source_info my_source {
.get_properties = my_source_properties,
[...]
};
The data parameter is the object's data if the object is present.
Typically this is unused and probably shouldn't be used if possible. It
can be null if the properties are retrieved without an object associated
with it.
Properties can also be modified depending on what settings are shown.
For example, you can mark certain properties as disabled or invisible
depending on what a particular setting is set to using the
:c:func:obs_property_set_modified_callback() function.
For example, if you wanted boolean property A to hide text property B:
.. code:: cpp
static bool setting_a_modified(obs_properties_t *ppts,
obs_property_t *p, obs_data_t *settings)
{
bool enabled = obs_data_get_bool(settings, "setting_a");
p = obs_properties_get(ppts, "setting_b");
obs_property_set_enabled(p, enabled);
/* return true to update property widgets, false
otherwise */
return true;}
[...]
static obs_properties_t *my_source_properties(void *data)
{
obs_properties_t *ppts = obs_properties_create();
obs_property_t *p;
p = obs_properties_add_bool(ppts, "setting_a",
obs_module_text("SettingA"));
obs_property_set_modified_callback(p, setting_a_modified);
obs_properties_add_text(ppts, "setting_b",
obs_module_text("SettingB"),
OBS_TEXT_DEFAULT);
return ppts;}
Localization
Typically, most plugins bundled with OBS Studio will use a simple
ini-file localization method, where each file is a different language.
When using this method, the :c:func:OBS_MODULE_USE_DEFAULT_LOCALE()
macro is used which will automatically load/destroy the locale data with
no extra effort on part of the plugin. Then the
:c:func:obs_module_text() function (which is automatically declared as
an extern by libobs/obs-module.h_) is used when text lookup is needed.
There are two exports the module used to load/destroy locale: the
:c:func:obs_module_set_locale() export, and the
:c:func:obs_module_free_locale() export. The
:c:func:obs_module_set_locale() export is called by libobs to set the
current language, and then the :c:func:obs_module_free_locale() export
is called by libobs on destruction of the module. If you wish to
implement a custom locale implementation for your plugin, you'd want to
define these exports along with the :c:func:obs_module_text() extern
yourself instead of relying on the
:c:func:OBS_MODULE_USE_DEFAULT_LOCALE() macro.
.. ---------------------------------------------------------------------------
.. _libobs/obs-module.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-module.h
.. _libobs/obs.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs.h
.. _libobs/obs-source.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-source.h
.. _libobs/obs-output.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-output.h
.. _libobs/obs-encoder.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-encoder.h
.. _libobs/obs-service.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-service.h
.. _libobs/obs-data.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-data.h
.. _libobs/obs-properties.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-properties.h
.. _libobs/graphics/graphics.h: https://github.com/obsproject/obs-studio/blob/master/libobs/graphics/graphics.h
File: docs/sphinx/reference-canvases.rst
Canvas API Reference (obs_canvas_t)
.. danger::
Canvases are still in their early stages of implementation and the API will evolve as they are gradually integrated
across OBS Studio.
The Canvas API should be considered unstable and may be changed without warning. This documentation serves to aid
in their iterative development within OBS Studio.
If you are developing a plugin that utilizes canvases, proceed with great caution.
Canvases are reference-counted objects that contain scenes and define how those are rendered.
They provide a video object which can be used with encoders or raw outputs.
libobs maintains a main canvas that exists at all times and is used for the default video outputs.
.. type:: obs_canvas_t
A reference-counted canvas.
.. type:: obs_weak_canvas_t
A weak reference to a canvas.
.. code:: cpp
#include <obs.h>
.. _canvas_signal_handler_reference:
Canvas Signals
The following signals are defined for canvases:
remove (ptr canvas)
Called when the :c:func:obs_canvas_remove() function is called on the canvas.
destroy (ptr canvas)
Called when a canvas is about to be destroyed.
video_reset (ptr canvas)
Called when the canvas's video mix has been reset after a call to
:c:func:obs_reset_video() or :c:func:obs_canvas_reset_video().
source_add (ptr canvas, ptr source)
Called when a source has been added to the canvas.
source_remove (ptr canvas, ptr source)
Called when a source has been removed from the canvas.
rename (ptr canvas, string new_name, string prev_name)
Called when the canvas has been renamed.
channel_change (ptr canvas, int channel, in out ptr source, ptr prev_source)
Called when a channel source has been changed.
Canvas Flags
Canvases can have different behaviors, these can be controlled via the flags parameter when creating a canvas.
Flags may be 0 or a bitwise OR combination of the following values:
- MAIN - Main canvas, cannot be renamed or reset, cannot be set by user
- ACTIVATE - Canvas's sources will become active when they are visible
- MIX_AUDIO - Audio from channels in this canvas will be mixed into the audio output
- SCENE_REF - Canvas will hold references for scene sources
- EPHEMERAL - Indicates this canvas is not supposed to be saved
Additionally, the following preset combinations of flags are defined:
- PROGRAM which equals
ACTIVATE | MIX_AUDIO | SCENE_REF - PREVIEW which equals
EPHEMERAL - DEVICE which equals
ACTIVATE | EPHEMERAL
General Canvas Functions
.. function:: obs_canvas_t *obs_get_main_canvas()
Get a strong reference to the main OBS canvas.
.. function:: obs_canvas_t *obs_canvas_create(const char *name, struct obs_video_info *ovi, uint32_t flags)
Creates a new canvas.
:param name: Name, will be deduplicated if necessary
:param ovi: Video configuration to use for this canvas's video output
:param flags: Canvas flags
:return: Canvas object
.. function:: obs_canvas_t *obs_canvas_create_private(const char *name, struct obs_video_info *ovi, uint32_t flags)
Creates a new private canvas.
:param name: Name, will not be deduplicated
:param ovi: Video configuration to use for this canvas's video output
:param flags: Canvas flags
:return: Canvas object
.. function:: void obs_canvas_remove(obs_canvas_t *canvas)
Signal that references to canvas should be released and mark the canvas as removed.
.. function:: bool obs_canvas_removed(obs_canvas_t *canvas)
Returns if a canvas is marked as removed (i.e., should no longer be used).
.. function:: void obs_canvas_set_name(obs_canvas_t *canvas, const char *name)
Set canvas name
.. function:: const char *obs_canvas_get_name(const obs_canvas_t *canvas)
Get canvas name
.. function:: const char *obs_canvas_get_uuid(const obs_canvas_t *canvas)
Get canvas UUID
.. function:: uint32_t obs_canvas_get_flags(const obs_canvas_t *canvas)
Gets flags set on a canvas
Saving/Loading Functions
.. function:: obs_data_t *obs_save_canvas(obs_canvas_t *source)
Saves a canvas to settings data
.. function:: obs_canvas_t *obs_load_canvas(obs_data_t *data)
Loads a canvas from settings data
Reference Counting Functions
.. function:: obs_canvas_t *obs_canvas_get_ref(obs_canvas_t *canvas)
Add strong reference to a canvas
.. function:: void obs_canvas_release(obs_canvas_t *canvas)
Release strong reference
.. function:: void obs_weak_canvas_addref(obs_weak_canvas_t *weak)
Add weak reference
.. function:: void obs_weak_canvas_release(obs_weak_canvas_t *weak)
Release weak reference
.. function:: obs_weak_canvas_t *obs_canvas_get_weak_canvas(obs_canvas_t *canvas)
Get weak reference from strong reference
.. function:: obs_canvas_t *obs_weak_canvas_get_canvas(obs_weak_canvas_t *weak)
Get strong reference from weak reference
Canvas Channel Functions
.. function:: void obs_canvas_set_channel(obs_canvas_t *canvas, uint32_t channel, obs_source_t *source)
Sets the source to be used for a canvas channel.
.. function:: obs_source_t *obs_canvas_get_channel(obs_canvas_t *canvas, uint32_t channel)
Gets the source currently in use for a canvas channel.
Canvas Source List Functions
.. function:: obs_scene_t *obs_canvas_scene_create(obs_canvas_t *canvas, const char *name)
Create scene attached to a canvas.
.. function:: void obs_canvas_scene_remove(obs_scene_t *scene)
Remove a scene from a canvas.
.. function:: void obs_canvas_move_scene(obs_scene_t *scene, obs_canvas_t *dst)
Move scene to another canvas, detaching it from the previous one and deduplicating the name if needed.
.. function:: void obs_canvas_enum_scenes(obs_canvas_t *canvas, bool (*enum_proc)(void *, obs_source_t *), void *param)
Enumerates scenes belonging to a canvas.
Callback function returns true to continue enumeration, or false to end enumeration.
.. function:: obs_source_t *obs_canvas_get_source_by_name(const char *name)
Gets a canvas source by its name.
Increments the source reference counter, use
:c:func:obs_source_release() to release it when complete.
.. function:: obs_scene_t *obs_canvas_get_scene_by_name(const char *name)
Gets a canvas scene by its name.
Increments the source reference counter, use
:c:func:obs_scene_release() to release it when complete.
Canvas Video Functions
.. function:: bool obs_canvas_reset_video(obs_canvas_t *canvas, struct obs_video_info *ovi)
Reset a canvas's video configuration.
Note that the frame rate property is ignored and the global rendering frame rate is used instead.
.. function:: bool obs_canvas_has_video(obs_canvas_t *canvas)
Returns true if the canvas video is configured.
.. function:: video_t *obs_canvas_get_video(const obs_canvas_t *canvas)
Get canvas video output
.. function:: bool obs_canvas_get_video_info(const obs_canvas_t *canvas, struct obs_video_info *ovi)
Get canvas video info (if any)
.. function:: void obs_canvas_render(obs_canvas_t *canvas)
Render the canvas's view. Must be called on the graphics thread.
File: docs/sphinx/reference-core.rst
OBS Core API Reference
.. code:: cpp
#include <obs.h>
.. _obs_init_shutdown_reference:
Initialization, Shutdown, and Information
.. function:: bool obs_startup(const char *locale, const char *module_config_path, profiler_name_store_t *store)
Initializes the OBS core context.
:param locale: The locale to use for modules
(E.G. "en-US")
:param module_config_path: Path to module config storage directory
(or NULL if none)
:param store: The profiler name store for OBS to use or NULL
:return: false if already initialized or failed
to initialize
.. function:: void obs_shutdown(void)
Releases all data associated with OBS and terminates the OBS context.
.. function:: bool obs_initialized(void)
:return: true if the main OBS context has been initialized
.. function:: uint32_t obs_get_version(void)
:return: The current core version
.. function:: const char *obs_get_version_string(void)
:return: The current core version string
.. function:: void obs_set_locale(const char *locale)
Sets a new locale to use for modules. This will call
:c:func:obs_module_set_locale() for each module with the new locale.
:param locale: The locale to use for modules
.. function:: const char *obs_get_locale(void)
:return: The current locale
.. function:: profiler_name_store_t *obs_get_profiler_name_store(void)
:return: The profiler name store (see util/profiler.h) used by OBS,
which is either a name store passed to :c:func:obs_startup(), an
internal name store, or NULL in case :c:func:obs_initialized()
returns false.
.. function:: int obs_reset_video(struct obs_video_info *ovi)
Sets base video output base resolution/fps/format.
Note: This data cannot be changed if an output is currently active.
Note: The graphics module cannot be changed without fully destroying
the OBS context.
:param ovi: Pointer to an obs_video_info structure containing the
specification of the graphics subsystem,
:return: | OBS_VIDEO_SUCCESS - Success
| OBS_VIDEO_NOT_SUPPORTED - The adapter lacks capabilities
| OBS_VIDEO_INVALID_PARAM - A parameter is invalid
| OBS_VIDEO_CURRENTLY_ACTIVE - Video is currently active
| OBS_VIDEO_MODULE_NOT_FOUND - The graphics module is not found
| OBS_VIDEO_FAIL - Generic failure
Relevant data types used with this function:
.. code:: cpp
struct obs_video_info {
/**
* Graphics module to use (usually "libobs-opengl" or "libobs-d3d11")
*/
const char *graphics_module;
uint32_t fps_num; /**< Output FPS numerator */
uint32_t fps_den; /**< Output FPS denominator */
uint32_t base_width; /**< Base compositing width */
uint32_t base_height; /**< Base compositing height */
uint32_t output_width; /**< Output width */
uint32_t output_height; /**< Output height */
enum video_format output_format; /**< Output format */
/** Video adapter index to use (NOTE: avoid for optimus laptops) */
uint32_t adapter;
/** Use shaders to convert to different color formats */
bool gpu_conversion;
enum video_colorspace colorspace; /**< YUV type (if YUV) */
enum video_range_type range; /**< YUV range (if YUV) */
enum obs_scale_type scale_type; /**< How to scale if scaling */};
.. function:: bool obs_reset_audio(const struct obs_audio_info *oai)
Sets base audio output format/channels/samples/etc.
Note: Cannot reset base audio if an output is currently active.
:return: true if successful, false otherwise
Relevant data types used with this function:
.. code:: cpp
struct obs_audio_info {
uint32_t samples_per_sec;
enum speaker_layout speakers;
};
.. function:: bool obs_reset_audio2(const struct obs_audio_info2 *oai)
Sets base audio output format/channels/samples/etc. Also allows the
ability to set the maximum audio latency of OBS, and set whether the
audio buffering is fixed or dynamically increasing.
When using fixed audio buffering, OBS will automatically buffer to
the maximum audio latency on startup.
Maximum audio latency will clamp to the closest multiple of the audio
output frames (which is typically 1024 audio frames).
Note: Cannot reset base audio if an output is currently active.
:return: true if successful, false otherwise
Relevant data types used with this function:
.. code:: cpp
struct obs_audio_info2 {
uint32_t samples_per_sec;
enum speaker_layout speakers;
uint32_t max_buffering_ms;
bool fixed_buffering;};
.. function:: bool obs_get_video_info(struct obs_video_info *ovi)
Gets the current video settings.
:return: false if no video
.. function:: float obs_get_video_sdr_white_level(void)
Gets the current SDR white level.
:return: SDR white level, 300.f if no video
.. function:: float obs_get_video_hdr_nominal_peak_level(void)
Gets the current HDR nominal peak level.
:return: HDR nominal peak level, 1000.f if no video
.. function:: void obs_set_video_levels(float sdr_white_level, float hdr_nominal_peak_level)
Sets the current video levels.
.. function:: bool obs_get_audio_info(struct obs_audio_info *oai)
Gets the current audio settings.
:return: false if no audio
Libobs Objects
.. function:: bool obs_enum_source_types(size_t idx, const char **id)
Enumerates all source types (inputs, filters, transitions, etc).
.. function:: bool obs_enum_input_types(size_t idx, const char **id)
Enumerates all available inputs source types.
Inputs are general source inputs (such as capture sources, device sources,
etc).
.. function:: bool obs_enum_filter_types(size_t idx, const char **id)
Enumerates all available filter source types.
Filters are sources that are used to modify the video/audio output of
other sources.
.. function:: bool obs_enum_transition_types(size_t idx, const char **id)
Enumerates all available transition source types.
Transitions are sources used to transition between two or more other
sources.
.. function:: bool obs_enum_output_types(size_t idx, const char **id)
Enumerates all available output types.
.. function:: bool obs_enum_encoder_types(size_t idx, const char **id)
Enumerates all available encoder types.
.. function:: bool obs_enum_service_types(size_t idx, const char **id)
Enumerates all available service types.
.. function:: void obs_enum_sources(bool (enum_proc)(void, obs_source_t*), void *param)
Enumerates all input sources.
Callback function returns true to continue enumeration, or false to end
enumeration.
Use :c:func:obs_source_get_ref() or
:c:func:obs_source_get_weak_source() if you want to retain a
reference after obs_enum_sources finishes.
For scripting, use :py:func:obs_enum_sources.
.. function:: void obs_enum_scenes(bool (enum_proc)(void, obs_source_t*), void *param)
Enumerates all scenes. Use :c:func:obs_scene_from_source() if the scene is
needed as an :c:type:obs_scene_t. The order that they are enumerated should
not be relied on. If one intends to enumerate the scenes in the order
presented by the OBS Studio Frontend, use :c:func:obs_frontend_get_scenes().
Callback function returns true to continue enumeration, or false to end
enumeration.
Use :c:func:obs_source_get_ref() or
:c:func:obs_source_get_weak_source() if you want to retain a
reference after obs_enum_scenes finishes.
.. function:: void obs_enum_outputs(bool (enum_proc)(void, obs_output_t*), void *param)
Enumerates outputs.
Callback function returns true to continue enumeration, or false to end
enumeration.
Use :c:func:obs_output_get_ref() or
:c:func:obs_output_get_weak_output() if you want to retain a
reference after obs_enum_outputs finishes.
.. function:: void obs_enum_encoders(bool (enum_proc)(void, obs_encoder_t*), void *param)
Enumerates encoders.
Callback function returns true to continue enumeration, or false to end
enumeration.
Use :c:func:obs_encoder_get_ref() or
:c:func:obs_encoder_get_weak_encoder() if you want to retain a
reference after obs_enum_encoders finishes.
.. function:: void obs_enum_canvases(bool (enum_proc)(void, obs_canvas_t*), void *param)
Enumerates canvases.
Callback function returns true to continue enumeration, or false to end
enumeration.
Use :c:func:obs_canvas_get_ref() or
:c:func:obs_canvas_get_weak_canvas() if you want to retain a
reference after obs_enum_canvases finishes.
.. function:: obs_source_t *obs_get_source_by_name(const char *name)
Gets a source by its name.
Increments the source reference counter, use
:c:func:obs_source_release() to release it when complete.
.. function:: obs_source_t *obs_get_source_by_uuid(const char *uuid)
Gets a source by its UUID.
Increments the source reference counter, use
:c:func:obs_source_release() to release it when complete.
.. versionadded:: 29.1
.. function:: obs_source_t *obs_get_transition_by_name(const char *name)
Gets a transition by its name.
Increments the source reference counter, use
:c:func:obs_source_release() to release it when complete.
.. deprecated:: 31.1
Use :c:func:obs_frontend_get_transitions from the Frontend API or :c:func:obs_get_source_by_uuid instead.
.. function:: obs_source_t *obs_get_transition_by_uuid(const char *uuid)
Gets a transition by its UUID.
Increments the source reference counter, use
:c:func:obs_source_release() to release it when complete.
.. versionadded:: 29.1
.. deprecated:: 31.1
Use :c:func:obs_get_source_by_uuid instead.
.. function:: obs_scene_t *obs_get_scene_by_name(const char *name)
Gets a scene by its name.
Increments the scene reference counter, use
:c:func:obs_scene_release() to release it when complete.
.. function:: obs_output_t *obs_get_output_by_name(const char *name)
Gets an output by its name.
Increments the output reference counter, use
:c:func:obs_output_release() to release it when complete.
.. function:: obs_encoder_t *obs_get_encoder_by_name(const char *name)
Gets an encoder by its name.
Increments the encoder reference counter, use
:c:func:obs_encoder_release() to release it when complete.
.. function:: obs_service_t *obs_get_service_by_name(const char *name)
Gets an service by its name.
Increments the service reference counter, use
:c:func:obs_service_release() to release it when complete.
.. function:: obs_canvas_t *obs_get_canvas_by_name(const char *name)
Get a canvas by its name.
Increments the canvas reference counter, use
:c:func:obs_canvas_release() to release it when complete.
.. function:: obs_canvas_t *obs_get_canvas_by_uuid(const char *uuid)
Get a canvas by its UUID.
Increments the canvas reference counter, use
:c:func:obs_canvas_release() to release it when complete.
.. function:: obs_data_t *obs_save_source(obs_source_t *source)
:return: A new reference to a source's saved data. Use
:c:func:obs_data_release() to release it when complete.
.. function:: obs_source_t *obs_load_source(obs_data_t *data)
:return: A source created from saved data
.. function:: void obs_load_sources(obs_data_array_t *array, obs_load_source_cb cb, void *private_data)
Helper function to load active sources from a data array.
Relevant data types used with this function:
.. code:: cpp
typedef void (*obs_load_source_cb)(void *private_data, obs_source_t *source);
.. function:: obs_data_array_t *obs_save_sources(void)
:return: A data array with the saved data of all active sources
.. function:: obs_data_array_t *obs_save_sources_filtered(obs_save_source_filter_cb cb, void *data)
:return: A data array with the saved data of all active sources,
filtered by the cb function
Relevant data types used with this function:
.. code:: cpp
typedef bool (*obs_save_source_filter_cb)(void *data, obs_source_t *source);
Video, Audio, and Graphics
.. function:: void obs_enter_graphics(void)
Helper function for entering the OBS graphics context.
.. function:: void obs_leave_graphics(void)
Helper function for leaving the OBS graphics context.
.. function:: audio_t *obs_get_audio(void)
:return: The main audio output handler for this OBS context
.. function:: video_t *obs_get_video(void)
:return: The main video output handler for this OBS context
.. function:: void obs_set_output_source(uint32_t channel, obs_source_t *source)
Sets the primary output source for a channel.
.. function:: obs_source_t *obs_get_output_source(uint32_t channel)
Gets the primary output source for a channel and increments the reference
counter for that source. Use :c:func:obs_source_release() to release.
.. function:: gs_effect_t *obs_get_base_effect(enum obs_base_effect effect)
Returns a commonly used base effect.
:param effect: | Can be one of the following values:
| OBS_EFFECT_DEFAULT - RGB/YUV
| OBS_EFFECT_DEFAULT_RECT - RGB/YUV (using texture_rect)
| OBS_EFFECT_OPAQUE - RGB/YUV (alpha set to 1.0)
| OBS_EFFECT_SOLID - RGB/YUV (solid color only)
| OBS_EFFECT_BICUBIC - Bicubic downscale
| OBS_EFFECT_LANCZOS - Lanczos downscale
| OBS_EFFECT_BILINEAR_LOWRES - Bilinear low resolution downscale
| OBS_EFFECT_PREMULTIPLIED_ALPHA - Premultiplied alpha
.. function:: void obs_render_main_texture(void)
Renders the main output texture. Useful for rendering a preview pane
of the main output.
.. function:: bool obs_audio_monitoring_available(void)
:return: Whether audio monitoring is supported and available on the current platform
.. function:: void obs_reset_audio_monitoring(void)
Resets all audio monitoring devices.
.. versionadded:: 30.1
.. function:: void obs_enum_audio_monitoring_devices(obs_enum_audio_device_cb cb, void *data)
Enumerates audio devices which can be used for audio monitoring.
Callback function returns true to continue enumeration, or false to end
enumeration.
Relevant data types used with this function:
.. code:: cpp
typedef bool (*obs_enum_audio_device_cb)(void *data, const char *name, const char *id);
.. function:: bool obs_set_audio_monitoring_device(const char *name, const char *id)
Sets the current audio device for audio monitoring.
.. function:: void obs_get_audio_monitoring_device(const char **name, const char **id)
Gets the current audio device for audio monitoring.
.. function:: void obs_add_main_render_callback(void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param)
void obs_remove_main_render_callback(void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param)
Adds/removes a main rendering callback. Allows custom rendering to
the main stream/recording output.
For scripting (Lua only), use :py:func:obs_add_main_render_callback
and :py:func:obs_remove_main_render_callback.
.. function:: void obs_add_main_rendered_callback(void (*rendered)(void *param), void *param)
void obs_remove_main_rendered_callback(void (*rendered)(void *param), void *param)
Adds/removes a main rendered callback. Allows using the result of
the main stream/recording output.
.. versionadded:: 29.1
.. function:: void obs_add_raw_video_callback(const struct video_scale_info *conversion, void (*callback)(void *param, struct video_data *frame), void *param)
void obs_remove_raw_video_callback(void (*callback)(void *param, struct video_data *frame), void *param)
Adds/removes a raw video callback. Allows the ability to obtain raw
video frames without necessarily using an output.
:param conversion: Specifies conversion requirements. Can be NULL.
:param callback: The callback that receives raw video frames.
:param param: The private data associated with the callback.
.. function:: void obs_add_raw_audio_callback(size_t mix_idx, const struct audio_convert_info *conversion, audio_output_callback_t callback, void *param)
void obs_remove_raw_raw_callback(size_t track, audio_output_callback_t callback, void *param)
Adds/removes a raw audio callback. Allows the ability to obtain raw
audio data without necessarily using an output.
:param mix_idx: Specifies audio track to get data from.
:param conversion: Specifies conversion requirements. Can be NULL.
:param callback: The callback that receives raw audio data.
:param param: The private data associated with the callback.
Primary signal/procedure handlers
.. function:: signal_handler_t *obs_get_signal_handler(void)
:return: The primary obs signal handler. Should not be manually freed,
as its lifecycle is managed by libobs.
See :ref:core_signal_handler_reference for more information on
core signals.
.. function:: proc_handler_t *obs_get_proc_handler(void)
:return: The primary obs procedure handler. Should not be manually freed,
as its lifecycle is managed by libobs.
.. _core_signal_handler_reference:
Core OBS Signals
source_create (ptr source)
Called when a source has been created.
source_destroy (ptr source)
Called when a source has been destroyed.
source_remove (ptr source)
Called when a source has been removed (:c:func:obs_source_remove()
has been called on the source).
source_update (ptr source)
Called when a source's settings have been updated.
source_save (ptr source)
Called when a source is being saved.
source_load (ptr source)
Called when a source is being loaded.
source_activate (ptr source)
Called when a source has been activated in the main view (visible on
stream/recording).
source_deactivate (ptr source)
Called when a source has been deactivated from the main view (no
longer visible on stream/recording).
source_show (ptr source)
Called when a source is visible on any display and/or on the main
view.
source_hide (ptr source)
Called when a source is no longer visible on any display and/or on
the main view.
source_rename (ptr source, string new_name, string prev_name)
Called when a source has been renamed.
source_volume (ptr source, in out float volume)
Called when a source's volume has changed.
source_audio_activate (ptr source)
Called when a source's audio becomes active.
source_audio_deactivate (ptr source)
Called when a source's audio becomes inactive.
source_filter_add (ptr source, ptr filter)
Called when a filter is added to a source.
source_filter_remove (ptr source, ptr filter)
Called when a filter is removed from a source.
source_transition_start (ptr source)
Called when a transition has started its transition.
source_transition_video_stop (ptr source)
Called when a transition has stopped its video transitioning.
source_transition_stop (ptr source)
Called when a transition has stopped its transition.
channel_change (int channel, in out ptr source, ptr prev_source)
Called when :c:func:obs_set_output_source() has been called.
hotkey_layout_change ()
Called when the hotkey layout has changed.
hotkey_register (ptr hotkey)
Called when a hotkey has been registered.
hotkey_unregister (ptr hotkey)
Called when a hotkey has been unregistered.
hotkey_bindings_changed (ptr hotkey)
Called when a hotkey's bindings has changed.
canvas_create (ptr canvas)
Called when a new public canvas has been created.
canvas_remove (ptr canvas)
Called when the :c:func:obs_canvas_remove() function is called on a public canvas.
canvas_destroy (ptr canvas)
Called when a public canvas is about to be destroyed.
canvas_video_reset (ptr canvas)
Called when a public canvas's video mix has been reset after a call to
:c:func:obs_reset_video() or :c:func:obs_canvas_reset_video().
canvas_rename (ptr canvas, string new_name, string prev_name)
Called when a public canvas has been renamed.
video_reset ()
Called when a the main OBS video has been reset.
.. _display_reference:
Displays
.. function:: obs_display_t *obs_display_create(const struct gs_init_data *graphics_data)
Adds a new window display linked to the main render pipeline. This creates
a new swap chain which updates every frame.
(Important note: do not use more than one display widget within the
hierarchy of the same base window; this will cause presentation
stalls on macOS.)
:param graphics_data: The swap chain initialization data
:return: The new display context, or NULL if failed
Relevant data types used with this function:
.. code:: cpp
enum gs_color_format {
[...]
GS_RGBA,
GS_BGRX,
GS_BGRA,
GS_RGBA16F,
GS_RGBA32F,
[...]
};
enum gs_zstencil_format {
GS_ZS_NONE,
GS_Z16,
GS_Z24_S8,
GS_Z32F,
GS_Z32F_S8X24
};
struct gs_window {
#if defined(_WIN32)
void *hwnd;
#elif defined(APPLE)
__unsafe_unretained id view;
#elif defined(linux) || defined(FreeBSD)
uint32_t id;
void *display;
#endif
};
struct gs_init_data {
struct gs_window window;
uint32_t cx, cy;
uint32_t num_backbuffers;
enum gs_color_format format;
enum gs_zstencil_format zsformat;
uint32_t adapter;
};
.. function:: void obs_display_destroy(obs_display_t *display)
Destroys a display context.
.. function:: void obs_display_resize(obs_display_t *display, uint32_t cx, uint32_t cy)
Changes the size of a display context.
.. function:: void obs_display_add_draw_callback(obs_display_t *display, void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param)
Adds a draw callback for a display context, which will be called
whenever the display is rendered.
:param display: The display context
:param draw: The draw callback which is called each time a frame
updates
:param param: The user data to be associated with this draw callback
.. function:: void obs_display_remove_draw_callback(obs_display_t *display, void (*draw)(void *param, uint32_t cx, uint32_t cy), void *param)
Removes a draw callback for a display context.
.. function:: void obs_display_set_enabled(obs_display_t *display, bool enable)
Enables/disables a display context.
.. function:: bool obs_display_enabled(obs_display_t *display)
:return: true if the display is enabled, false otherwise
.. function:: void obs_display_set_background_color(obs_display_t *display, uint32_t color)
Sets the background (clear) color for the display context.
.. _view_reference:
Views
.. function:: obs_view_t *obs_view_create(void)
:return: A view context
.. function:: void obs_view_destroy(obs_view_t *view)
Destroys a view context.
.. function:: void obs_view_render(obs_view_t *view)
Renders the sources of this view context.
.. function:: video_t *obs_view_add(obs_view_t *view)
Renders the sources of this view context.
:return: The main video output handler for the view context
.. function:: video_t *obs_view_add2(obs_view_t *view, struct obs_video_info *ovi)
Adds a view to the main render loop, with custom video settings.
:return: The main video output handler for the view context
.. function:: void obs_view_remove(obs_view_t *view)
Removes a view from the main render loop.
.. function:: void obs_view_set_source(obs_view_t *view, uint32_t channel, obs_source_t *source)
Sets the source to be used for this view context.
.. function:: obs_source_t *obs_view_get_source(obs_view_t *view, uint32_t channel)
:return: The source currently in use for this view context
.. function:: void obs_view_enum_video_info(obs_view_t *view, bool (*enum_proc)(void *, struct obs_video_info *), void *param)
Enumerates all the video info of all mixes that use the specified mix.
.. versionadded:: 30.1