OBS-scene
+ -

obs-scene场景添加元素item

2024-06-04 21 0

场景中的资源是通过函数AddNew实现的。具体可详见:https://www.pnpon.com/article/detail-636.html

bool AddNew(QWidget *parent, const char *id, const char *name,
        const bool visible, OBSSource &newSource)
{
    OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
    OBSScene scene = main->GetCurrentScene();
    bool success = false;
    if (!scene)
        return false;

    OBSSourceAutoRelease source = obs_get_source_by_name(name);
    if (source && parent) {
        OBSMessageBox::information(parent, QTStr("NameExists.Title"),
                       QTStr("NameExists.Text"));

    } else {
        const char *v_id = obs_get_latest_input_type_id(id);
        source = obs_source_create(v_id, name, NULL, nullptr);

        if (source) {
            //入参
            AddSourceData data;
            data.source = source;
            data.visible = visible;

            obs_enter_graphics();
            //调用AddSource创建源
            obs_scene_atomic_update(scene, AddSource, &data);
            obs_leave_graphics();

            newSource = source;

            /* set monitoring if source monitors by default */
            uint32_t flags = obs_source_get_output_flags(source);
            if ((flags & OBS_SOURCE_MONITOR_BY_DEFAULT) != 0) {
                obs_source_set_monitoring_type(
                    source,
                    OBS_MONITORING_TYPE_MONITOR_ONLY);
            }

            success = true;
        }
    }

    return success;
}

AddNew中使用obs_source_create获取obs_source_t并和visible组合成结构体AddSourceData,并调用AddSource。
232637352926
AddSource函数中根据类型id使用函数obs_scene_add来创建资源item

static void AddSource(void *_data, obs_scene_t *scene)
{
    AddSourceData *data = (AddSourceData *)_data;
    obs_sceneitem_t *sceneitem;


    sceneitem = obs_scene_add(scene, data->source);

    if (data->transform != nullptr)
        obs_sceneitem_set_info2(sceneitem, data->transform);
    if (data->crop != nullptr)
        obs_sceneitem_set_crop(sceneitem, data->crop);
    if (data->blend_method != nullptr)
        obs_sceneitem_set_blending_method(sceneitem,
                          *data->blend_method);
    if (data->blend_mode != nullptr)
        obs_sceneitem_set_blending_mode(sceneitem, *data->blend_mode);

    obs_sceneitem_set_visible(sceneitem, data->visible);
}
obs_sceneitem_t *obs_scene_add(obs_scene_t *scene, obs_source_t *source)
{
    obs_sceneitem_t *item = obs_scene_add_internal(scene, source, NULL, 0);
    struct calldata params;
    uint8_t stack[128];

    if (!item)
        return NULL;

    calldata_init_fixed(&params, stack, sizeof(stack));
    calldata_set_ptr(&params, "scene", scene);
    calldata_set_ptr(&params, "item", item);
    signal_handler_signal(scene->source->context.signals, "item_add",
                  &params);
    return item;
}

最终调用obs_scene_add_internal


static obs_sceneitem_t *obs_scene_add_internal(obs_scene_t *scene,
                           obs_source_t *source,
                           obs_sceneitem_t *insert_after,
                           int64_t id)
{
    struct obs_scene_item *last;
    struct obs_scene_item *item;
    pthread_mutex_t mutex;

    struct item_action action = {.visible = true,
                     .timestamp = os_gettime_ns()};

    if (!scene)
        return NULL;

//增加引用计数
    source = obs_source_get_ref(source);
    if (!source) {
        blog(LOG_ERROR, "Tried to add a NULL source to a scene");
        return NULL;
    }

    if (source->removed) {
        blog(LOG_WARNING, "Tried to add a removed source to a scene");
        goto release_source_and_fail;
    }

    if (pthread_mutex_init(&mutex, NULL) != 0) {
        blog(LOG_WARNING, "Failed to create scene item mutex");
        goto release_source_and_fail;
    }

    if (!obs_source_add_active_child(scene->source, source)) {
        blog(LOG_WARNING, "Failed to add source to scene due to "
                  "infinite source recursion");
        pthread_mutex_destroy(&mutex);
        goto release_source_and_fail;
    }

//申请obs_scene_item空间结构体
    item = bzalloc(sizeof(struct obs_scene_item));
    item->source = source;
    item->id = id ? id : ++scene->id_counter;
    item->parent = scene;
    item->ref = 1;
    item->align = OBS_ALIGN_TOP | OBS_ALIGN_LEFT;
    item->actions_mutex = mutex;
    item->user_visible = true;
    item->locked = false;
    item->is_group = strcmp(source->info.id, group_info.id) == 0;
    item->private_settings = obs_data_create();
    item->toggle_visibility = OBS_INVALID_HOTKEY_PAIR_ID;
    os_atomic_set_long(&item->active_refs, 1);
    vec2_set(&item->scale, 1.0f, 1.0f);
    matrix4_identity(&item->draw_transform);
    matrix4_identity(&item->box_transform);

    if (source_has_audio(source)) {
        item->visible = false;
        da_push_back(item->audio_actions, &action);
    } else {
        item->visible = true;
    }

    full_lock(scene);

//加入scene的链表
    if (insert_after) {
        obs_sceneitem_t *next = insert_after->next;
        if (next)
            next->prev = item;
        item->next = insert_after->next;
        item->prev = insert_after;
        insert_after->next = item;
    } else {
        last = scene->first_item;
        if (!last) {
            scene->first_item = item;
        } else {
            while (last->next)
                last = last->next;

            last->next = item;
            item->prev = last;
        }
    }

    full_unlock(scene);

    if (!scene->source->context.private)
        init_hotkeys(scene, item, obs_source_get_name(source));

    signal_handler_connect(obs_source_get_signal_handler(source), "rename",
                   sceneitem_renamed, item);

    return item;

release_source_and_fail:
    obs_source_release(source);
    return NULL;
}

0 篇笔记 写笔记

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

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

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