1,obs插件管理

201 阅读3分钟

OBS的插件管理系统是其架构中的重要组成部分。OBS 插件系统通过插件框架允许第三方开发者扩展 OBS 的功能,插件可以是源(source)、输出(output)、过渡(transition)、滤镜(filter)等。本文将详细分析 OBS 的插件管理部分,包括插件的加载、注册、调用等内容。

1,插件目录加载

obs调用obs_startup函数,初始化全局变量struct obs_core *obs

图片.png 在该函数中添加默认插件目录

默认目录由OBS_INSTALL_PREFIX拼接OBS_PLUGIN_DESTINATION组成,linux默认/usr/local/lib/obs-plugins

调用顺序obs_startup-->obs_init-->add_default_module_paths

图片.png 默认插件目录保存在全局变量obs->module_paths数组中,我们也可以调用obs_add_module_path加载自己自定义的插件目录

图片.png

2,插件加载

调用obs_load_all_modules,在obs_load_all_modules中调用obs_find_modules传参库加载处理回调函数load_all_callback

图片.png obs_find_modules遍历所有插件目录obs->module_paths,查找目录下所有的so路径,so库路径由load_all_callback回调处理加载

图片.png obs_open_module调用os_dlopen[封装了各操作系统动态库加载接口,linux下为dlopen]并将so句柄保存在obs->first_module链表中

load_module_exports[实际调用linux下dlsym加载]根据函数名称加载so库中函数指针,如obs_module_load

各个插件均需实现

图片.png obs_open_module加载插件会调用obs_init_module,实际调用的是各个模块下obs_module_load函数,这个函数的非常重要

至此,我们拥有了一个全局变量struct obs_core *obs,该变量下包含一个链表保存了各个插件信息以及函数指针

3,插件注册

以obs-x264编码器插件为例,加载插件时会调用obs_module_load

图片.png

obs_encoder_info为编码器插件通用结构体,保存了create,destroy,encode,update等函数指针以及编码器id,编码器名称等信息

obs_x264_encoder全局变量如下,各个函数指针的实现由x264编码库封装而来

图片.png

我们需要关注obs_register_encoder的行为

图片.png CHECK_REQUIRED_VAL_宏用于检测对应接口是否存在有效

我们将REGISTER_OBS_DEF(size, obs_encoder_info, obs->encoder_types, info);宏展开得到如下代码

图片.png memcpy将全局变量复制到了data中然后添加到了obs->encoder_types.da数组中,我们可以通过遍历该数组通过id查找到对应的obs_encoder_info,然后调用obs_encoder_info里面的接口以完成编解码

4,插件调用

上面我们已经将插件注册到了obs->encoder_types.da中,我们调用

obs_video_encoder_create("obs_x264", "simple_h264_stream", encoder_settings, nullptr);

obs_x264为id需要和插件中保持一致,simple_h264_stream为名称可以自定义,encoder_settings是编码配置相关

成功的话会返回obs_encoder_t指针,该指针包含了obs_encoder_info,obs_encoder_info就是我们需要的编解码接口,obs_video_encoder_create源码如下:

图片.png

图片.png 在find_encoder遍历全局变量obs->encoder_types.da数组查找obs_x264对应的obs_encoder_info,这里和上面插件注册是一一对应的

图片.png 其他类型插件注册和调用也是类似的都是采用加载到全局obs数组中,然后通过id查找的方式,如source,input,filter,transition,output,service等

图片.png