Skip to content

Commit 2aee34b

Browse files
authored
Add RFC: Add notion of protocol (#45)
1 parent 5f0b6f4 commit 2aee34b

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Summary
2+
- Define supported protocols for services and outputs in libobs and OBS Studio
3+
- Outputs for streaming are registered with one or more compatible protocols and codecs
4+
- Only codecs compatible with the output and the service are shown
5+
- Audio codec can be chosen if various compatible, codec in simple mode and encoder advanced output mode.
6+
- Will be extended with RFC 39
7+
8+
# Motivation
9+
Create a better management of outputs, encoders, and services with an approach focused on protocols.
10+
11+
# Design
12+
13+
## Outputs API
14+
Only outputs with the `OBS_OUTPUT_SERVICE` flag are concerned.
15+
16+
Adding to `obs_output_info`:
17+
- `const char *protocols`: protocols separated with a semi-colon (ex: `"RTMP;RTMPS"`), required to register the output. The string used to identify the protocol must be its officialy/widely used acronym, those acronyms are usually uppercased.
18+
19+
Adding to this API these functions:
20+
- `const char *obs_output_get_protocols(const obs_output_t *output)`: returns protocols supported by the output.
21+
- `bool obs_is_output_protocol_registered(const char *protocol)`: return true if an output with the protocol is registered.
22+
- `void obs_enum_output_types_with_protocol(const char *protocol, void *data, bool (*enum_cb)(void *data, const char *id))`: enumerate through a callback all outputs types compatible with the given protocol.
23+
- `bool obs_enum_output_protocols(size_t idx, const char **protocol)`: enumerate all registered protocol.
24+
- `const char *obs_get_output_supported_video_codecs(const char *id)`: return compatible video codecs of the given output id.
25+
- `const char *obs_get_output_supported_audio_codecs(const char *id)`: return compatible audio codecs of the given output id.
26+
27+
## Services API
28+
Since a streaming service may not accept all the codecs usable by a protocol, adding a way to set supported codecs is required.
29+
30+
Adding to `obs_service_info`:
31+
- `const char *(*get_protocol)(void *data)`: return the protocol used by the service. RFC 39 will allow multi-protocol services in the future.
32+
- `const char **(*get_supported_video_codecs)(void *data)`: video codecs supported by the service. Optional, fallback to protocol supported codecs if not set.
33+
- `const char **(*get_supported_audio_codecs)(void *data)`: audio codecs supported by the service. Optional, fallback to protocol supported codecs if not set.
34+
35+
Adding to this API these functions:
36+
- `const char *obs_service_get_protocol(const obs_service_t *service)`: return the protocol used by the service.
37+
- `const char **obs_service_get_supported_video_codecs(const obs_service_t *service)`: return video codecs compatible with the service.
38+
- `const char **obs_service_get_supported_audio_codecs(const obs_service_t *service)`: return audio codecs compatible with the service.
39+
40+
### Services and connection informations
41+
42+
Depending on the protocol, the service object should provide various types of connection details (e.g., server URL, stream key, username, password).
43+
44+
Currently, `get_key` can provide a stream id (SRT) or an encryption passphrase (RIST) rather than a stream key.
45+
46+
Rather than adding a getter for each possible type of information, a getter where we can choose which type of information we want should be implemented.
47+
48+
Types of connection details will be defined by an enum with only even number values. Odd number values will be reserved for potential third-party protocols (RFC 39).
49+
50+
List of types:
51+
```c
52+
enum obs_service_connect_info {
53+
OBS_SERVICE_CONNECT_INFO_SERVER_URL = 0,
54+
OBS_SERVICE_CONNECT_INFO_STREAM_ID = 2,
55+
OBS_SERVICE_CONNECT_INFO_STREAM_KEY = 2,
56+
OBS_SERVICE_CONNECT_INFO_USERNAME = 4,
57+
OBS_SERVICE_CONNECT_INFO_PASSWORD = 6,
58+
OBS_SERVICE_CONNECT_INFO_ENCRYPT_PASSPHRASE = 8,
59+
};
60+
```
61+
62+
Note: `OBS_SERVICE_CONNECT_INFO_STREAM_ID` is an alias of `OBS_SERVICE_CONNECT_INFO_STREAM_KEY` since they are technically the same. It was done to avoid confusion by forcing only one naming.
63+
64+
Adding to `obs_service_info`:
65+
- `const char *(*get_connect_info)(void *data, uint32_t type)` where `type` is one of the value of the list above indicating which info we want and return `NULL` if it doesn't have it.
66+
- `bool (*can_try_to_connect)(void *data)`, since protocols and services do not always require the same information. This function allows the service to return if it can connect. Return true if the the service has all it needs to connect.
67+
68+
Adding these functions to the Services API:
69+
- `const char *obs_service_get_connect_info(const obs_service_t *service, uint32_t type)`: return the connection information related to the given type (list above).
70+
- `bool obs_service_can_try_to_connect(const obs_service_t *service)`: return if the service can try to connect.
71+
- return `bool (*can_try_to_connect)(void *data)` result.
72+
- return true if `bool (*can_try_to_connect)(void *data)` is not implemented in the service.
73+
- return false if the service object is `NULL`.
74+
75+
`obs_service_get_url()`, `obs_service_get_key()`, `obs_service_get_username()`, and `obs_service_get_password()` will be deprecated in favor of `obs_service_get_connect_info()`.
76+
77+
In the future, if we want to support a protocol that doesn't use a server URL, this scenario is covered by this design.
78+
79+
### About `rtmp-services`
80+
81+
`rtmp-services` is a plugin that provides two services `rtmp_common` and `rtmp_custom`. The use of "rtmp" in these three terms no longer means that it only supports RTMP, it was and is kept to avoid breakage.
82+
83+
- In `rtmp_common`, services must at least support H264 as video codec and AAC or Opus as audio codec. This is a limitation required by the simple output mode.
84+
- NOTE: Some service provides RTMP and RTMPS which force the plugin to check the URI scheme to return the right protocol in this situation.
85+
86+
#### About service JSON file
87+
88+
- For `services` objects, a `"protocol"` field will be added. This will be used to indicate the protocol for services.
89+
- The field is required if server URLs are not RTMP(s) (`rtmp://`, `rtmps://`).
90+
- Services that use a protocol that is not registered will not be shown. For example, OBS Studio without RTMPS support will not show services and servers that rely on RTMPS.
91+
- Codecs field for audio and video will be added to allow services to limit which codec is compatible with the service.
92+
- `"output"` field in the `"recommended"` object will be deprecated, but it will be kept for backward compatibility. `const char *(*get_output_type)(void *data)` in `obs_service_info` will no longer be used by `rtmp-services`.
93+
- The JSON schema will be modified to require the `"protocol"` field when the protocol is not auto-detectable. The same for the `"output"` field to keep backward compatibility.
94+
95+
## UI
96+
97+
### About custom server
98+
99+
The protocol of the custom server will be determined through the URI scheme (e.g., `rtmp`, `rtmps`, `ftl`, `srt`, `rist`) of the server URL and fallback to RTMP.
100+
Those checks will be hardcoded in the UI until RFC 39 replace custom server implementation.
101+
102+
### Audio encoders
103+
104+
If the service/output is compatible with more than one audio codec, the user should be able to choose in the UI which one:
105+
- In simple mode, the user will be able to choose the codec (AAC or Opus).
106+
- In advanced mode, the user will be able to choose a specific encoder.
107+
108+
### Settings loading order
109+
110+
Service settings need to be loaded first and output ones afterward to show only compatible encoder.
111+
112+
### Service and Output settings interactions
113+
114+
NOTE: Since Services API is not usable by third-party for now, this RFC will not consider a scenario where there is no simple encoder preset for the service.
115+
116+
If changing the service results in the selected protocol changing, the Output page should be updated to list only compatible encoders.
117+
118+
If the currently selected encoder (codec) is not supported by the service, the encoder will be changed and the user will be notified about the change.
119+
120+
## What if there are various registered outputs for one protocol?
121+
122+
The improbable situation where a plugin register a output for an already registered protocol could happen, so managing this possibility is required.
123+
124+
- In `obs_service_info`:
125+
- `const char *(*get_output_type)(void *data)` will be renamed `const char *(*get_preferred_output_type)(void *data)` when an API break is possible.
126+
- `const char *obs_service_get_output_type(const obs_service_t *service)` will be deprecated and replaced by `const char *obs_service_get_preferred_output_type(const obs_service_t *service)`.
127+
128+
A function in the UI to prefer first-party outputs will be considered.
129+
An option in advanced output to allow to choose an output type will not be considered for now.

0 commit comments

Comments
 (0)