obs插件基础

(一)OBS插件模块基本信息(加载插件模块时使用)

libobs 是obs最核心的库,其他扩展插件都是基于 libobs (负责管理各个插件)

1. 模块信息结构体

//模块信息结构体 obs\obs-studio\libobs\obs-internal.h 中定义
struct obs_module { 
	char *mod_name;                 //模块名
	const char *file;               //模块文件名
	char *bin_path;                 //dll路径
	char *data_path;                //数据路径
	void *module;                   //dll打开后的handle
	bool loaded;

    //模块的一些导出接口
	bool (*load)(void);     //加载模块时首先调用这个函数指针,每个模块都需要实现这个函数指针(obs_moudle_load 函数)
	void (*unload)(void);
	void (*post_load)(void);
	void (*set_locale)(const char *locale);
	bool (*get_string)(const char *lookup_string,
			   const char **translated_string);
	void (*free_locale)(void);
	uint32_t (*ver)(void);
	void (*set_pointer)(obs_module_t *module);
	const char *(*name)(void);
	const char *(*description)(void);
	const char *(*author)(void);

	struct obs_module *next;  //指向下一个模块
};	

2. 模块通用函数

// obs\obs-studio\libobs\util\platform-windows.c 中定义
void *os_dlopen(const char *path)                   //打开dll
void *os_dlsym(void *module, const char *func)      //dll中函数接口的导出地址
//示例:
struct obs_module mod = {0};
mod.module = os_dlopen(path);
load_module_exports(&mod, path);
static int load_module_exports(struct obs_module *mod, const char *path)
{
	mod->load = os_dlsym(mod->module, "obs_module_load");
	if (!mod->load)
		return req_func_not_found("obs_module_load", path);

	mod->set_pointer = os_dlsym(mod->module, "obs_module_set_pointer");
	if (!mod->set_pointer)
		return req_func_not_found("obs_module_set_pointer", path);

	mod->ver = os_dlsym(mod->module, "obs_module_ver");
	if (!mod->ver)
		return req_func_not_found("obs_module_ver", path);

	/* optional exports */
	mod->unload = os_dlsym(mod->module, "obs_module_unload");
	mod->post_load = os_dlsym(mod->module, "obs_module_post_load");
	mod->set_locale = os_dlsym(mod->module, "obs_module_set_locale");
	mod->free_locale = os_dlsym(mod->module, "obs_module_free_locale");
	mod->name = os_dlsym(mod->module, "obs_module_name");
	mod->description = os_dlsym(mod->module, "obs_module_description");
	mod->author = os_dlsym(mod->module, "obs_module_author");
	mod->get_string = os_dlsym(mod->module, "obs_module_get_string");
	return MODULE_SUCCESS;
}

(二)OBS插件模块核心内容(编写插件模块时使用)

实现模块插件必要内容

  1. 包含头文件 #include obs\obs-studio\libobs\obs-module.h 目录下
  2. 包含 OBS_DECLARE_MODULE()
  3. 实现 bool obs_module_load(void) (仅在头文件obs-module.h中定义,每个插件模块需要实现此函数)

可选内容

  1. 包含 OBS_MODULE_USE_DEFAULT_LOCALE("win-dshow", "en-US") 默认语言处理相关的宏(虽非必须,但通常也都包含)
  2. void obs_module_unload(void) void obs_module_post_load(void) ;void obs_module_set_locale(const char *locale) ;void obs_module_free_locale(void);

1. 宏定义 OBS_DECLARE_MODULE()

#define OBS_DECLARE_MODULE() 
    //静态模块变量       
    static obs_module_t *obs_module_pointer;     
    //两个导出接口函数             
	MODULE_EXPORT void obs_module_set_pointer(obs_module_t *module);  
    MODULE_EXPORT uint32_t obs_module_ver(void);
    //设置变量值      
	void obs_module_set_pointer(obs_module_t *module)                
	{                                                                     
		obs_module_pointer = module;                               
	}         
    //获得变量值                                                           
	obs_module_t *obs_current_module(void) { return obs_module_pointer; }

    //模块版本
	uint32_t obs_module_ver(void) { return LIBOBS_API_VER; }

2. bool obs_module_load(void) 函数实现示例

//win-dshow插件 obs\obs-studio\plugins\win-dshow\dshow-plugin.cpp 中定义
bool obs_module_load(void)
{
	RegisterDShowSource();
	RegisterDShowEncoders();
#ifdef VIRTUALCAM_ENABLED
	obs_register_output(&virtualcam_info);

	bool installed = vcam_installed(false);
#else
	bool installed = false;
#endif

	obs_data_t *obs_settings = obs_data_create();
	obs_data_set_bool(obs_settings, "vcamEnabled", installed);
	obs_apply_private_data(obs_settings);
	obs_data_release(obs_settings);

	return true;
}

3. 宏定义 OBS_MODULE_USE_DEFAULT_LOCALE

/** Optional: Use this macro in a module to use default locale handling. */
#define OBS_MODULE_USE_DEFAULT_LOCALE(module_name, default_locale)      \
	lookup_t *obs_module_lookup = NULL;                             \
	const char *obs_module_text(const char *val)                    \
	{                                                               \
		const char *out = val;                                  \
		text_lookup_getstr(obs_module_lookup, val, &out);       \
		return out;                                             \
	}                                                               \
	bool obs_module_get_string(const char *val, const char **out)   \
	{                                                               \
		return text_lookup_getstr(obs_module_lookup, val, out); \
	}                                                               \
	void obs_module_set_locale(const char *locale)                  \
	{                                                               \
		if (obs_module_lookup)                                  \
			text_lookup_destroy(obs_module_lookup);         \
		obs_module_lookup = obs_module_load_locale(             \
			obs_current_module(), default_locale, locale);  \
	}                                                               \
	void obs_module_free_locale(void)                               \
	{                                                               \
		text_lookup_destroy(obs_module_lookup);                 \
		obs_module_lookup = NULL;                               \
	}

    //使用示例
    OBS_MODULE_USE_DEFAULT_LOCALE("win-dshow", "en-US")

(三)使用OBS插件模块

插件基本信息

  1. OBS插件是一些编译好的dll库,放在制定目录下,由 libobs 加载,然后调用 os_dlopenos_dlsym 获得插件的对外接口
  2. 插件目录结构
  • obs\obs-studio\build-vs2019\rundir\Debug\bin ->可执行程序目录 obs.exe
  • obs\obs-studio\build-vs2019\rundir\Debug\data ->资源目录
  • obs\obs-studio\build-vs2019\rundir\Debug\data\obs-plugins ->各个插件资源目录
  • obs\obs-studio\build-vs2019\rundir\Debug\data\obs-plugins\win-dshow\locale ->win-dshow 插件下面的语言包
  • obs\obs-studio\build-vs2019\rundir\Debug\obs-plugins\32bit -> 所有插件dll位置
  1. 插件初始化过程

    3.1 设置插件路径(.dll路径和插件data路径)

    main():obs-app.cpp
    run_program():obs-app.cpp
    OBSApp::OBSInit():obs-app.cpp
    OBSBasic::OBSInit():window-base-main.cpp
    AddExtraModulePaths 设置windows系统插件路径
    StartupOBS
    obs_startup
    obs_init
    add_default_module_paths 设置默认插件路径 ../../obs-plugins/ ../../data/obs-plugins/%module%

    3.2 插件初始化

    查找插件、设置插件路径obs_load_all_modules()
    查找所有插件并设置回调obs_find_modules(load_all_callback, NULL)
    在指定路径中查找插件 find_modules_in_path(struct obs_module_path *omp, obs_find_module_callback_t callback, void *param)
    处理每个查到的插件 process_found_module(omp, gi->gl_pathv[i].path, search_directories, callback, param);
    回调加载插件 load_all_callback()
    打开插件,并进行初始化 obs_open_module
    打开dll并导出函数 os_dlopen、load_module_exports
    初始化插件 obs_init_module
    调用每个插件实现的obs_module_load 函数 module->load()

1. obs_load_all_modules() 函数分析

//obs\obs-studio\libobs\obs-module.c
void obs_load_all_modules(void)
{
	profile_start(obs_load_all_modules_name);
	obs_find_modules(load_all_callback, NULL);   //查找所有模块
#ifdef _WIN32
	profile_start(reset_win32_symbol_paths_name);
	reset_win32_symbol_paths();
	profile_end(reset_win32_symbol_paths_name);
#endif
	profile_end(obs_load_all_modules_name);
}

void obs_find_modules(obs_find_module_callback_t callback, void *param)
{
	if (!obs)
		return;

	for (size_t i = 0; i < obs->module_paths.num; i++) 
    {
		struct obs_module_path *omp = obs->module_paths.array + i;
		find_modules_in_path(omp, callback, param);             //加载查找到的插件
	}
}
//函数调用
find_modules_in_path()    //加载插件
    |os_glob()
    |process_found_module() //处理插件
        |info.bin_path = parsed_bin_path.array;
		|info.data_path = parsed_data_dir;
		|callback(param, &info);   //调用回调传出插件信息(info)

    |static void load_all_callback(void *param, const struct obs_module_info *info)    //回调函数
        |obs_open_module()   //加载dll 获得模块基本信息和导出接口
            |mod.module = os_dlopen(path);
            |load_module_exports(&mod, path);   //获得模块导出接口指针 对应 ## 2. 模块通用函数
		|obs_init_module(module);				//初始化模块
			|module->loaded	 //此处调用插件自己实现的 bool obs_module_load(void)

你可能感兴趣的:(OBS,c++,windows,obs)