Separate source activation for main/aux views

Split off activate to activate and show callbacks, and split off
deactivate to deactivate and hide callbacks.  Sources didn't previously
have a means to know whether it was actually being displayed in the main
view or just happened to be visible somewhere.  Now, for things like
transition sources, they have a means of knowing when they have actually
been "activated" so they can initiate their sequence.

A source is now only considered "active" when it's being displayed by
the main view.  When a source is shown in the main view, the activate
callback/signal is triggered.  When it's no longer being displayed by
the main view, deactivate callback/signal is triggered.

When a source is just generally visible to see by any view, the show
callback/signal is triggered.  If it's no longer visible by any views,
then the hide callback/signal is triggered.

Presentation volume will now only be active when a source is active in
the main view rather than also in auxilary views.

Also fix a potential bug where parents wouldn't properly increment or
decrement all the activation references of a child source when a child
was added or removed.
master
jp9000 2014-02-23 17:46:00 -07:00
parent c232ebde15
commit 60e6316a5e
6 changed files with 99 additions and 47 deletions

View File

@ -185,6 +185,9 @@ struct obs_source {
signal_handler_t signals; signal_handler_t signals;
proc_handler_t procs; proc_handler_t procs;
/* ensures show/hide are only called once */
int show_refs;
/* ensures activate/deactivate are only called once */ /* ensures activate/deactivate are only called once */
int activate_refs; int activate_refs;
@ -241,8 +244,13 @@ bool obs_source_init_handlers(struct obs_source *source);
extern bool obs_source_init(struct obs_source *source, extern bool obs_source_init(struct obs_source *source,
const struct obs_source_info *info); const struct obs_source_info *info);
extern void obs_source_activate(obs_source_t source); enum view_type {
extern void obs_source_deactivate(obs_source_t source); MAIN_VIEW,
AUX_VIEW
};
extern void obs_source_activate(obs_source_t source, enum view_type type);
extern void obs_source_deactivate(obs_source_t source, enum view_type type);
extern void obs_source_video_tick(obs_source_t source, float seconds); extern void obs_source_video_tick(obs_source_t source, float seconds);

View File

@ -123,13 +123,16 @@ bool obs_source_init(struct obs_source *source,
} }
static inline void obs_source_dosignal(struct obs_source *source, static inline void obs_source_dosignal(struct obs_source *source,
const char *signal) const char *signal_obs, const char *signal_source)
{ {
struct calldata data; struct calldata data;
calldata_init(&data); calldata_init(&data);
calldata_setptr(&data, "source", source); calldata_setptr(&data, "source", source);
signal_handler_signal(obs->signals, signal, &data); if (signal_obs)
signal_handler_signal(obs->signals, signal_obs, &data);
if (signal_source)
signal_handler_signal(source->signals, signal_source, &data);
calldata_free(&data); calldata_free(&data);
} }
@ -159,7 +162,7 @@ obs_source_t obs_source_create(enum obs_source_type type, const char *id,
if (!obs_source_init(source, info)) if (!obs_source_init(source, info))
goto fail; goto fail;
obs_source_dosignal(source, "source-create"); obs_source_dosignal(source, "source-create", NULL);
return source; return source;
fail: fail:
@ -187,7 +190,7 @@ static void obs_source_destroy(struct obs_source *source)
{ {
size_t i; size_t i;
obs_source_dosignal(source, "source-destroy"); obs_source_dosignal(source, "source-destroy", "destroy");
if (source->filter_parent) if (source->filter_parent)
obs_source_filter_remove(source->filter_parent, source); obs_source_filter_remove(source->filter_parent, source);
@ -243,7 +246,6 @@ void obs_source_release(obs_source_t source)
void obs_source_remove(obs_source_t source) void obs_source_remove(obs_source_t source)
{ {
struct obs_core_data *data = &obs->data; struct obs_core_data *data = &obs->data;
struct calldata cd = {0};
size_t id; size_t id;
pthread_mutex_lock(&data->sources_mutex); pthread_mutex_lock(&data->sources_mutex);
@ -263,11 +265,7 @@ void obs_source_remove(obs_source_t source)
pthread_mutex_unlock(&data->sources_mutex); pthread_mutex_unlock(&data->sources_mutex);
calldata_setptr(&cd, "source", source); obs_source_dosignal(source, "source-remove", "remove");
signal_handler_signal(obs->signals, "source-remove", &cd);
signal_handler_signal(source->signals, "remove", &cd);
calldata_free(&cd);
obs_source_release(source); obs_source_release(source);
} }
@ -300,28 +298,30 @@ void obs_source_update(obs_source_t source, obs_data_t settings)
static void activate_source(obs_source_t source) static void activate_source(obs_source_t source)
{ {
struct calldata data = {0};
if (source->info.activate) if (source->info.activate)
source->info.activate(source->data); source->info.activate(source->data);
obs_source_dosignal(source, "source-activate", "activate");
calldata_setptr(&data, "source", source);
signal_handler_signal(obs->signals, "source-activate", &data);
signal_handler_signal(source->signals, "activate", &data);
calldata_free(&data);
} }
static void deactivate_source(obs_source_t source) static void deactivate_source(obs_source_t source)
{ {
struct calldata data = {0};
if (source->info.deactivate) if (source->info.deactivate)
source->info.deactivate(source->data); source->info.deactivate(source->data);
obs_source_dosignal(source, "source-deactivate", "deactivate");
}
calldata_setptr(&data, "source", source); static void show_source(obs_source_t source)
signal_handler_signal(obs->signals, "source-deactivate", &data); {
signal_handler_signal(source->signals, "deactivate", &data); if (source->info.show)
calldata_free(&data); source->info.show(source->data);
obs_source_dosignal(source, "source-show", "show");
}
static void hide_source(obs_source_t source)
{
if (source->info.hide)
source->info.hide(source->data);
obs_source_dosignal(source, "source-hide", "hide");
} }
static void activate_tree(obs_source_t parent, obs_source_t child, void *param) static void activate_tree(obs_source_t parent, obs_source_t child, void *param)
@ -343,25 +343,57 @@ static void deactivate_tree(obs_source_t parent, obs_source_t child,
UNUSED_PARAMETER(param); UNUSED_PARAMETER(param);
} }
void obs_source_activate(obs_source_t source) static void show_tree(obs_source_t parent, obs_source_t child, void *param)
{
if (++child->show_refs == 1)
show_source(child);
UNUSED_PARAMETER(parent);
UNUSED_PARAMETER(param);
}
static void hide_tree(obs_source_t parent, obs_source_t child, void *param)
{
if (--child->show_refs == 0)
hide_source(child);
UNUSED_PARAMETER(parent);
UNUSED_PARAMETER(param);
}
void obs_source_activate(obs_source_t source, enum view_type type)
{ {
if (!source) return; if (!source) return;
if (++source->activate_refs == 1) { if (++source->show_refs == 1) {
activate_source(source); show_source(source);
obs_source_enum_tree(source, activate_tree, NULL); obs_source_enum_tree(source, show_tree, NULL);
obs_source_set_present_volume(source, 1.0f); }
if (type == MAIN_VIEW) {
if (++source->activate_refs == 1) {
activate_source(source);
obs_source_enum_tree(source, activate_tree, NULL);
obs_source_set_present_volume(source, 1.0f);
}
} }
} }
void obs_source_deactivate(obs_source_t source) void obs_source_deactivate(obs_source_t source, enum view_type type)
{ {
if (!source) return; if (!source) return;
if (--source->activate_refs == 0) { if (--source->show_refs == 0) {
deactivate_source(source); hide_source(source);
obs_source_enum_tree(source, deactivate_tree, NULL); obs_source_enum_tree(source, hide_tree, NULL);
obs_source_set_present_volume(source, 0.0f); }
if (type == MAIN_VIEW) {
if (--source->activate_refs == 0) {
deactivate_source(source);
obs_source_enum_tree(source, deactivate_tree, NULL);
obs_source_set_present_volume(source, 0.0f);
}
} }
} }
@ -1311,16 +1343,22 @@ void obs_source_add_child(obs_source_t parent, obs_source_t child)
{ {
if (!parent || !child) return; if (!parent || !child) return;
if (parent->activate_refs > 0) for (int i = 0; i < parent->show_refs; i++) {
obs_source_activate(child); enum view_type type;
type = (i < parent->activate_refs) ? MAIN_VIEW : AUX_VIEW;
obs_source_activate(child, type);
}
} }
void obs_source_remove_child(obs_source_t parent, obs_source_t child) void obs_source_remove_child(obs_source_t parent, obs_source_t child)
{ {
if (!parent || !child) return; if (!parent || !child) return;
if (parent->activate_refs > 0) for (int i = 0; i < parent->show_refs; i++) {
obs_source_deactivate(child); enum view_type type;
type = (i < parent->activate_refs) ? MAIN_VIEW : AUX_VIEW;
obs_source_deactivate(child, type);
}
} }
static void reset_transition_vol(obs_source_t parent, obs_source_t child, static void reset_transition_vol(obs_source_t parent, obs_source_t child,

View File

@ -151,15 +151,21 @@ struct obs_source_info {
*/ */
void (*update)(void *data, obs_data_t settings); void (*update)(void *data, obs_data_t settings);
/** Called when the source has been activated */ /** Called when the source has been activated in the main view */
void (*activate)(void *data); void (*activate)(void *data);
/** /**
* Called when the source has been deactivated (no longer being * Called when the source has been deactivated from the main view
* played/displayed) * (no longer being played/displayed)
*/ */
void (*deactivate)(void *data); void (*deactivate)(void *data);
/** Called when the source is visible */
void (*show)(void *data);
/** Called when the source is no longer visible */
void (*hide)(void *data);
/** /**
* Called each video frame with the time elapsed * Called each video frame with the time elapsed
* *

View File

@ -95,11 +95,11 @@ void obs_view_setsource(obs_view_t view, uint32_t channel,
if (source) { if (source) {
obs_source_addref(source); obs_source_addref(source);
obs_source_activate(source); obs_source_activate(source, AUX_VIEW);
} }
if (prev_source) { if (prev_source) {
obs_source_deactivate(prev_source); obs_source_deactivate(prev_source, AUX_VIEW);
obs_source_release(prev_source); obs_source_release(prev_source);
} }

View File

@ -707,11 +707,11 @@ void obs_set_output_source(uint32_t channel, obs_source_t source)
if (source) { if (source) {
obs_source_addref(source); obs_source_addref(source);
obs_source_activate(source); obs_source_activate(source, MAIN_VIEW);
} }
if (prev_source) { if (prev_source) {
obs_source_deactivate(prev_source); obs_source_deactivate(prev_source, MAIN_VIEW);
obs_source_release(prev_source); obs_source_release(prev_source);
} }

View File

@ -77,7 +77,7 @@
<item> <item>
<widget class="QStackedWidget" name="settingsPages"> <widget class="QStackedWidget" name="settingsPages">
<property name="currentIndex"> <property name="currentIndex">
<number>2</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="generalPage"> <widget class="QWidget" name="generalPage">
<layout class="QFormLayout" name="formLayout_2"> <layout class="QFormLayout" name="formLayout_2">