OBS源
+ -

OBS源类型注册大全

2024-06-21 21 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);

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);

0 篇笔记 写笔记

作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!