obs-studio/libobs/obs-module.c

272 lines
8.0 KiB
C
Raw Normal View History

2013-09-30 19:37:13 -07:00
/******************************************************************************
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
2013-09-30 19:37:13 -07:00
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
2013-09-30 19:37:13 -07:00
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "util/platform.h"
#include "util/dstr.h"
#include "obs-defs.h"
#include "obs-internal.h"
2013-09-30 19:37:13 -07:00
#include "obs-module.h"
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
extern char *find_plugin(const char *plugin);
extern const char *get_module_extension(void);
2013-09-30 19:37:13 -07:00
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
static inline int req_func_not_found(const char *name, const char *path)
{
blog(LOG_ERROR, "Required module function '%s' in module '%s' not "
"found, loading of module failed",
name, path);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
return MODULE_FUNCTION_NOT_FOUND;
}
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
#define LOAD_REQ_SIZE_FUNC(func, module, path) \
func = os_dlsym(module, #func); \
if (!func) \
return req_func_not_found(#func, path)
static int call_module_load(void *module, const char *path)
{
bool (*obs_module_load)(uint32_t obs_ver) = NULL;
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
obs_module_load = os_dlsym(module, "obs_module_load");
if (!obs_module_load)
return req_func_not_found("obs_module_load", path);
if (!obs_module_load(LIBOBS_API_VER)) {
blog(LOG_ERROR, "Module '%s' failed to load: "
"obs_module_load failed", path);
return MODULE_ERROR;
}
return MODULE_SUCCESS;
}
int obs_load_module(const char *path)
2013-09-30 19:37:13 -07:00
{
struct obs_module mod;
char *plugin_path = find_plugin(path);
int errorcode;
2013-09-30 19:37:13 -07:00
mod.module = os_dlopen(plugin_path);
bfree(plugin_path);
if (!mod.module) {
obs-studio UI: Implement stream settings UI - Updated the services API so that it links up with an output and the output gets data from that service rather than via settings. This allows the service context to have control over how an output is used, and makes it so that the URL/key/etc isn't necessarily some static setting. Also, if the service is attached to an output, it will stick around until the output is destroyed. - The settings interface has been updated so that it can allow the usage of service plugins. What this means is that now you can create a service plugin that can control aspects of the stream, and it allows each service to create their own user interface if they create a service plugin module. - Testing out saving of current service information. Saves/loads from JSON in to obs_data_t, seems to be working quite nicely, and the service object information is saved/preserved on exit, and loaded again on startup. - I agonized over the settings user interface for days, and eventually I just decided that the only way that users weren't going to be fumbling over options was to split up the settings in to simple/basic output, pre-configured, and then advanced for advanced use (such as multiple outputs or services, which I'll implement later). This was particularly painful to really design right, I wanted more features and wanted to include everything in one interface but ultimately just realized from experience that users are just not technically knowledgable about it and will end up fumbling with the settings rather than getting things done. Basically, what this means is that casual users only have to enter in about 3 things to configure their stream: Stream key, audio bitrate, and video bitrate. I am really happy with this interface for those types of users, but it definitely won't be sufficient for advanced usage or for custom outputs, so that stuff will have to be separated. - Improved the JSON usage for the 'common streaming services' context, I realized that JSON arrays are there to ensure sorting, while forgetting that general items are optimized for hashing. So basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
blog(LOG_WARNING, "Module '%s' not found", path);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
return MODULE_FILE_NOT_FOUND;
}
2013-09-30 19:37:13 -07:00
errorcode = call_module_load(mod.module, path);
if (errorcode != MODULE_SUCCESS) {
os_dlclose(mod.module);
return errorcode;
2013-09-30 19:37:13 -07:00
}
mod.name = bstrdup(path);
mod.set_locale = os_dlsym(mod.module, "obs_module_set_locale");
if (mod.set_locale)
mod.set_locale(obs->locale);
2013-09-30 19:37:13 -07:00
da_push_back(obs->modules, &mod);
return MODULE_SUCCESS;
}
void free_module(struct obs_module *mod)
{
if (!mod)
return;
if (mod->module) {
void (*module_unload)(void);
module_unload = os_dlsym(mod->module, "obs_module_unload");
2013-09-30 19:37:13 -07:00
if (module_unload)
module_unload();
os_dlclose(mod->module);
}
bfree(mod->name);
}
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
lookup_t obs_module_load_locale(const char *module, const char *default_locale,
const char *locale)
{
struct dstr str = {0};
lookup_t lookup = NULL;
if (!module || !default_locale || !locale) {
blog(LOG_WARNING, "obs_module_load_locale: Invalid parameters");
return NULL;
}
dstr_copy(&str, module);
dstr_cat(&str, "/locale/");
dstr_cat(&str, default_locale);
dstr_cat(&str, ".ini");
char *file = obs_find_plugin_file(str.array);
if (file)
lookup = text_lookup_create(file);
bfree(file);
if (!lookup) {
blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'",
default_locale, module);
goto cleanup;
}
if (astrcmpi(locale, default_locale) == 0)
goto cleanup;
dstr_copy(&str, module);
dstr_cat(&str, "/locale/");
dstr_cat(&str, locale);
dstr_cat(&str, ".ini");
file = obs_find_plugin_file(str.array);
if (!text_lookup_add(lookup, file))
blog(LOG_WARNING, "Failed to load '%s' text for module: '%s'",
locale, module);
bfree(file);
cleanup:
dstr_free(&str);
return lookup;
}
Add source properties window (very preliminary) - Add a properties window for sources so that you can now actually edit the settings for sources. Also, display the source by itself in the window (Note: not working on mac, and possibly not working on linux). When changing the settings for a source, it will call obs_source_update on that source when you have modified any values automatically. - Add a properties 'widget', eventually I want to turn this in to a regular nice properties view like you'd see in the designer, but right now it just uses a form layout in a QScrollArea with regular controls to display the properties. It's clunky but works for the time being. - Make it so that swap chains and the main graphics subsystem will automatically use at least one backbuffer if none was specified - Fix bug where displays weren't added to the main display array - Make it so that you can get the properties of a source via the actual pointer of a source/encoder/output in addition to being able to look up properties via identifier. - When registering source types, check for required functions (wasn't doing it before). getheight/getwidth should not be optional if it's a video source as well. - Add an RAII OBSObj wrapper to obs.hpp for non-reference-counted libobs pointers - Add an RAII OBSSignal wrapper to obs.hpp for libobs signals to automatically disconnect them on destruction - Move the "scale and center" calculation in window-basic-main.cpp to its own function and in its own source file - Add an 'update' callback to WASAPI audio sources
2014-03-23 01:07:54 -07:00
#define REGISTER_OBS_DEF(size_var, structure, dest, info) \
do { \
struct structure data = {0}; \
if (!size_var) { \
blog(LOG_ERROR, "Tried to register " #structure \
" outside of obs_module_load"); \
return; \
} \
\
memcpy(&data, info, size_var); \
da_push_back(dest, &data); \
} while (false)
#define CHECK_REQUIRED_VAL(info, val, func) \
do { \
if (!info->val) {\
blog(LOG_ERROR, "Required value '" #val " for" \
"'%s' not found. " #func \
" failed.", info->id); \
return; \
} \
} while (false)
void obs_register_source_s(const struct obs_source_info *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
struct obs_source_info data = {0};
struct darray *array;
CHECK_REQUIRED_VAL(info, getname, obs_register_source);
CHECK_REQUIRED_VAL(info, create, obs_register_source);
CHECK_REQUIRED_VAL(info, destroy, obs_register_source);
Add source properties window (very preliminary) - Add a properties window for sources so that you can now actually edit the settings for sources. Also, display the source by itself in the window (Note: not working on mac, and possibly not working on linux). When changing the settings for a source, it will call obs_source_update on that source when you have modified any values automatically. - Add a properties 'widget', eventually I want to turn this in to a regular nice properties view like you'd see in the designer, but right now it just uses a form layout in a QScrollArea with regular controls to display the properties. It's clunky but works for the time being. - Make it so that swap chains and the main graphics subsystem will automatically use at least one backbuffer if none was specified - Fix bug where displays weren't added to the main display array - Make it so that you can get the properties of a source via the actual pointer of a source/encoder/output in addition to being able to look up properties via identifier. - When registering source types, check for required functions (wasn't doing it before). getheight/getwidth should not be optional if it's a video source as well. - Add an RAII OBSObj wrapper to obs.hpp for non-reference-counted libobs pointers - Add an RAII OBSSignal wrapper to obs.hpp for libobs signals to automatically disconnect them on destruction - Move the "scale and center" calculation in window-basic-main.cpp to its own function and in its own source file - Add an 'update' callback to WASAPI audio sources
2014-03-23 01:07:54 -07:00
if (info->type == OBS_SOURCE_TYPE_INPUT &&
(info->output_flags & OBS_SOURCE_VIDEO) != 0 &&
(info->output_flags & OBS_SOURCE_ASYNC) == 0) {
Add source properties window (very preliminary) - Add a properties window for sources so that you can now actually edit the settings for sources. Also, display the source by itself in the window (Note: not working on mac, and possibly not working on linux). When changing the settings for a source, it will call obs_source_update on that source when you have modified any values automatically. - Add a properties 'widget', eventually I want to turn this in to a regular nice properties view like you'd see in the designer, but right now it just uses a form layout in a QScrollArea with regular controls to display the properties. It's clunky but works for the time being. - Make it so that swap chains and the main graphics subsystem will automatically use at least one backbuffer if none was specified - Fix bug where displays weren't added to the main display array - Make it so that you can get the properties of a source via the actual pointer of a source/encoder/output in addition to being able to look up properties via identifier. - When registering source types, check for required functions (wasn't doing it before). getheight/getwidth should not be optional if it's a video source as well. - Add an RAII OBSObj wrapper to obs.hpp for non-reference-counted libobs pointers - Add an RAII OBSSignal wrapper to obs.hpp for libobs signals to automatically disconnect them on destruction - Move the "scale and center" calculation in window-basic-main.cpp to its own function and in its own source file - Add an 'update' callback to WASAPI audio sources
2014-03-23 01:07:54 -07:00
CHECK_REQUIRED_VAL(info, getwidth, obs_register_source);
CHECK_REQUIRED_VAL(info, getheight, obs_register_source);
2014-02-23 21:39:33 -08:00
}
memcpy(&data, info, size);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
if (info->type == OBS_SOURCE_TYPE_INPUT) {
array = &obs->input_types.da;
} else if (info->type == OBS_SOURCE_TYPE_FILTER) {
array = &obs->filter_types.da;
} else if (info->type == OBS_SOURCE_TYPE_TRANSITION) {
array = &obs->transition_types.da;
} else {
blog(LOG_ERROR, "Tried to register unknown source type: %u",
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
info->type);
return;
}
darray_push_back(sizeof(struct obs_source_info), array, &data);
}
void obs_register_output_s(const struct obs_output_info *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
CHECK_REQUIRED_VAL(info, getname, obs_register_output);
CHECK_REQUIRED_VAL(info, create, obs_register_output);
CHECK_REQUIRED_VAL(info, destroy, obs_register_output);
CHECK_REQUIRED_VAL(info, start, obs_register_output);
CHECK_REQUIRED_VAL(info, stop, obs_register_output);
Implement encoder usage with outputs - Make it so that encoders can be assigned to outputs. If an encoder is destroyed, it will automatically remove itself from that output. I specifically didn't want to do reference counting because it leaves too much potential for unchecked references and it just felt like it would be more trouble than it's worth. - Add a 'flags' value to the output definition structure. This lets the output specify if it uses video/audio, and whether the output is meant to be used with OBS encoders or not. - Remove boilerplate code for outputs. This makes it easier to program outputs. The boilerplate code involved before was mostly just involving connecting to the audio/video data streams directly in each output plugin. Instead of doing that, simply add plugin callback functions for receiving video/audio (either encoded or non-encoded, whichever it's set to use), and then call obs_output_begin_data_capture and obs_output_end_data_capture to automatically handle setting up connections to raw or encoded video/audio streams for the plugin. - Remove 'active' function from output callbacks, as it's no longer really needed now that the libobs output context automatically knows when the output is active or not. - Make it so that an encoder cannot be destroyed until all data connections to the encoder have been removed. - Change the 'start' and 'stop' functions in the encoder interface to just an 'initialize' callback, which initializes the encoder. - Make it so that the encoder must be initialized first before the data stream can be started. The reason why initialization was separated from starting the encoder stream was because we need to be able to check that the settings used with the encoder *can* be used first. This problem was especially annoying if you had both video/audio encoding. Before, you'd have to check the return value from obs_encoder_start, and if that second encoder fails, then you basically had to stop the first encoder again, making for unnecessary boilerplate code whenever starting up two encoders.
2014-03-27 21:50:15 -07:00
if (info->flags & OBS_OUTPUT_ENCODED) {
CHECK_REQUIRED_VAL(info, encoded_packet, obs_register_output);
Implement encoder usage with outputs - Make it so that encoders can be assigned to outputs. If an encoder is destroyed, it will automatically remove itself from that output. I specifically didn't want to do reference counting because it leaves too much potential for unchecked references and it just felt like it would be more trouble than it's worth. - Add a 'flags' value to the output definition structure. This lets the output specify if it uses video/audio, and whether the output is meant to be used with OBS encoders or not. - Remove boilerplate code for outputs. This makes it easier to program outputs. The boilerplate code involved before was mostly just involving connecting to the audio/video data streams directly in each output plugin. Instead of doing that, simply add plugin callback functions for receiving video/audio (either encoded or non-encoded, whichever it's set to use), and then call obs_output_begin_data_capture and obs_output_end_data_capture to automatically handle setting up connections to raw or encoded video/audio streams for the plugin. - Remove 'active' function from output callbacks, as it's no longer really needed now that the libobs output context automatically knows when the output is active or not. - Make it so that an encoder cannot be destroyed until all data connections to the encoder have been removed. - Change the 'start' and 'stop' functions in the encoder interface to just an 'initialize' callback, which initializes the encoder. - Make it so that the encoder must be initialized first before the data stream can be started. The reason why initialization was separated from starting the encoder stream was because we need to be able to check that the settings used with the encoder *can* be used first. This problem was especially annoying if you had both video/audio encoding. Before, you'd have to check the return value from obs_encoder_start, and if that second encoder fails, then you basically had to stop the first encoder again, making for unnecessary boilerplate code whenever starting up two encoders.
2014-03-27 21:50:15 -07:00
} else {
if (info->flags & OBS_OUTPUT_VIDEO)
CHECK_REQUIRED_VAL(info, raw_video,
obs_register_output);
if (info->flags & OBS_OUTPUT_AUDIO)
CHECK_REQUIRED_VAL(info, raw_audio,
obs_register_output);
}
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
REGISTER_OBS_DEF(size, obs_output_info, obs->output_types, info);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
}
void obs_register_encoder_s(const struct obs_encoder_info *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
CHECK_REQUIRED_VAL(info, getname, obs_register_encoder);
CHECK_REQUIRED_VAL(info, create, obs_register_encoder);
CHECK_REQUIRED_VAL(info, destroy, obs_register_encoder);
CHECK_REQUIRED_VAL(info, encode, obs_register_encoder);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
Implement RTMP module (still needs drop code) - Implement the RTMP output module. This time around, we just use a simple FLV muxer, then just write to the stream with RTMP_Write. Easy and effective. - Fix the FLV muxer, the muxer now outputs proper FLV packets. - Output API: * When using encoders, automatically interleave encoded packets before sending it to the output. * Pair encoders and have them automatically wait for the other to start to ensure sync. * Change 'obs_output_signal_start_fail' to 'obs_output_signal_stop' because it was a bit confusing, and doing this makes a lot more sense for outputs that need to stop suddenly (disconnections/etc). - Encoder API: * Remove some unnecessary encoder functions from the actual API and make them internal. Most of the encoder functions are handled automatically by outputs anyway, so there's no real need to expose them and end up inadvertently confusing plugin writers. * Have audio encoders wait for the video encoder to get a frame, then start at the exact data point that the first video frame starts to ensure the most accrate sync of video/audio possible. * Add a required 'frame_size' callback for audio encoders that returns the expected number of frames desired to encode with. This way, the libobs encoder API can handle the circular buffering internally automatically for the encoder modules, so encoder writers don't have to do it themselves. - Fix a few bugs in the serializer interface. It was passing the wrong variable for the data in a few cases. - If a source has video, make obs_source_update defer the actual update callback until the tick function is called to prevent threading issues.
2014-04-07 22:00:10 -07:00
if (info->type == OBS_ENCODER_AUDIO)
CHECK_REQUIRED_VAL(info, frame_size, obs_register_encoder);
REGISTER_OBS_DEF(size, obs_encoder_info, obs->encoder_types, info);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
}
void obs_register_service_s(const struct obs_service_info *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
CHECK_REQUIRED_VAL(info, getname, obs_register_service);
CHECK_REQUIRED_VAL(info, create, obs_register_service);
CHECK_REQUIRED_VAL(info, destroy, obs_register_service);
REGISTER_OBS_DEF(size, obs_service_info, obs->service_types, info);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
}
void obs_regsiter_modal_ui_s(const struct obs_modal_ui *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
CHECK_REQUIRED_VAL(info, task, obs_regsiter_modal_ui);
CHECK_REQUIRED_VAL(info, target, obs_regsiter_modal_ui);
CHECK_REQUIRED_VAL(info, exec, obs_regsiter_modal_ui);
REGISTER_OBS_DEF(size, obs_modal_ui, obs->modal_ui_callbacks, info);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
}
void obs_regsiter_modeless_ui_s(const struct obs_modeless_ui *info, size_t size)
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
{
CHECK_REQUIRED_VAL(info, task, obs_regsiter_modeless_ui);
CHECK_REQUIRED_VAL(info, target, obs_regsiter_modeless_ui);
CHECK_REQUIRED_VAL(info, create, obs_regsiter_modeless_ui);
REGISTER_OBS_DEF(size, obs_modeless_ui, obs->modeless_ui_callbacks,
info);
Revamp API and start using doxygen The API used to be designed in such a way to where it would expect exports for each individual source/output/encoder/etc. You would export functions for each and it would automatically load those functions based on a specific naming scheme from the module. The idea behind this was that I wanted to limit the usage of structures in the API so only functions could be used. It was an interesting idea in theory, but this idea turned out to be flawed in a number of ways: 1.) Requiring exports to create sources/outputs/encoders/etc meant that you could not create them by any other means, which meant that things like faruton's .net plugin would become difficult. 2.) Export function declarations could not be checked, therefore if you created a function with the wrong parameters and parameter types, the compiler wouldn't know how to check for that. 3.) Required overly complex load functions in libobs just to handle it. It makes much more sense to just have a load function that you call manually. Complexity is the bane of all good programs. 4.) It required that you have functions of specific names, which looked and felt somewhat unsightly. So, to fix these issues, I replaced it with a more commonly used API scheme, seen commonly in places like kernels and typical C libraries with abstraction. You simply create a structure that contains the callback definitions, and you pass it to a function to register that definition (such as obs_register_source), which you call in the obs_module_load of the module. It will also automatically check the structure size and ensure that it only loads the required values if the structure happened to add new values in an API change. The "main" source file for each module must include obs-module.h, and must use OBS_DECLARE_MODULE() within that source file. Also, started writing some doxygen documentation in to the main library headers. Will add more detailed documentation as I go.
2014-02-12 07:04:50 -08:00
}