mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-07-15 07:44:10 +00:00
(API Change) libobs: Add 'type' to obs_scene_duplicate
(Note: This commit also modifies the UI) Allows the ability to duplicate sources fully copied, and/or have the scene and its duplicates be private sources
This commit is contained in:
parent
6824910f5d
commit
a61933dd8e
|
@ -751,22 +751,91 @@ obs_scene_t *obs_scene_create_private(const char *name)
|
|||
return source->context.data;
|
||||
}
|
||||
|
||||
obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name)
|
||||
static obs_source_t *get_child_at_idx(obs_scene_t *scene, size_t idx)
|
||||
{
|
||||
struct obs_scene *new_scene = obs_scene_create(name);
|
||||
struct obs_scene_item *item = scene->first_item;
|
||||
|
||||
while (item && idx--)
|
||||
item = item->next;
|
||||
return item ? item->source : NULL;
|
||||
}
|
||||
|
||||
static inline obs_source_t *dup_child(struct darray *array, size_t idx,
|
||||
obs_scene_t *new_scene, bool private)
|
||||
{
|
||||
DARRAY(struct obs_scene_item*) old_items;
|
||||
obs_source_t *source;
|
||||
|
||||
old_items.da = *array;
|
||||
|
||||
source = old_items.array[idx]->source;
|
||||
|
||||
/* if the old item is referenced more than once in the old scene,
|
||||
* make sure they're referenced similarly in the new scene to reduce
|
||||
* load times */
|
||||
for (size_t i = 0; i < idx; i++) {
|
||||
struct obs_scene_item *item = old_items.array[i];
|
||||
if (item->source == source) {
|
||||
source = get_child_at_idx(new_scene, i);
|
||||
obs_source_addref(source);
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
return obs_source_duplicate(source, NULL, private);
|
||||
}
|
||||
|
||||
static inline obs_source_t *new_ref(obs_source_t *source)
|
||||
{
|
||||
obs_source_addref(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name,
|
||||
enum obs_scene_duplicate_type type)
|
||||
{
|
||||
bool make_unique = ((int)type & (1<<0)) != 0;
|
||||
bool make_private = ((int)type & (1<<1)) != 0;
|
||||
DARRAY(struct obs_scene_item*) items;
|
||||
struct obs_scene *new_scene;
|
||||
struct obs_scene_item *item;
|
||||
struct obs_source *source;
|
||||
|
||||
da_init(items);
|
||||
|
||||
if (!obs_ptr_valid(scene, "obs_scene_duplicate"))
|
||||
return NULL;
|
||||
|
||||
/* --------------------------------- */
|
||||
|
||||
full_lock(scene);
|
||||
|
||||
item = scene->first_item;
|
||||
while (item) {
|
||||
struct obs_source *source = item->source;
|
||||
da_push_back(items, &item);
|
||||
obs_sceneitem_addref(item);
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
full_unlock(scene);
|
||||
|
||||
/* --------------------------------- */
|
||||
|
||||
new_scene = make_private ?
|
||||
obs_scene_create_private(name) : obs_scene_create(name);
|
||||
|
||||
for (size_t i = 0; i < items.num; i++) {
|
||||
item = items.array[i];
|
||||
source = make_unique ?
|
||||
dup_child(&items.da, i, new_scene, make_private) :
|
||||
new_ref(item->source);
|
||||
|
||||
if (source) {
|
||||
struct obs_scene_item *new_item =
|
||||
obs_scene_add(new_scene, source);
|
||||
|
||||
if (!new_item) {
|
||||
item = item->next;
|
||||
obs_source_release(source);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -784,13 +853,15 @@ obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name)
|
|||
new_item->bounds_type = item->bounds_type;
|
||||
new_item->bounds_align = item->bounds_align;
|
||||
new_item->bounds = item->bounds;
|
||||
}
|
||||
|
||||
item = item->next;
|
||||
obs_source_release(source);
|
||||
}
|
||||
}
|
||||
|
||||
full_unlock(scene);
|
||||
for (size_t i = 0; i < items.num; i++)
|
||||
obs_sceneitem_release(items.array[i]);
|
||||
|
||||
da_free(items);
|
||||
return new_scene;
|
||||
}
|
||||
|
||||
|
|
13
libobs/obs.h
13
libobs/obs.h
|
@ -1084,13 +1084,18 @@ EXPORT obs_scene_t *obs_scene_create(const char *name);
|
|||
|
||||
EXPORT obs_scene_t *obs_scene_create_private(const char *name);
|
||||
|
||||
enum obs_scene_duplicate_type {
|
||||
OBS_SCENE_DUP_REFS, /**< Source refs only */
|
||||
OBS_SCENE_DUP_COPY, /**< Fully duplicate */
|
||||
OBS_SCENE_DUP_PRIVATE_REFS, /**< Source refs only (as private) */
|
||||
OBS_SCENE_DUP_PRIVATE_COPY /**< Fully duplicate (as private) */
|
||||
};
|
||||
|
||||
/**
|
||||
* Duplicates a scene.
|
||||
*
|
||||
* Sources in a scene will not be recreated; it will contain references to
|
||||
* the same sources as the originating scene.
|
||||
*/
|
||||
EXPORT obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name);
|
||||
EXPORT obs_scene_t *obs_scene_duplicate(obs_scene_t *scene, const char *name,
|
||||
enum obs_scene_duplicate_type type);
|
||||
|
||||
EXPORT void obs_scene_addref(obs_scene_t *scene);
|
||||
EXPORT void obs_scene_release(obs_scene_t *scene);
|
||||
|
|
|
@ -1769,7 +1769,7 @@ void OBSBasic::DuplicateSelectedScene()
|
|||
}
|
||||
|
||||
obs_scene_t *scene = obs_scene_duplicate(curScene,
|
||||
name.c_str());
|
||||
name.c_str(), OBS_SCENE_DUP_REFS);
|
||||
source = obs_scene_get_source(scene);
|
||||
obs_scene_release(scene);
|
||||
|
||||
|
|
Loading…
Reference in a new issue