OBS-scene
+ -

obs-scene场景

2024-06-04 34 0

scene

OBS至少需要一个场景。
211123986195
每个scene使用结构体obs_scene来表示:

struct obs_scene {
    struct obs_source *source;

    bool is_group;
    bool custom_size;
    uint32_t cx;
    uint32_t cy;

    int64_t id_counter;

    pthread_mutex_t video_mutex;
    pthread_mutex_t audio_mutex;
    struct obs_scene_item *first_item;
};

obs_scene对象其实和color_source属性同性质类的。其都是对通用obs_source_t的封装。obs扬景中的所有子对象加由链表first_item相连。
102834799653

每个obs_scene下可以有多个obs_scene_item,这些item可以是group,也可以是视频,图片,文字等。
232637352926


struct obs_scene_item {
    volatile long ref;
    volatile bool removed;

    bool is_group;
    bool update_transform;
    bool update_group_resize;

    int64_t id;

    struct obs_scene *parent;
    struct obs_source *source;
    volatile long active_refs;
    volatile long defer_update;
    volatile long defer_group_resize;
    bool user_visible;
    bool visible;
    bool selected;
    bool locked;

    gs_texrender_t *item_render;
    struct obs_sceneitem_crop crop;

    struct vec2 pos;
    struct vec2 scale;
    float rot;
    uint32_t align;

    /* last width/height of the source, this is used to check whether
     * the transform needs updating */
    uint32_t last_width;
    uint32_t last_height;

    struct vec2 output_scale;
    enum obs_scale_type scale_filter;

    enum obs_blending_method blend_method;
    enum obs_blending_type blend_type;

    struct matrix4 box_transform;
    struct vec2 box_scale;
    struct matrix4 draw_transform;

    enum obs_bounds_type bounds_type;
    uint32_t bounds_align;
    struct vec2 bounds;
    bool crop_to_bounds;
    struct obs_sceneitem_crop bounds_crop;

    obs_hotkey_pair_id toggle_visibility;

    obs_data_t *private_settings;

    pthread_mutex_t actions_mutex;
    DARRAY(struct item_action) audio_actions;

    struct obs_source *show_transition;
    struct obs_source *hide_transition;
    uint32_t show_transition_duration;
    uint32_t hide_transition_duration;

    /* would do **prev_next, but not really great for reordering */
    struct obs_scene_item *prev;
    struct obs_scene_item *next;
};

关于obs-scener的关回函数如下:

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-scene场景创建

默认的第一个场景是在void OBSBasic::OBSInit()函数中使用OBSBasic::Load(savePath),然后调用CreateDefaultScene(true)来实现的。

void OBSBasic::CreateDefaultScene(bool firstStart)
{
    disableSaving++;

    ClearSceneData();
    InitDefaultTransitions();
    CreateDefaultQuickTransitions();
    ui->transitionDuration->setValue(300);
    SetTransition(fadeTransition);

//创建默认的第一个场景
    OBSSceneAutoRelease scene = obs_scene_create(Str("Basic.Scene"));

//将其设置为第一个场景
    if (firstStart)
        CreateFirstRunSources();

//当设置为当前扬景
    SetCurrentScene(scene, true);

    disableSaving--;
}

在OBS中,使用一个公共的结构体obs_source来描述所有的源信息。其结构体的成员context.data用来指向具体的那种源结构体。具体可见:create_private_id函数

obs_scene_t *obs_scene_create(const char *name)
{
    return create_id("scene", name);
}
static inline obs_scene_t *create_private_id(const char *id, const char *name)
{
    struct obs_source *source = obs_source_create_private(id, name, NULL);
    return source->context.data;
}

obs_source_create调用obs_source_create_internal:

obs_source_t *obs_source_create(const char *id, const char *name,
                obs_data_t *settings, obs_data_t *hotkey_data)
{
    return obs_source_create_internal(id, name, NULL, settings, hotkey_data,
                      false, LIBOBS_API_VER);
}

最终创建场景

static obs_source_t *
obs_source_create_internal(const char *id, const char *name, const char *uuid,
               obs_data_t *settings, obs_data_t *hotkey_data,
               bool private, uint32_t last_obs_ver)
{

//创建源通用结构体
    struct obs_source *source = bzalloc(sizeof(struct obs_source));

//根据ID中找到const struct obs_source_info scene_info回调函数集
    const struct obs_source_info *info = get_source_info(id);
    if (!info) {
        blog(LOG_ERROR, "Source ID '%s' not found", id);

        source->info.id = bstrdup(id);
        source->owns_info_id = true;
        source->info.unversioned_id = bstrdup(source->info.id);
    } else {
        source->info = *info;

        /* Always mark filters as private so they aren't found by
         * source enum/search functions.
         *
         * XXX: Fix design flaws with filters */
        if (info->type == OBS_SOURCE_TYPE_FILTER)
        private = true;
    }

    source->mute_unmute_key = OBS_INVALID_HOTKEY_PAIR_ID;
    source->push_to_mute_key = OBS_INVALID_HOTKEY_ID;
    source->push_to_talk_key = OBS_INVALID_HOTKEY_ID;
    source->last_obs_ver = last_obs_ver;

    //加入全局obs结构体data.first_audio_source的链表。
    if (!obs_source_init_context(source, settings, name, uuid, hotkey_data,private))
        goto fail;

    if (info) {
        if (info->get_defaults) {
            info->get_defaults(source->context.settings);
        }
        if (info->get_defaults2) {
            info->get_defaults2(info->type_data,
                        source->context.settings);
        }
    }

    if (!obs_source_init(source))
        goto fail;

    if (!private)
        obs_source_init_audio_hotkeys(source);

    /* allow the source to be created even if creation fails so that the
     * user's data doesn't become lost */
     //调用回调函数create即scene_create创建特定源的上下文信息
    if (info && info->create)
        source->context.data = info->create(source->context.settings, source);
    if ((!info || info->create) && !source->context.data)
        blog(LOG_ERROR, "Failed to create source '%s'!", name);

    blog(LOG_DEBUG, "%ssource '%s' (%s) created", private ? "private " : "",
         name, id);

    source->flags = source->default_flags;
    source->enabled = true;

    obs_source_init_finalize(source);
    if (!private) {
        obs_source_dosignal(source, "source_create", NULL);
    }

    return source;

fail:
    blog(LOG_ERROR, "obs_source_create failed");
    obs_source_destroy(source);
    return NULL;
}

0 篇笔记 写笔记

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

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

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