OBS源类型注册大全
2024-06-21
27
0
上一节知道,在各个模块中,通过obs_register_source函数注册OBS源。
OBS源类型定义如下四种类型:
enum obs_source_type {
OBS_SOURCE_TYPE_INPUT,
OBS_SOURCE_TYPE_FILTER,
OBS_SOURCE_TYPE_TRANSITION,
OBS_SOURCE_TYPE_SCENE,
};
OBS源使用obs_source_info结构体标识,并根据类型存储于以下数组中。
struct obs_core {
...
obs_source_info_array_t source_types; //ALL
obs_source_info_array_t input_types; //OBS_SOURCE_TYPE_INPUT
obs_source_info_array_t filter_types;//OBS_SOURCE_TYPE_FILTER
obs_source_info_array_t transition_types;//OBS_SOURCE_TYPE_TRANSITION
...
}
这些源的注册,都是通过各个模块DLL或者OBS内部代码去注册的。
注册的源区分为同步和异步
#define OBS_SOURCE_ASYNC (1 << 2)
#define OBS_SOURCE_ASYNC_VIDEO (OBS_SOURCE_ASYNC | OBS_SOURCE_VIDEO)
对于异步源,可以不需要video_render回调渲染。
异步源使用obs_source_output_video函数传递原始视频数据,这将在指定的时间戳自动上传,即其在自己的线程中(如mp_media_thread)计算时间(mp_media_sleep),时间到了,直接调用mp_media_next_video(m->v_cb(m->opaque, frame))。而v_cb是get_frame
static void get_frame(void *opaque, struct obs_source_frame *f)
{
struct ffmpeg_source *s = opaque;
obs_source_output_video(s->source, f);
}
obs.c
scene
const struct obs_source_info scene_info = {
.id = "scene",
.type = OBS_SOURCE_TYPE_SCENE,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_COMPOSITE | OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_SRGB,
.get_name = scene_getname,
.create = scene_create,
.destroy = scene_destroy,
.video_tick = scene_video_tick,
.video_render = scene_video_render,
.audio_render = scene_audio_render,
.get_width = scene_getwidth,
.get_height = scene_getheight,
.load = scene_load,
.save = scene_save,
.enum_active_sources = scene_enum_active_sources,
.enum_all_sources = scene_enum_all_sources,
.video_get_color_space = scene_video_get_color_space,
};
obs_register_source(&scene_info);
group
const struct obs_source_info group_info = {
.id = "group",
.type = OBS_SOURCE_TYPE_SCENE,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_COMPOSITE | OBS_SOURCE_SRGB,
.get_name = group_getname,
.create = scene_create,
.destroy = scene_destroy,
.video_tick = scene_video_tick,
.video_render = scene_video_render,
.audio_render = scene_audio_render,
.get_width = scene_getwidth,
.get_height = scene_getheight,
.load = scene_load,
.save = scene_save,
.enum_active_sources = scene_enum_active_sources,
.enum_all_sources = scene_enum_all_sources,
.video_get_color_space = scene_video_get_color_space,
};
obs_register_source(&group_info);
audio_line
const struct obs_source_info audio_line_info = {
.id = "audio_line",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_CAP_DISABLED |
OBS_SOURCE_SUBMIX,
.get_name = submix_name,
};
obs_register_source(&audio_line_info);
plugin-decklink
decklink-input
struct obs_source_info decklink_source_info = {};
decklink_source_info.id = "decklink-input";
decklink_source_info.type = OBS_SOURCE_TYPE_INPUT;
decklink_source_info.output_flags =
OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_DO_NOT_DUPLICATE | OBS_SOURCE_CEA_708;
decklink_source_info.create = decklink_create;
decklink_source_info.destroy = decklink_destroy;
decklink_source_info.get_defaults = decklink_get_defaults;
decklink_source_info.get_name = decklink_get_name;
decklink_source_info.get_properties = decklink_get_properties;
decklink_source_info.update = decklink_update;
decklink_source_info.show = decklink_show;
decklink_source_info.hide = decklink_hide;
decklink_source_info.icon_type = OBS_ICON_TYPE_CAMERA;
obs_register_source(&decklink_source_info);
decklink_output
struct obs_output_info decklink_output_info = {};
decklink_output_info.id = "decklink_output";
decklink_output_info.flags = OBS_OUTPUT_AV;
decklink_output_info.get_name = decklink_output_get_name;
decklink_output_info.create = decklink_output_create;
decklink_output_info.destroy = decklink_output_destroy;
decklink_output_info.start = decklink_output_start;
decklink_output_info.stop = decklink_output_stop;
decklink_output_info.get_properties = decklink_output_properties;
decklink_output_info.raw_video = decklink_output_raw_video;
decklink_output_info.raw_audio = decklink_output_raw_audio;
decklink_output_info.update = decklink_output_update;
obs_register_output(&decklink_output_info);
plugin-image
static struct obs_source_info image_source_info = {
.id = "image_source",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_SRGB,
.get_name = image_source_get_name,
.create = image_source_create,
.destroy = image_source_destroy,
.update = image_source_update,
.get_defaults = image_source_defaults,
.show = image_source_show,
.hide = image_source_hide,
.get_width = image_source_getwidth,
.get_height = image_source_getheight,
.video_render = image_source_render,
.video_tick = image_source_tick,
.missing_files = image_source_missingfiles,
.get_properties = image_source_properties,
.icon_type = OBS_ICON_TYPE_IMAGE,
.activate = image_source_activate,
.video_get_color_space = image_source_get_color_space,
};
obs_register_source(&image_source_info);
color_source
struct obs_source_info color_source_info_v3 = {
.id = "color_source",
.version = 3,
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |OBS_SOURCE_SRGB,
.create = color_source_create,
.destroy = color_source_destroy,
.update = color_source_update,
.get_name = color_source_get_name,
.get_defaults = color_source_defaults_v3,
.get_width = color_source_getwidth,
.get_height = color_source_getheight,
.video_render = color_source_render,
.get_properties = color_source_properties,
.icon_type = OBS_ICON_TYPE_COLOR,
};
obs_register_source(&color_source_info_v3);
slideshow
struct obs_source_info slideshow_info_mk2 = {
.id = "slideshow",
.version = 2,
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_COMPOSITE | OBS_SOURCE_CONTROLLABLE_MEDIA,
.get_name = ss_getname,
.create = ss_create,
.destroy = ss_destroy,
.update = ss_update,
.activate = ss_activate,
.deactivate = ss_deactivate,
.video_render = ss_video_render,
.video_tick = ss_video_tick,
.audio_render = ss_audio_render,
.enum_active_sources = ss_enum_sources,
.get_width = ss_width,
.get_height = ss_height,
.get_defaults = ss_defaults,
.get_properties = ss_properties,
.missing_files = ss_missingfiles,
.icon_type = OBS_ICON_TYPE_SLIDESHOW,
.media_play_pause = ss_play_pause,
.media_restart = ss_restart,
.media_stop = ss_stop,
.media_next = ss_next_slide,
.media_previous = ss_previous_slide,
.media_get_state = ss_get_state,
.video_get_color_space = ss_video_get_color_space,
};
obs_register_source(&slideshow_info_mk2);
obs-ffmpeg
ffmpeg_source
struct obs_source_info ffmpeg_source = {
.id = "ffmpeg_source",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_CONTROLLABLE_MEDIA,
.get_name = ffmpeg_source_getname,
.create = ffmpeg_source_create,
.destroy = ffmpeg_source_destroy,
.get_defaults = ffmpeg_source_defaults,
.get_properties = ffmpeg_source_getproperties,
.activate = ffmpeg_source_activate,
.deactivate = ffmpeg_source_deactivate,
.video_tick = ffmpeg_source_tick,
.missing_files = ffmpeg_source_missingfiles,
.update = ffmpeg_source_update,
.icon_type = OBS_ICON_TYPE_MEDIA,
.media_play_pause = ffmpeg_source_play_pause,
.media_restart = ffmpeg_source_restart,
.media_stop = ffmpeg_source_stop,
.media_get_duration = ffmpeg_source_get_duration,
.media_get_time = ffmpeg_source_get_time,
.media_set_time = ffmpeg_source_set_time,
.media_get_state = ffmpeg_source_get_state,
};
其它
obs_register_source(&ffmpeg_source);
obs_register_output(&ffmpeg_output);
obs_register_output(&ffmpeg_muxer);
obs_register_output(&ffmpeg_mpegts_muxer);
obs_register_output(&ffmpeg_hls_muxer);
obs_register_output(&replay_buffer);
obs_register_encoder(&aac_encoder_info);
register_encoder_if_available(&svt_av1_encoder_info, "libsvtav1");
register_encoder_if_available(&aom_av1_encoder_info, "libaom-av1");
obs_register_encoder(&opus_encoder_info);
obs_register_encoder(&pcm_encoder_info);
obs_register_encoder(&pcm24_encoder_info);
obs_register_encoder(&pcm32_encoder_info);
obs_register_encoder(&alac_encoder_info);
obs_register_encoder(&flac_encoder_info);
#ifndef __APPLE__
bool h264 = false;
bool hevc = false;
bool av1 = false;
if (nvenc_supported(&h264, &hevc, &av1)) {
blog(LOG_INFO, "NVENC supported");
#ifdef _WIN32
obs_nvenc_load(h264, hevc, av1);
#endif
if (h264)
obs_register_encoder(&h264_nvenc_encoder_info);
#ifdef ENABLE_HEVC
if (hevc)
obs_register_encoder(&hevc_nvenc_encoder_info);
#endif
}
obs-filters
mask_filter
struct obs_source_info mask_filter = {
.id = "mask_filter",
.type = OBS_SOURCE_TYPE_FILTER,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE,
.get_name = mask_filter_get_name,
.create = mask_filter_create,
.destroy = mask_filter_destroy,
.update = mask_filter_update_v1,
.get_defaults = mask_filter_defaults_v1,
.get_properties = mask_filter_properties_v1,
.video_tick = mask_filter_tick,
.video_render = mask_filter_render,
};
其它
bool obs_module_load(void)
{
obs_register_source(&mask_filter);
obs_register_source(&mask_filter_v2);
obs_register_source(&crop_filter);
obs_register_source(&gain_filter);
obs_register_source(&eq_filter);
obs_register_source(&hdr_tonemap_filter);
obs_register_source(&color_filter);
obs_register_source(&color_filter_v2);
obs_register_source(&scale_filter);
obs_register_source(&scroll_filter);
obs_register_source(&gpu_delay_filter);
obs_register_source(&color_key_filter);
obs_register_source(&color_key_filter_v2);
obs_register_source(&color_grade_filter);
obs_register_source(&sharpness_filter);
obs_register_source(&sharpness_filter_v2);
obs_register_source(&chroma_key_filter);
obs_register_source(&chroma_key_filter_v2);
obs_register_source(&async_delay_filter);
#if defined(HAS_NOISEREDUCTION)
#ifdef LIBNVAFX_ENABLED
/* load nvidia audio fx dll */
load_nvafx();
#endif
obs_register_source(&noise_suppress_filter);
obs_register_source(&noise_suppress_filter_v2);
#endif
obs_register_source(&invert_polarity_filter);
obs_register_source(&noise_gate_filter);
obs_register_source(&compressor_filter);
obs_register_source(&limiter_filter);
obs_register_source(&expander_filter);
obs_register_source(&upward_compressor_filter);
obs_register_source(&luma_key_filter);
obs_register_source(&luma_key_filter_v2);
#ifdef LIBNVVFX_ENABLED
if (load_nvvfx())
obs_register_source(&nvidia_greenscreen_filter_info);
#endif
return true;
}
obs-text
text_gdiplus
obs_source_info si = {};
si.id = "text_gdiplus";
si.type = OBS_SOURCE_TYPE_INPUT;
si.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |
OBS_SOURCE_CAP_OBSOLETE | OBS_SOURCE_SRGB;
si.get_properties = get_properties;
si.icon_type = OBS_ICON_TYPE_TEXT;
obs_source_info si_v2 = si;
si_v2.version = 2;
obs_source_info si_v3 = si_v2;
si_v3.version = 3;
si_v3.output_flags &= ~OBS_SOURCE_CAP_OBSOLETE;
obs_register_source(&si);
obs_register_source(&si_v2);
obs_register_source(&si_v3);
obs-transitions
cut_transition
struct obs_source_info cut_transition = {
.id = "cut_transition",
.type = OBS_SOURCE_TYPE_TRANSITION,
.get_name = cut_get_name,
.create = cut_create,
.destroy = cut_destroy,
.video_render = cut_video_render,
.audio_render = cut_audio_render,
.video_get_color_space = cut_video_get_color_space,
};
bool obs_module_load(void)
{
obs_register_source(&cut_transition);
obs_register_source(&fade_transition);
obs_register_source(&swipe_transition);
obs_register_source(&slide_transition);
obs_register_source(&stinger_transition);
obs_register_source(&fade_to_color_transition);
obs_register_source(&luma_wipe_transition);
return true;
}
obs-vst
struct obs_source_info vst_filter = {};
vst_filter.id = "vst_filter";
vst_filter.type = OBS_SOURCE_TYPE_FILTER;
vst_filter.output_flags = OBS_SOURCE_AUDIO;
vst_filter.get_name = vst_name;
vst_filter.create = vst_create;
vst_filter.destroy = vst_destroy;
vst_filter.update = vst_update;
vst_filter.filter_audio = vst_filter_audio;
vst_filter.get_properties = vst_properties;
vst_filter.save = vst_save;
obs_register_source(&vst_filter);
oss-audio
struct obs_source_info oss_input_capture = {
.id = "oss_input_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_AUDIO,
.get_name = oss_getname,
.create = oss_create,
.destroy = oss_destroy,
.update = oss_update,
.get_defaults = oss_defaults,
.get_properties = oss_properties,
.icon_type = OBS_ICON_TYPE_AUDIO_INPUT,
};
obs_register_source(&oss_input_capture);
sndio
struct obs_source_info sndio_output_capture = {
.id = "sndio_output_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_AUDIO,
.get_name = sndio_input_getname,
.create = sndio_create,
.destroy = sndio_destroy,
#if SHUTDOWN_ON_DEACTIVATE
.activate = sndio_activate,
.deactivate = sndio_deactivate,
#endif
.update = sndio_update,
.get_defaults = sndio_input_defaults,
.get_properties = sndio_input_properties,
.icon_type = OBS_ICON_TYPE_AUDIO_OUTPUT,
};
obs_register_source(&sndio_output_capture);
text-freetype2
static struct obs_source_info freetype2_source_info_v1 = {
.id = "text_ft2_source",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_CAP_OBSOLETE |
OBS_SOURCE_CUSTOM_DRAW,
.get_name = ft2_source_get_name,
.create = ft2_source_create,
.destroy = ft2_source_destroy,
.update = ft2_source_update,
.get_width = ft2_source_get_width,
.get_height = ft2_source_get_height,
.video_render = ft2_source_render,
.video_tick = ft2_video_tick,
.get_defaults = ft2_source_defaults_v1,
.get_properties = ft2_source_properties,
.icon_type = OBS_ICON_TYPE_TEXT,
};
obs_register_source(&freetype2_source_info_v1);
obs_register_source(&freetype2_source_info_v2);
vlc-video-plugin
struct obs_source_info vlc_source_info = {
.id = "vlc_source",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_ASYNC_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_CONTROLLABLE_MEDIA,
.get_name = vlcs_get_name,
.create = vlcs_create,
.destroy = vlcs_destroy,
.update = vlcs_update,
.get_defaults = vlcs_defaults,
.get_properties = vlcs_properties,
.activate = vlcs_activate,
.deactivate = vlcs_deactivate,
.missing_files = vlcs_missingfiles,
.icon_type = OBS_ICON_TYPE_MEDIA,
.media_play_pause = vlcs_play_pause,
.media_restart = vlcs_restart,
.media_stop = vlcs_stop,
.media_next = vlcs_playlist_next,
.media_previous = vlcs_playlist_prev,
.media_get_duration = vlcs_get_duration,
.media_get_time = vlcs_get_time,
.media_set_time = vlcs_set_time,
.media_get_state = vlcs_get_state,
};
obs_register_source(&vlc_source_info);
win-capture
struct obs_source_info game_capture_info = {
.id = "game_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_SRGB,
.get_name = game_capture_name,
.create = game_capture_create,
.destroy = game_capture_destroy,
.get_width = game_capture_width,
.get_height = game_capture_height,
.get_defaults = game_capture_defaults,
.get_properties = game_capture_properties,
.enum_active_sources = game_capture_enum,
.update = game_capture_update,
.video_tick = game_capture_tick,
.video_render = game_capture_render,
.icon_type = OBS_ICON_TYPE_GAME_CAPTURE,
.video_get_color_space = game_capture_get_color_space,
};
struct obs_source_info window_capture_info = {
.id = "window_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_SRGB,
.get_name = wc_getname,
.create = wc_create,
.destroy = wc_destroy,
.update = wc_update,
.video_render = wc_render,
.hide = wc_hide,
.video_tick = wc_tick,
.get_width = wc_width,
.get_height = wc_height,
.get_defaults = wc_defaults,
.get_properties = wc_properties,
.enum_active_sources = wc_child_enum,
.icon_type = OBS_ICON_TYPE_WINDOW_CAPTURE,
.video_get_color_space = wc_get_color_space,
};
struct obs_source_info game_capture_info = {
.id = "game_capture",
.type = OBS_SOURCE_TYPE_INPUT,
.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_CUSTOM_DRAW | OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_SRGB,
.get_name = game_capture_name,
.create = game_capture_create,
.destroy = game_capture_destroy,
.get_width = game_capture_width,
.get_height = game_capture_height,
.get_defaults = game_capture_defaults,
.get_properties = game_capture_properties,
.enum_active_sources = game_capture_enum,
.update = game_capture_update,
.video_tick = game_capture_tick,
.video_render = game_capture_render,
.icon_type = OBS_ICON_TYPE_GAME_CAPTURE,
.video_get_color_space = game_capture_get_color_space,
};
obs_register_source(&game_capture_info);
if (win8_or_above && graphics_uses_d3d11)
obs_register_source(&duplicator_capture_info);
else
obs_register_source(&monitor_capture_info);
obs_register_source(&window_capture_info);
obs_register_source(&game_capture_info);
win-dshow
obs_source_info info = {};
info.id = "dshow_input";
info.type = OBS_SOURCE_TYPE_INPUT;
info.output_flags = OBS_SOURCE_VIDEO | OBS_SOURCE_AUDIO |
OBS_SOURCE_ASYNC | OBS_SOURCE_DO_NOT_DUPLICATE;
info.show = ShowDShowInput;
info.hide = HideDShowInput;
info.get_name = GetDShowInputName;
info.create = CreateDShowInput;
info.destroy = DestroyDShowInput;
info.update = UpdateDShowInput;
info.get_defaults = GetDShowDefaults;
info.get_properties = GetDShowProperties;
info.icon_type = OBS_ICON_TYPE_CAMERA;
obs_register_source(&info);
win-wasapi
obs_source_info info = {};
info.id = "wasapi_input_capture";
info.type = OBS_SOURCE_TYPE_INPUT;
info.output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE;
info.get_name = GetWASAPIInputName;
info.create = CreateWASAPIInput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsInput;
info.get_properties = GetWASAPIPropertiesInput;
info.icon_type = OBS_ICON_TYPE_AUDIO_INPUT;
obs_register_source(&info);//wasapi_input_capture
obs_source_info info = {};
info.id = "wasapi_output_capture";
info.type = OBS_SOURCE_TYPE_INPUT;
info.output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_DO_NOT_SELF_MONITOR;
info.get_name = GetWASAPIDeviceOutputName;
info.create = CreateWASAPIDeviceOutput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsDeviceOutput;
info.get_properties = GetWASAPIPropertiesDeviceOutput;
info.icon_type = OBS_ICON_TYPE_AUDIO_OUTPUT;
obs_register_source(&info);
obs_source_info info = {};
info.id = "wasapi_process_output_capture";
info.type = OBS_SOURCE_TYPE_INPUT;
info.output_flags = OBS_SOURCE_AUDIO | OBS_SOURCE_DO_NOT_DUPLICATE |
OBS_SOURCE_DO_NOT_SELF_MONITOR;
info.get_name = GetWASAPIProcessOutputName;
info.create = CreateWASAPIProcessOutput;
info.destroy = DestroyWASAPISource;
info.update = UpdateWASAPISource;
info.activate = ActivateWASAPISource;
info.deactivate = DeactivateWASAPISource;
info.get_defaults = GetWASAPIDefaultsProcessOutput;
info.get_properties = GetWASAPIPropertiesProcessOutput;
info.icon_type = OBS_ICON_TYPE_PROCESS_AUDIO_OUTPUT;
obs_register_source(&info);