Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 43 additions & 1 deletion docs/sphinx/reference-outputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,15 @@ Output Definition Structure (obs_output_info)
This variable specifies which codecs are supported by an encoded
output, separated by semicolon.

(Optional, though recommended)
Required if **OBS_OUTPUT_SERVICE** flag is set, otherwise
recommended.

.. member:: const char *obs_output_info.protocols

This variable specifies which protocols are supported by an output,
separated by semicolon.

Required only if **OBS_OUTPUT_SERVICE** flag is set.

.. _output_signal_handler_reference:

Expand Down Expand Up @@ -685,6 +693,40 @@ General Output Functions

---------------------

.. function:: const char *obs_output_get_protocols(const obs_output_t *output)

:return: Supported protocols, separated by semicolon. Always NULL if the
output is not **OBS_OUTPUT_SERVICE**.

---------------------

.. function:: bool obs_is_output_protocol_registered(const char *protocol)

Check if one of the registered output use the given protocol.

:return: A boolean showing if an output with the given
protocol is registered

---------------------

.. function:: bool obs_enum_output_protocols(size_t idx, char **protocol)

Enumerates all registered protocol.

---------------------

.. function:: void obs_enum_output_types_with_protocol(const char *protocol, void *data, bool (*enum_cb)(void *data, const char *id))

Enumerates through a callback all available output types for the given protocol.

:param protocol: Protocol of the outputs to enumerate
:param data: Data passed to the callback
:param enum_cb: Callback used when a matching output is found, the id
of the output is passed to the callback
:return: When all outputs are enumerated or if the callback return *false*

---------------------

Functions used by outputs
-------------------------

Expand Down
10 changes: 10 additions & 0 deletions docs/sphinx/reference-services.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,10 @@ Service Definition Structure
the data manually (typically best to use strlist_split to
generate this)

.. member:: const char *(*obs_service_info.get_protocol)(void *data)

:return: The protocol used by the service


General Service Functions
-------------------------
Expand Down Expand Up @@ -305,6 +309,12 @@ General Service Functions
for the service, terminated with a *NULL* pointer. Does not
need to be freed

---------------------

.. function:: const char *obs_service_get_protocol(const obs_service_t *service)

:return: Protocol currently used for this service

.. ---------------------------------------------------------------------------

.. _libobs/obs-service.h: https://github.com/obsproject/obs-studio/blob/master/libobs/obs-service.h
2 changes: 2 additions & 0 deletions libobs/obs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,8 @@ struct obs_core_data {
obs_data_t *private_data;

volatile bool valid;

DARRAY(char *) protocols;
};

/* user hotkeys */
Expand Down
22 changes: 22 additions & 0 deletions libobs/obs-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,9 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size)
CHECK_REQUIRED_VAL_(info, start, obs_register_output);
CHECK_REQUIRED_VAL_(info, stop, obs_register_output);

if (info->flags & OBS_OUTPUT_SERVICE)
CHECK_REQUIRED_VAL_(info, protocols, obs_register_output);

if (info->flags & OBS_OUTPUT_ENCODED) {
CHECK_REQUIRED_VAL_(info, encoded_packet, obs_register_output);
} else {
Expand All @@ -856,6 +859,24 @@ void obs_register_output_s(const struct obs_output_info *info, size_t size)
#undef CHECK_REQUIRED_VAL_

REGISTER_OBS_DEF(size, obs_output_info, obs->output_types, info);

if (info->flags & OBS_OUTPUT_SERVICE) {
char **protocols = strlist_split(info->protocols, ';', false);
for (char **protocol = protocols; *protocol; ++protocol) {
bool skip = false;
for (size_t i = 0; i < obs->data.protocols.num; i++) {
if (strcmp(*protocol,
obs->data.protocols.array[i]) == 0)
skip = true;
}

if (skip)
continue;
char *new_prtcl = bstrdup(*protocol);
da_push_back(obs->data.protocols, &new_prtcl);
}
strlist_free(protocols);
}
return;

error:
Expand Down Expand Up @@ -907,6 +928,7 @@ void obs_register_service_s(const struct obs_service_info *info, size_t size)
CHECK_REQUIRED_VAL_(info, get_name, obs_register_service);
CHECK_REQUIRED_VAL_(info, create, obs_register_service);
CHECK_REQUIRED_VAL_(info, destroy, obs_register_service);
CHECK_REQUIRED_VAL_(info, get_protocol, obs_register_service);
#undef CHECK_REQUIRED_VAL_

REGISTER_OBS_DEF(size, obs_service_info, obs->service_types, info);
Expand Down
38 changes: 38 additions & 0 deletions libobs/obs-output.c
Original file line number Diff line number Diff line change
Expand Up @@ -2713,3 +2713,41 @@ const char *obs_output_get_supported_audio_codecs(const obs_output_t *output)
? output->info.encoded_audio_codecs
: NULL;
}

const char *obs_output_get_protocols(const obs_output_t *output)
{
if (!obs_output_valid(output, "obs_output_get_protocols"))
return NULL;

return (output->info.flags & OBS_OUTPUT_SERVICE)
? output->info.protocols
: NULL;
}

void obs_enum_output_types_with_protocol(const char *protocol, void *data,
bool (*enum_cb)(void *data,
const char *id))
{
if (!obs_is_output_protocol_registered(protocol))
return;

size_t protocol_len = strlen(protocol);
for (size_t i = 0; i < obs->output_types.num; i++) {
if (!(obs->output_types.array[i].flags & OBS_OUTPUT_SERVICE))
continue;

const char *substr = obs->output_types.array[i].protocols;
while (substr && substr[0] != '\0') {
const char *next = strchr(substr, ';');
size_t len = next ? (size_t)(next - substr)
: strlen(substr);
if (protocol_len == len &&
strncmp(substr, protocol, len) == 0) {
if (!enum_cb(data,
obs->output_types.array[i].id))
return;
}
substr = next ? next + 1 : NULL;
}
}
}
3 changes: 3 additions & 0 deletions libobs/obs-output.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ struct obs_output_info {

/* raw audio callback for multi track outputs */
void (*raw_audio2)(void *data, size_t idx, struct audio_data *frames);

/* required if OBS_OUTPUT_SERVICE */
const char *protocols;
};

EXPORT void obs_register_output_s(const struct obs_output_info *info,
Expand Down
8 changes: 8 additions & 0 deletions libobs/obs-service.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,3 +477,11 @@ obs_service_get_supported_video_codecs(const obs_service_t *service)
service->context.data);
return NULL;
}

const char *obs_service_get_protocol(const obs_service_t *service)
{
if (!obs_service_valid(service, "obs_service_get_protocol"))
return NULL;

return service->info.get_protocol(service->context.data);
}
2 changes: 2 additions & 0 deletions libobs/obs-service.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ struct obs_service_info {
int *audio_bitrate);

const char **(*get_supported_video_codecs)(void *data);

const char *(*get_protocol)(void *data);
};

EXPORT void obs_register_service_s(const struct obs_service_info *info,
Expand Down
23 changes: 23 additions & 0 deletions libobs/obs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,10 @@ static void obs_free_data(void)
da_free(data->draw_callbacks);
da_free(data->tick_callbacks);
obs_data_release(data->private_data);

for (size_t i = 0; i < data->protocols.num; i++)
bfree(data->protocols.array[i]);
da_free(data->protocols);
}

static const char *obs_signals[] = {
Expand Down Expand Up @@ -3452,3 +3456,22 @@ bool obs_weak_object_references_object(obs_weak_object_t *weak,
{
return weak && object && weak->object == object;
}

bool obs_is_output_protocol_registered(const char *protocol)
{
for (size_t i = 0; i < obs->data.protocols.num; i++) {
if (strcmp(protocol, obs->data.protocols.array[i]) == 0)
return true;
}

return false;
}

bool obs_enum_output_protocols(size_t idx, char **protocol)
{
if (idx >= obs->data.protocols.num)
return false;

*protocol = obs->data.protocols.array[idx];
return true;
}
13 changes: 13 additions & 0 deletions libobs/obs.h
Original file line number Diff line number Diff line change
Expand Up @@ -2211,6 +2211,16 @@ obs_output_get_supported_video_codecs(const obs_output_t *output);
EXPORT const char *
obs_output_get_supported_audio_codecs(const obs_output_t *output);

EXPORT const char *obs_output_get_protocols(const obs_output_t *output);

EXPORT bool obs_is_output_protocol_registered(const char *protocol);

EXPORT bool obs_enum_output_protocols(size_t idx, char **protocol);

EXPORT void obs_enum_output_types_with_protocol(
const char *protocol, void *data,
bool (*enum_cb)(void *data, const char *id));

/* ------------------------------------------------------------------------- */
/* Functions used by outputs */

Expand Down Expand Up @@ -2535,6 +2545,9 @@ obs_service_get_supported_video_codecs(const obs_service_t *service);
* date. */
EXPORT const char *obs_service_get_output_type(const obs_service_t *service);

/** Returns the protocol for this service context */
EXPORT const char *obs_service_get_protocol(const obs_service_t *service);

/* ------------------------------------------------------------------------- */
/* Source frame allocation functions */
EXPORT void obs_source_frame_init(struct obs_source_frame *frame,
Expand Down
1 change: 1 addition & 0 deletions plugins/obs-ffmpeg/obs-ffmpeg-hls-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ struct obs_output_info ffmpeg_hls_muxer = {
.id = "ffmpeg_hls_muxer",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK |
OBS_OUTPUT_SERVICE,
.protocols = "HLS",
#ifdef ENABLE_HEVC
.encoded_video_codecs = "h264;hevc",
#else
Expand Down
1 change: 1 addition & 0 deletions plugins/obs-ffmpeg/obs-ffmpeg-mpegts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,7 @@ struct obs_output_info ffmpeg_mpegts_muxer = {
.id = "ffmpeg_mpegts_muxer",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK |
OBS_OUTPUT_SERVICE,
.protocols = "SRT;RIST",
#ifdef ENABLE_HEVC
.encoded_video_codecs = "h264;hevc;av1",
#else
Expand Down
1 change: 1 addition & 0 deletions plugins/obs-ffmpeg/obs-ffmpeg-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ struct obs_output_info ffmpeg_mpegts_muxer = {
.id = "ffmpeg_mpegts_muxer",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_MULTI_TRACK |
OBS_OUTPUT_SERVICE,
.protocols = "SRT;RIST",
.encoded_video_codecs = "h264;av1",
.encoded_audio_codecs = "aac",
.get_name = ffmpeg_mpegts_mux_getname,
Expand Down
1 change: 1 addition & 0 deletions plugins/obs-outputs/ftl-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,7 @@ static int _ftl_error_to_obs_error(int status)
struct obs_output_info ftl_output_info = {
.id = "ftl_output",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE,
.protocols = "FTL",
.encoded_video_codecs = "h264",
.encoded_audio_codecs = "opus",
.get_name = ftl_stream_getname,
Expand Down
5 changes: 5 additions & 0 deletions plugins/obs-outputs/rtmp-stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,11 @@ struct obs_output_info rtmp_output_info = {
.id = "rtmp_output",
.flags = OBS_OUTPUT_AV | OBS_OUTPUT_ENCODED | OBS_OUTPUT_SERVICE |
OBS_OUTPUT_MULTI_TRACK,
#ifdef NO_CRYPTO
.protocols = "RTMP",
#else
.protocols = "RTMP;RTMPS",
#endif
.encoded_video_codecs = "h264",
.encoded_audio_codecs = "aac",
.get_name = rtmp_stream_getname,
Expand Down
4 changes: 2 additions & 2 deletions plugins/rtmp-services/data/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"$schema": "schema/package-schema.json",
"url": "https://obsproject.com/obs2_update/rtmp-services/v4",
"version": 220,
"version": 221,
"files": [
{
"name": "services.json",
"version": 220
"version": 221
}
]
}
24 changes: 24 additions & 0 deletions plugins/rtmp-services/data/schema/service-schema-v4.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@
"description": "Name of the streaming service. Will be displayed in the Service dropdown.",
"minLength": 1
},
"protocol" : {
"type": "string",
"description": "Protocol used by the service. If missing the service is considered using RTMP or RTMPS.",
"enum": [
"RTMP",
"RTMPS",
"HLS",
"FTL",
"SRT",
"RIST"
]
},
"common": {
"type": "boolean",
"description": "Whether or not the service is shown in the list before it is expanded to all services by the user.",
Expand Down Expand Up @@ -200,6 +212,18 @@
"required": [
"name",
"servers"
],
"allOf": [
{
"$comment": "Require protocol field if not an RTMP(S) URL",
"if": { "not": { "properties": { "servers": { "items": { "properties": { "url": { "format": "uri", "pattern": "^rtmps?://" } } } } } } },
"then": { "required": ["protocol"] }
},
{
"$comment": "Require recommended output field if protocol field is not RTMP(S)",
"if": { "required": ["protocol"], "properties": { "protocol": { "pattern": "^(HLS|SRT|RIST|FTL)$" } } },
"then": { "properties": { "recommended": { "required": ["output"] } } }
}
]
},
"additionalItems": true
Expand Down
Loading