Skip to content

Commit

Permalink
Feature: allowing scenes to be added to backstage (#550)
Browse files Browse the repository at this point in the history
  • Loading branch information
avoitenko-logitech authored Nov 1, 2023
1 parent fd0c838 commit 9a747cf
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
1 change: 1 addition & 0 deletions libobs/obs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ struct obs_core_data {
struct obs_view main_view;
struct obs_view stream_view;
struct obs_view record_view;
struct obs_view backstage_view;

long long unnamed_index;

Expand Down
92 changes: 92 additions & 0 deletions libobs/obs.c
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,9 @@ static int obs_init_video()

if (!obs_record_view_add(&obs->data.record_view, ovi))
return OBS_VIDEO_FAIL;

if (!obs_record_view_add(&obs->data.backstage_view, ovi))
return OBS_VIDEO_FAIL;
}

int errorcode;
Expand Down Expand Up @@ -965,6 +968,8 @@ static bool obs_init_data(void)
goto fail;
if (!obs_view_init(&data->record_view))
goto fail;
if (!obs_view_init(&data->backstage_view))
goto fail;

data->private_data = obs_data_create();
data->valid = true;
Expand Down Expand Up @@ -1009,6 +1014,8 @@ static void obs_free_data(void)
obs_main_view_free(&data->stream_view);
obs_view_remove(&data->record_view);
obs_main_view_free(&data->record_view);
obs_view_remove(&data->backstage_view);
obs_main_view_free(&data->backstage_view);

blog(LOG_INFO, "Freeing OBS context data");

Expand Down Expand Up @@ -1968,6 +1975,91 @@ void *obs_create_ui(const char *name, const char *task, const char *target,
return callback ? callback->create(data, ui_data) : NULL;
}

void obs_add_scene_to_backstage(obs_source_t *source)
{
if (!source) {
blog(LOG_WARNING,
"obs_add_scene_to_backstage - source is NULL");
return;
}

if (obs_source_get_type(source) != OBS_SOURCE_TYPE_SCENE) {
blog(LOG_WARNING,
"obs_add_scene_to_backstage - trying to add not a scene");
return;
}

struct obs_view *backstage_view = &obs->data.backstage_view;

pthread_mutex_lock(&backstage_view->channels_mutex);

size_t channel = MAX_CHANNELS;
for (size_t i = 0; i < MAX_CHANNELS; ++i) {
if (!backstage_view->channels[i]) {
channel = i;
break;
}
}

if (channel == MAX_CHANNELS) {
blog(LOG_WARNING,
"obs_add_scene_to_backstage - no free slots left for scenes");
pthread_mutex_unlock(&backstage_view->channels_mutex);
return;
}

source = obs_source_get_ref(source);
backstage_view->channels[channel] = source;

pthread_mutex_unlock(&backstage_view->channels_mutex);

if (source) {
obs_source_activate(source, MAIN_VIEW);
}
}

void obs_remove_scene_from_backstage(obs_source_t *source)
{
if (!source) {
blog(LOG_WARNING,
"obs_remove_scene_from_backstage - source is NULL");
return;
}

if (obs_source_get_type(source) != OBS_SOURCE_TYPE_SCENE) {
blog(LOG_WARNING,
"obs_remove_scene_from_backstage - trying to remove not a scene");
return;
}

blog(LOG_INFO, "obs_remove_scene_from_backstage - 0x%" PRIXPTR,
(uintptr_t)source);
struct obs_view *backstage_view = &obs->data.backstage_view;

pthread_mutex_lock(&backstage_view->channels_mutex);

obs_source_t *found_source = NULL;
for (size_t i = 0; i < MAX_CHANNELS; ++i) {
if (backstage_view->channels[i] == source) {
found_source = source;
backstage_view->channels[i] = NULL;
break;
}
}

if (!found_source) {
blog(LOG_WARNING,
"obs_remove_scene_from_backstage - scene not found on backstage");
pthread_mutex_unlock(&backstage_view->channels_mutex);
return;
}

pthread_mutex_unlock(&backstage_view->channels_mutex);

obs_source_deactivate(found_source, MAIN_VIEW);
obs_source_release(found_source);
}

obs_source_t *obs_get_output_source(uint32_t channel)
{
return obs_view_get_source(&obs->data.main_view, channel);
Expand Down
10 changes: 10 additions & 0 deletions libobs/obs.h
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,16 @@ EXPORT void obs_set_output_source(uint32_t channel, obs_source_t *source);
*/
EXPORT obs_source_t *obs_get_output_source(uint32_t channel);

/**
* Adds scene to backstage view. It stays active, but is not visible on stream or recording.
* The main use case is creation of various scene previews while user is able to change
* current active scene. Use obs_remove_scene_from_backstage to clear resources.
*/
EXPORT void obs_add_scene_to_backstage(obs_source_t *source);

/** Removes scene from backstage view. */
EXPORT void obs_remove_scene_from_backstage(obs_source_t *source);

/**
* Enumerates all input sources
*
Expand Down

0 comments on commit 9a747cf

Please sign in to comment.