diff --git a/docs/sphinx/reference-outputs.rst b/docs/sphinx/reference-outputs.rst index 0cbe9f988..eb8b94c0b 100644 --- a/docs/sphinx/reference-outputs.rst +++ b/docs/sphinx/reference-outputs.rst @@ -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: @@ -685,6 +693,22 @@ 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 + +--------------------- + Functions used by outputs ------------------------- diff --git a/libobs/obs-internal.h b/libobs/obs-internal.h index f6a383550..a67fb518c 100644 --- a/libobs/obs-internal.h +++ b/libobs/obs-internal.h @@ -411,6 +411,8 @@ struct obs_core_data { obs_data_t *private_data; volatile bool valid; + + DARRAY(char *) protocols; }; /* user hotkeys */ diff --git a/libobs/obs-module.c b/libobs/obs-module.c index ff118814f..73c8228a5 100644 --- a/libobs/obs-module.c +++ b/libobs/obs-module.c @@ -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 { @@ -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: diff --git a/libobs/obs-output.c b/libobs/obs-output.c index 335b76555..148b31b4a 100644 --- a/libobs/obs-output.c +++ b/libobs/obs-output.c @@ -2713,3 +2713,13 @@ 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; +} diff --git a/libobs/obs-output.h b/libobs/obs-output.h index e57659fd9..0469d39a1 100644 --- a/libobs/obs-output.h +++ b/libobs/obs-output.h @@ -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, diff --git a/libobs/obs.c b/libobs/obs.c index cb17d5d88..3cd697a07 100644 --- a/libobs/obs.c +++ b/libobs/obs.c @@ -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[] = { @@ -3452,3 +3456,13 @@ 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; +} diff --git a/libobs/obs.h b/libobs/obs.h index f5b84b708..f6e08e33a 100644 --- a/libobs/obs.h +++ b/libobs/obs.h @@ -2211,6 +2211,10 @@ 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); + /* ------------------------------------------------------------------------- */ /* Functions used by outputs */