obs-studio/libobs/obs-internal.h

511 lines
17 KiB
C
Raw Normal View History

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
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/>.
******************************************************************************/
#pragma once
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
#include "util/c99defs.h"
2013-09-30 19:37:13 -07:00
#include "util/darray.h"
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
#include "util/circlebuf.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
#include "util/dstr.h"
2013-09-30 19:37:13 -07:00
#include "util/threading.h"
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
#include "util/platform.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
#include "callback/signal.h"
#include "callback/proc.h"
2013-09-30 19:37:13 -07:00
#include "graphics/graphics.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
#include "media-io/audio-resampler.h"
2013-09-30 19:37:13 -07:00
#include "media-io/video-io.h"
#include "media-io/audio-io.h"
#include "obs.h"
2013-09-30 19:37:13 -07:00
#define NUM_TEXTURES 2
#define MICROSECOND_DEN 1000000
2013-09-30 19:37:13 -07:00
static inline int64_t packet_dts_usec(struct encoder_packet *packet)
{
return packet->dts * MICROSECOND_DEN / packet->timebase_den;
}
struct draw_callback {
void (*draw)(void *param, uint32_t cx, uint32_t cy);
void *param;
};
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
/* ------------------------------------------------------------------------- */
/* modules */
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_module {
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
const char *file;
char *bin_path;
char *data_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
void *module;
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
bool loaded;
bool (*load)(void);
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
void (*unload)(void);
void (*set_locale)(const char *locale);
void (*free_locale)(void);
uint32_t (*ver)(void);
void (*set_pointer)(obs_module_t *module);
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
const char *(*name)(void);
const char *(*description)(void);
const char *(*author)(void);
struct obs_module *next;
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
extern void free_module(struct obs_module *mod);
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
struct obs_module_path {
char *bin;
char *data;
};
static inline void free_module_path(struct obs_module_path *omp)
{
if (omp) {
bfree(omp->bin);
bfree(omp->data);
}
}
static inline bool check_path(const char *data, const char *path,
struct dstr *output)
{
dstr_copy(output, path);
dstr_cat(output, data);
return os_file_exists(output->array);
}
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
/* ------------------------------------------------------------------------- */
/* views */
struct obs_view {
pthread_mutex_t channels_mutex;
obs_source_t *channels[MAX_CHANNELS];
};
extern bool obs_view_init(struct obs_view *view);
extern void obs_view_free(struct obs_view *view);
/* ------------------------------------------------------------------------- */
/* displays */
struct obs_display {
bool size_changed;
uint32_t cx, cy;
gs_swapchain_t *swap;
pthread_mutex_t draw_callbacks_mutex;
DARRAY(struct draw_callback) draw_callbacks;
struct obs_display *next;
struct obs_display **prev_next;
};
extern bool obs_display_init(struct obs_display *display,
const struct gs_init_data *graphics_data);
extern void obs_display_free(struct obs_display *display);
/* ------------------------------------------------------------------------- */
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
/* core */
struct obs_core_video {
graphics_t *graphics;
gs_stagesurf_t *copy_surfaces[NUM_TEXTURES];
gs_texture_t *render_textures[NUM_TEXTURES];
gs_texture_t *output_textures[NUM_TEXTURES];
gs_texture_t *convert_textures[NUM_TEXTURES];
bool textures_rendered[NUM_TEXTURES];
bool textures_output[NUM_TEXTURES];
bool textures_copied[NUM_TEXTURES];
bool textures_converted[NUM_TEXTURES];
struct obs_source_frame convert_frames[NUM_TEXTURES];
gs_effect_t *default_effect;
gs_effect_t *default_rect_effect;
gs_effect_t *solid_effect;
gs_effect_t *conversion_effect;
gs_stagesurf_t *mapped_surface;
int cur_texture;
video_t *video;
pthread_t video_thread;
bool thread_initialized;
bool gpu_conversion;
const char *conversion_tech;
uint32_t conversion_height;
uint32_t plane_offsets[3];
uint32_t plane_sizes[3];
uint32_t plane_linewidth[3];
uint32_t output_width;
uint32_t output_height;
uint32_t base_width;
uint32_t base_height;
struct obs_display main_display;
};
struct obs_core_audio {
/* TODO: sound output subsystem */
audio_t *audio;
float user_volume;
float present_volume;
};
/* user sources, output channels, and displays */
struct obs_core_data {
pthread_mutex_t user_sources_mutex;
DARRAY(struct obs_source*) user_sources;
struct obs_source *first_source;
struct obs_display *first_display;
struct obs_output *first_output;
struct obs_encoder *first_encoder;
struct obs_service *first_service;
pthread_mutex_t sources_mutex;
pthread_mutex_t displays_mutex;
pthread_mutex_t outputs_mutex;
pthread_mutex_t encoders_mutex;
pthread_mutex_t services_mutex;
struct obs_view main_view;
long long unnamed_index;
volatile bool valid;
};
struct obs_core {
(API Change) Refactor module handling Changed API: - char *obs_find_plugin_file(const char *sub_path); Changed to: char *obs_module_file(const char *file); Cahnge it so you no longer need to specify a sub-path such as: obs_find_plugin_file("module_name/file.ext") Instead, now automatically handle the module data path so all you need to do is: obs_module_file("file.ext") - int obs_load_module(const char *name); Changed to: int obs_open_module(obs_module_t *module, const char *path, const char *data_path); bool obs_init_module(obs_module_t module); Change the module loading API so that if the front-end chooses, it can load modules directly from a specified path, and associate a data directory with it on the spot. The module will not be initialized immediately; obs_init_module must be called on the module pointer in order to fully initialize the module. This is done so a module can be disabled by the front-end if the it so chooses. New API: - void obs_add_module_path(const char *bin, const char *data); These functions allow you to specify new module search paths to add, and allow you to search through them, or optionally just load all modules from them. If the string %module% is included, it will replace it with the module's name when that string is used as a lookup. Data paths are now directly added to the module's internal storage structure, and when obs_find_module_file is used, it will look up the pointer to the obs_module structure and get its data directory that way. Example: obs_add_module_path("/opt/obs/my-modules/%module%/bin", "/opt/obs/my-modules/%module%/data"); This would cause it to additionally look for the binary of a hypthetical module named "foo" at /opt/obs/my-modules/foo/bin/foo.so (or libfoo.so), and then look for the data in /opt/obs/my-modules/foo/data. This gives the front-end more flexibility for handling third-party plugin modules, or handling all plugin modules in a custom way. - void obs_find_modules(obs_find_module_callback_t callback, void *param); This searches the existing paths for modules and calls the callback function when any are found. Useful for plugin management and custom handling of the paths by the front-end if desired. - void obs_load_all_modules(void); Search through the paths and both loads and initializes all modules automatically without custom handling. - void obs_enum_modules(obs_enum_module_callback_t callback, void *param); Enumerates currently opened modules.
2014-07-27 12:00:11 -07:00
struct obs_module *first_module;
DARRAY(struct obs_module_path) module_paths;
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
DARRAY(struct obs_source_info) input_types;
DARRAY(struct obs_source_info) filter_types;
DARRAY(struct obs_source_info) transition_types;
DARRAY(struct obs_output_info) output_types;
DARRAY(struct obs_encoder_info) encoder_types;
DARRAY(struct obs_service_info) service_types;
DARRAY(struct obs_modal_ui) modal_ui_callbacks;
DARRAY(struct obs_modeless_ui) modeless_ui_callbacks;
signal_handler_t *signals;
proc_handler_t *procs;
char *locale;
/* segmented into multiple sub-structures to keep things a bit more
* clean and organized */
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_core_video video;
struct obs_core_audio audio;
struct obs_core_data data;
2013-09-30 19:37:13 -07:00
};
extern struct obs_core *obs;
2013-09-30 19:37:13 -07:00
extern void *obs_video_thread(void *param);
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 shared context data */
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_context_data {
char *name;
void *data;
obs_data_t *settings;
signal_handler_t *signals;
proc_handler_t *procs;
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
DARRAY(char*) rename_cache;
pthread_mutex_t rename_cache_mutex;
pthread_mutex_t *mutex;
struct obs_context_data *next;
struct obs_context_data **prev_next;
};
extern bool obs_context_data_init(
struct obs_context_data *context,
obs_data_t *settings,
const char *name);
extern void obs_context_data_free(struct obs_context_data *context);
extern void obs_context_data_insert(struct obs_context_data *context,
pthread_mutex_t *mutex, void *first);
extern void obs_context_data_remove(struct obs_context_data *context);
extern void obs_context_data_setname(struct obs_context_data *context,
const char *name);
/* ------------------------------------------------------------------------- */
/* sources */
struct obs_source {
struct obs_context_data context;
struct obs_source_info info;
volatile long refs;
/* indicates ownership of the info.id buffer */
bool owns_info_id;
/* signals to call the source update in the video thread */
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
bool defer_update;
/* ensures show/hide are only called once */
volatile long show_refs;
/* ensures activate/deactivate are only called once */
volatile long activate_refs;
/* prevents infinite recursion when enumerating sources */
volatile long enum_refs;
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
/* used to indicate that the source has been removed and all
* references to it should be released (not exactly how I would prefer
* to handle things but it's the best option) */
bool removed;
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
/* timing (if video is present, is based upon video) */
volatile bool timing_set;
volatile uint64_t timing_adjust;
uint64_t next_audio_ts_min;
uint64_t last_frame_ts;
uint64_t last_sys_timestamp;
bool async_rendered;
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
/* audio */
bool audio_failed;
struct resample_info sample_info;
audio_resampler_t *resampler;
audio_line_t *audio_line;
pthread_mutex_t audio_mutex;
struct obs_audio_data audio_data;
size_t audio_storage_size;
float user_volume;
float present_volume;
2014-02-20 15:16:25 -08:00
int64_t sync_offset;
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
/* audio levels*/
float vol_mag;
float vol_max;
float vol_peak;
size_t vol_update_count;
Implement volume handling - Remove obs_source::type because it became redundant now that the type is always stored in the obs_source::info variable. - Apply presentation volumes of 1.0 and 0.0 to sources when they activate/deactivate, respectively. It also applies that presentation volume to all sub-sources, with exception of transition sources. Transition sources must apply presentation volume manually to their sub-sources with the new transition functions below. - Add a "transition_volume" variable to obs_source structure, and add three functions for handling volume for transitions: * obs_transition_begin_frame * obs_source_set_transition_vol * obs_transition_end_frame Because the to/from targets of a transition source might both contain some of the same sources, handling the transitioning of volumes for that specific situation becomes an issue. So for transitions, instead of modifying the presentation volumes directly for both sets of sources, we do this: - First, call obs_transition_begin_frame at the beginning of each transition frame, which will reset transition volumes for all sub-sources to 0. Presentation volumes remain unchanged. - Call obs_source_set_transition_vol on each sub-source, which will then add the volume to the transition volume for each source in that source's tree. Presentation volumes still remain unchanged. - Then you call obs_trandition_end_frame when complete, which will then finally set the presentation volumes to the transition volumes. For example, let's say that there's one source that's within both the "transitioning from" sources and "transition to" sources. It would add both the fade in and fade out volumes to that source, and then when the frame is complete, it would set the presentation volume to the sum of those two values, rather than set the presentation volume for that same source twice which would cause weird volume jittering and also set the wrong values.
2014-02-21 18:41:38 -08:00
/* transition volume is meant to store the sum of transitioning volumes
* of a source, i.e. if a source is within both the "to" and "from"
* targets of a transition, it would add both volumes to this variable,
* and then when the transition frame is complete, is applies the value
* to the presentation volume. */
float transition_volume;
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
/* async video data */
gs_texture_t *async_texture;
gs_texrender_t *async_convert_texrender;
bool async_gpu_conversion;
enum video_format async_format;
enum gs_color_format async_texture_format;
float async_color_matrix[16];
bool async_full_range;
float async_color_range_min[3];
float async_color_range_max[3];
int async_plane_offset[2];
bool async_flip;
DARRAY(struct obs_source_frame*)video_frames;
pthread_mutex_t video_mutex;
uint32_t async_width;
uint32_t async_height;
uint32_t async_convert_width;
uint32_t async_convert_height;
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
/* filters */
struct obs_source *filter_parent;
struct obs_source *filter_target;
DARRAY(struct obs_source*) filters;
pthread_mutex_t filter_mutex;
gs_texrender_t *filter_texrender;
bool rendering_filter;
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 const struct obs_source_info *find_source(struct darray *list,
const char *id);
extern bool obs_source_init_context(struct obs_source *source,
obs_data_t *settings, const char *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
extern bool obs_source_init(struct obs_source *source,
const struct obs_source_info *info);
extern void obs_source_destroy(struct obs_source *source);
enum view_type {
MAIN_VIEW,
AUX_VIEW
};
extern void obs_source_activate(obs_source_t *source, enum view_type type);
extern void obs_source_deactivate(obs_source_t *source, enum view_type type);
extern void obs_source_video_tick(obs_source_t *source, float seconds);
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
/* ------------------------------------------------------------------------- */
/* outputs */
struct obs_output {
struct obs_context_data context;
struct obs_output_info info;
bool received_video;
bool received_audio;
int64_t first_video_ts;
int64_t video_offset;
int64_t audio_offset;
int64_t highest_audio_ts;
int64_t highest_video_ts;
pthread_mutex_t interleaved_mutex;
DARRAY(struct encoder_packet) interleaved_packets;
int reconnect_retry_sec;
int reconnect_retry_max;
int reconnect_retries;
bool reconnecting;
pthread_t reconnect_thread;
os_event_t *reconnect_stop_event;
volatile bool reconnect_thread_active;
uint32_t starting_frame_count;
uint32_t starting_skipped_frame_count;
int total_frames;
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
bool active;
video_t *video;
audio_t *audio;
obs_encoder_t *video_encoder;
obs_encoder_t *audio_encoder;
obs_service_t *service;
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
uint32_t scaled_width;
uint32_t scaled_height;
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
bool video_conversion_set;
bool audio_conversion_set;
struct video_scale_info video_conversion;
struct audio_convert_info audio_conversion;
bool valid;
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 const struct obs_output_info *find_output(const char *id);
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
extern void obs_output_remove_encoder(struct obs_output *output,
struct obs_encoder *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
/* ------------------------------------------------------------------------- */
/* encoders */
struct encoder_callback {
Implement encoder interface (still preliminary) - Implement OBS encoder interface. It was previously incomplete, but now is reaching some level of completion, though probably should still be considered preliminary. I had originally implemented it so that encoders only have a 'reset' function to reset their parameters, but I felt that having both a 'start' and 'stop' function would be useful. Encoders are now assigned to a specific video/audio media output each rather than implicitely assigned to the main obs video/audio contexts. This allows separate encoder contexts that aren't necessarily assigned to the main video/audio context (which is useful for things such as recording specific sources). Will probably have to do this for regular obs outputs as well. When creating an encoder, you must now explicitely state whether that encoder is an audio or video encoder. Audio and video can optionally be automatically converted depending on what the encoder specifies. When something 'attaches' to an encoder, the first attachment starts the encoder, and the encoder automatically attaches to the media output context associated with it. Subsequent attachments won't have the same effect, they will just start receiving the same encoder data when the next keyframe plays (along with SEI if any). When detaching from the encoder, the last detachment will fully stop the encoder and detach the encoder from the media output context associated with the encoder. SEI must actually be exported separately; because new encoder attachments may not always be at the beginning of the stream, the first keyframe they get must have that SEI data in it. If the encoder has SEI data, it needs only add one small function to simply query that SEI data, and then that data will be handled automatically by libobs for all subsequent encoder attachments. - Implement x264 encoder plugin, move x264 files to separate plugin to separate necessary dependencies. - Change video/audio frame output structures to not use const qualifiers to prevent issues with non-const function usage elsewhere. This was an issue when writing the x264 encoder, as the x264 encoder expects non-const frame data. Change stagesurf_map to return a non-const data type to prevent this as well. - Change full range parameter of video scaler to be an enum rather than boolean
2014-03-16 16:21:34 -07:00
bool sent_first_packet;
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 (*new_packet)(void *param, struct encoder_packet *packet);
void *param;
};
struct obs_encoder {
struct obs_context_data context;
struct obs_encoder_info 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
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
uint32_t samplerate;
size_t planes;
size_t blocksize;
size_t framesize;
size_t framesize_bytes;
uint32_t scaled_width;
uint32_t scaled_height;
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
bool active;
Implement encoder interface (still preliminary) - Implement OBS encoder interface. It was previously incomplete, but now is reaching some level of completion, though probably should still be considered preliminary. I had originally implemented it so that encoders only have a 'reset' function to reset their parameters, but I felt that having both a 'start' and 'stop' function would be useful. Encoders are now assigned to a specific video/audio media output each rather than implicitely assigned to the main obs video/audio contexts. This allows separate encoder contexts that aren't necessarily assigned to the main video/audio context (which is useful for things such as recording specific sources). Will probably have to do this for regular obs outputs as well. When creating an encoder, you must now explicitely state whether that encoder is an audio or video encoder. Audio and video can optionally be automatically converted depending on what the encoder specifies. When something 'attaches' to an encoder, the first attachment starts the encoder, and the encoder automatically attaches to the media output context associated with it. Subsequent attachments won't have the same effect, they will just start receiving the same encoder data when the next keyframe plays (along with SEI if any). When detaching from the encoder, the last detachment will fully stop the encoder and detach the encoder from the media output context associated with the encoder. SEI must actually be exported separately; because new encoder attachments may not always be at the beginning of the stream, the first keyframe they get must have that SEI data in it. If the encoder has SEI data, it needs only add one small function to simply query that SEI data, and then that data will be handled automatically by libobs for all subsequent encoder attachments. - Implement x264 encoder plugin, move x264 files to separate plugin to separate necessary dependencies. - Change video/audio frame output structures to not use const qualifiers to prevent issues with non-const function usage elsewhere. This was an issue when writing the x264 encoder, as the x264 encoder expects non-const frame data. Change stagesurf_map to return a non-const data type to prevent this as well. - Change full range parameter of video scaler to be an enum rather than boolean
2014-03-16 16:21:34 -07:00
uint32_t timebase_num;
uint32_t timebase_den;
int64_t cur_pts;
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
struct circlebuf audio_input_buffer[MAX_AV_PLANES];
uint8_t *audio_output_buffer[MAX_AV_PLANES];
/* if a video encoder is paired with an audio encoder, make it start
* up at the specific timestamp. if this is the audio encoder,
* wait_for_video makes it wait until it's ready to sync up with
* video */
bool wait_for_video;
struct obs_encoder *paired_encoder;
uint64_t start_ts;
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
pthread_mutex_t outputs_mutex;
DARRAY(obs_output_t*) outputs;
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
bool destroy_on_stop;
/* stores the video/audio media output pointer. video_t *or audio_t **/
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
void *media;
Implement encoder interface (still preliminary) - Implement OBS encoder interface. It was previously incomplete, but now is reaching some level of completion, though probably should still be considered preliminary. I had originally implemented it so that encoders only have a 'reset' function to reset their parameters, but I felt that having both a 'start' and 'stop' function would be useful. Encoders are now assigned to a specific video/audio media output each rather than implicitely assigned to the main obs video/audio contexts. This allows separate encoder contexts that aren't necessarily assigned to the main video/audio context (which is useful for things such as recording specific sources). Will probably have to do this for regular obs outputs as well. When creating an encoder, you must now explicitely state whether that encoder is an audio or video encoder. Audio and video can optionally be automatically converted depending on what the encoder specifies. When something 'attaches' to an encoder, the first attachment starts the encoder, and the encoder automatically attaches to the media output context associated with it. Subsequent attachments won't have the same effect, they will just start receiving the same encoder data when the next keyframe plays (along with SEI if any). When detaching from the encoder, the last detachment will fully stop the encoder and detach the encoder from the media output context associated with the encoder. SEI must actually be exported separately; because new encoder attachments may not always be at the beginning of the stream, the first keyframe they get must have that SEI data in it. If the encoder has SEI data, it needs only add one small function to simply query that SEI data, and then that data will be handled automatically by libobs for all subsequent encoder attachments. - Implement x264 encoder plugin, move x264 files to separate plugin to separate necessary dependencies. - Change video/audio frame output structures to not use const qualifiers to prevent issues with non-const function usage elsewhere. This was an issue when writing the x264 encoder, as the x264 encoder expects non-const frame data. Change stagesurf_map to return a non-const data type to prevent this as well. - Change full range parameter of video scaler to be an enum rather than boolean
2014-03-16 16:21:34 -07:00
pthread_mutex_t callbacks_mutex;
DARRAY(struct encoder_callback) callbacks;
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 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
extern struct obs_encoder_info *find_encoder(const char *id);
extern bool obs_encoder_initialize(obs_encoder_t *encoder);
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
extern void obs_encoder_start(obs_encoder_t *encoder,
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
void (*new_packet)(void *param, struct encoder_packet *packet),
void *param);
extern void obs_encoder_stop(obs_encoder_t *encoder,
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
void (*new_packet)(void *param, struct encoder_packet *packet),
void *param);
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
extern void obs_encoder_add_output(struct obs_encoder *encoder,
struct obs_output *output);
extern void obs_encoder_remove_output(struct obs_encoder *encoder,
struct obs_output *output);
/* ------------------------------------------------------------------------- */
/* services */
struct obs_service {
struct obs_context_data context;
struct obs_service_info info;
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
bool active;
bool destroy;
struct obs_output *output;
};
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
extern const struct obs_service_info *find_service(const char *id);
extern void obs_service_activate(struct obs_service *service);
extern void obs_service_deactivate(struct obs_service *service, bool remove);
extern bool obs_service_initialize(struct obs_service *service,
struct obs_output *output);