1Frontends
2=========
3
4Initialization and Shutdown
5---------------------------
6
7To initialize libobs, you must call :c:func:`obs_startup()`,
8:c:func:`obs_reset_video()`, and then :c:func:`obs_reset_audio()`.
9After that, modules typically should be loaded.
10
11You can load individual modules manually by calling
12:c:func:`obs_open_module()`.  After loading, the
13:c:func:`obs_open_module()` function, you must then call
14:c:func:`obs_init_module()` to initialize the module.
15
16You can load modules automatically via two functions:
17:c:func:`obs_add_module_path()` and :c:func:`obs_load_all_modules()`.
18
19After all plugin modules have been loaded, call
20:c:func:`obs_post_load_modules()`.
21
22Certain modules may optionally use a configuration storage directory,
23which is set as a parameter to :c:func:`obs_startup()`.
24
25When it's time to shut down the frontend, make sure to release all
26references to any objects, free any data, and then call
27:c:func:`obs_shutdown()`.  If for some reason any libobs objects have
28not been released, they will be destroyed automatically and a warning
29will be logged.
30
31To detect if any general memory allocations have not been freed, call
32the :c:func:`bnum_allocs()` to get the number of allocations remaining.
33If the number remaining is above 0, there are memory leaks.
34
35See :ref:`obs_init_shutdown_reference` for more information.
36
37
38Reconfiguring Video
39-------------------
40
41Any time after initialization, video settings can be reconfigured by
42calling :c:func:`obs_reset_video()` as long as no outputs are active.
43Audio was originally intended to have this capability as well, but
44currently is not able to be reset once initialized; libobs must be fully
45shutdown in order to reconfigure audio settings.
46
47
48Displays
49--------
50
51Displays as the name implies are used for display/preview panes.  To use
52displays, you must have a native window handle or identifier to draw on.
53
54First you must call :c:func:`obs_display_create()` to initialize the
55display, then you must assign a draw callback with
56:c:func:`obs_display_add_draw_callback()`.  If you need to remove a draw
57callback, call :c:func:`obs_display_remove_draw_callback()` similarly.
58
59When drawing, to draw the main preview window (if any), call
60:c:func:`obs_render_main_texture()`.  If you need to render a specific
61source on a secondary display, you can increment its "showing" state
62with :c:func:`obs_source_inc_showing()` while it's showing in the
63secondary display, draw it with :c:func:`obs_source_video_render()` in
64the draw callback, then when it's no longer showing in the secondary
65display, call :c:func:`obs_source_dec_showing()`.
66
67If the display needs to be resized, call :c:func:`obs_display_resize()`.
68
69If the display needs a custom background color other than black, call
70:c:func:`obs_display_set_background_color()`.
71
72If the display needs to be temporarily disabled, call
73:c:func:`obs_display_set_enabled()` to disable, and
74:c:func:`obs_display_enabled()` to get its enabled/disabled state.
75
76Then call :c:func:`obs_display_destroy()` to destroy the display when
77it's no longer needed.
78
79*(Important note: do not use more than one display widget within the
80hierarchy of the same base window; this will cause presentation stalls
81on Macs.)*
82
83For an example of how displays are used with Qt, see
84`UI/qt-display.hpp`_ and `UI/qt-display.cpp`_.
85
86See :ref:`display_reference` for more information.
87
88
89Saving/Loading Objects and Object Management
90--------------------------------------------
91
92The frontend is generally expected to manage its own objects, however
93for sources, there are some helper functions to allow easier
94saving/loading all sources: :c:func:`obs_save_sources()` and
95:c:func:`obs_load_sources()`.  With those functions, all sources that
96aren't private will automatically be saved and loaded.  You can also
97save/load individual sources manually by using
98:c:func:`obs_save_source()` and :c:func:`obs_load_source()`.
99
100*(Author's note: I should not have written those helper functions; the
101downside is I had to add "private" sources that aren't saveable via the*
102:c:func:`obs_source_create_private()` *function.  Just one of the many
103minor design flaws that can occur during long-term development.)*
104
105For outputs, encoders, and services, there are no helper functions, so
106usually you'd get their settings individually and save them as json.
107(See :c:func:`obs_output_get_settings()`).  You don't have to save each
108object to different files individually; you'd save multiple objects
109together in a bigger :c:type:`obs_data_t` object, then save that via
110:c:func:`obs_data_save_json_safe()`, then load everything again via
111:c:func:`obs_data_create_from_json_file_safe()`.
112
113
114Signals
115-------
116
117The core, as well as scenes and sources, have a set of standard signals
118that are used to determine when something happens or changes.
119
120Typically the most important signals are the
121:ref:`output_signal_handler_reference`:  the **start**, **stop**,
122**starting**, **stopping**, **reconnect**, **reconnect_success**
123signals in particular.
124
125Most other signals for scenes/sources are optional if you are the only
126thing controlling their state.  However, it's generally recommended to
127watch most signals when possible for consistency.  See
128:ref:`source_signal_handler_reference` and :ref:`scene_signal_reference`
129for more information.
130
131For example, let's say you wanted to connect a callback to the **stop**
132signal of an output.  The **stop** signal has two parameters:  *output*
133and *code*.  A callback for this signal would typically look something
134like this:
135
136.. code:: cpp
137
138   static void output_stopped(void *my_data, calldata_t *cd)
139   {
140           obs_output_t *output = calldata_ptr(cd, "output");
141           int code = calldata_int(cd, "code");
142
143           [...]
144   }
145
146*(Note that callbacks are not thread-safe.)*
147
148Then to connect it to the **stop** signal, you use the
149:c:func:`signal_handler_connect()` with the callback.  In this case for
150example:
151
152.. code:: cpp
153
154   signal_handler_t *handler = obs_output_get_signal_handler(output);
155   signal_handler_connect(handler, "stop", output_stopped);
156
157
158.. _displaying_sources:
159
160Displaying Sources
161------------------
162
163Sources are displayed on stream/recording via :ref:`output_channels`
164with the :c:func:`obs_set_output_source()` function.  There are 64
165channels that you can assign sources to, which will draw on top of each
166other in ascending index order.  Typically, a normal source shouldn't be
167directly assigned with this function; you would use a scene or a
168transition containing scenes.
169
170To draw one or more sources together with a specific transform applied
171to them, scenes are used.  To create a scene, you call
172:c:func:`obs_scene_create()`.  Child sources are referenced using scene
173items, and then specific transforms are applied to those scene items.
174Scene items are not sources but containers for sources; the same source
175can be referenced by multiple scene items within the same scene, or can
176be referenced in multiple scenes.  To create a scene item that
177references a source, you call :c:func:`obs_scene_add()`, which returns a
178new reference to a scene item.
179
180To change the transform of a scene item, you typically would call a
181function like :c:func:`obs_sceneitem_set_pos()` to change its position,
182:c:func:`obs_sceneitem_set_rot()` to change its rotation, or
183:c:func:`obs_sceneitem_set_scale()` to change its scaling.  Scene items
184can also force scaling in to a custom size constraint referred to as a
185"bounding box"; a bounding box will force the source to be drawn at a
186specific size and with specific scaling constraint within that size.  To
187use a bounding box, you call the
188:c:func:`obs_sceneitem_set_bounds_type()`,
189:c:func:`obs_sceneitem_set_bounds()`, and
190:c:func:`obs_sceneitem_set_bounds_alignment()`.  Though the easiest way
191to handle everything related to transforms is to use the
192:c:func:`obs_sceneitem_set_info()` and
193:c:func:`obs_sceneitem_get_info()` functions.  See
194:ref:`scene_item_reference` for all the functions related to scene
195items.
196
197Usually, a smooth transition between multiple scenes is required.  To do
198this, transitions are used.  To create a transition, you use
199:c:func:`obs_source_create()` or :c:func:`obs_source_create_private()`
200like any other source.  Then, to activate a transition, you call
201:c:func:`obs_transition_start()`.  When the transition is not active and
202is only displaying one source, it performs a pass-through to the current
203displaying source.  See :ref:`transitions` for more functions related to
204using transitions.
205
206The recommended way to set up your structure is to have a transition as
207the source that is used as the main output source, then your scene as a
208child of the transition, then your sources as children in the scene.
209When you need to switch to a new scene, simply call
210:c:func:`obs_transition_start()`.
211
212
213Outputs, Encoders, and Services
214-------------------------------
215
216Outputs, encoders, and services are all used together, and managed a bit
217differently than sources.  There currently is no global function to
218save/load them, that must be accomplished manually for now via their
219settings if needed.
220
221Encoders are used with outputs that expect encoded data (which is almost
222all typical outputs), such as standard file recording or streaming.
223
224Services are used with outputs to a stream; the `RTMP output`_ is the
225quintessential example of this.
226
227Here's an example of how an output would be used with encoders and
228services:
229
230.. code:: cpp
231
232   obs_encoder_set_video(my_h264_encoder, obs_get_video());
233   obs_encoder_set_audio(my_aac_encoder, obs_get_audio());
234   obs_output_set_video_encoder(my_output, my_h264_encoder);
235   obs_output_set_audio_encoder(my_output, my_aac_encoder);
236   obs_output_set_service(my_output, my_service); /* if a stream */
237   obs_output_start(my_output);
238
239Once the output has started successfully, it automatically starts
240capturing the video and/or audio from the current video/audio output
241(i.e. any sources that are assigned to the :ref:`output_channels`).
242
243If the output fails to start up, it will send the **stop** signal with
244an error code in the *code* parameter, possibly accompanied by a
245translated error message stored that can be obtained via the
246:c:func:`obs_output_get_last_error()` function.
247
248.. --------------------------------------------------------------------
249
250.. _RTMP Output: https://github.com/jp9000/obs-studio/blob/master/plugins/obs-outputs/rtmp-stream.c
251.. _UI/qt-display.hpp: https://github.com/jp9000/obs-studio/blob/master/UI/qt-display.hpp
252.. _UI/qt-display.cpp: https://github.com/jp9000/obs-studio/blob/master/UI/qt-display.cpp
253