Pārlūkot izejas kodu

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.
jp9000 11 gadi atpakaļ
vecāks
revīzija
60e6316a5e
6 mainītis faili ar 99 papildinājumiem un 47 dzēšanām
  1. 10 2
      libobs/obs-internal.h
  2. 75 37
      libobs/obs-source.c
  3. 9 3
      libobs/obs-source.h
  4. 2 2
      libobs/obs-view.c
  5. 2 2
      libobs/obs.c
  6. 1 1
      obs/forms/OBSBasicSettings.ui

+ 10 - 2
libobs/obs-internal.h

@@ -185,6 +185,9 @@ struct obs_source {
 	signal_handler_t                signals;
 	proc_handler_t                  procs;
 
+	/* ensures show/hide are only called once */
+	int                             show_refs;
+
 	/* ensures activate/deactivate are only called once */
 	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,
 		const struct obs_source_info *info);
 
-extern void obs_source_activate(obs_source_t source);
-extern void obs_source_deactivate(obs_source_t source);
+enum view_type {
+	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);
 
 

+ 75 - 37
libobs/obs-source.c

@@ -123,13 +123,16 @@ bool obs_source_init(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;
 
 	calldata_init(&data);
 	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);
 }
 
@@ -159,7 +162,7 @@ obs_source_t obs_source_create(enum obs_source_type type, const char *id,
 	if (!obs_source_init(source, info))
 		goto fail;
 
-	obs_source_dosignal(source, "source-create");
+	obs_source_dosignal(source, "source-create", NULL);
 	return source;
 
 fail:
@@ -187,7 +190,7 @@ static void obs_source_destroy(struct obs_source *source)
 {
 	size_t i;
 
-	obs_source_dosignal(source, "source-destroy");
+	obs_source_dosignal(source, "source-destroy", "destroy");
 
 	if (source->filter_parent)
 		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)
 {
 	struct obs_core_data *data = &obs->data;
-	struct calldata cd = {0};
 	size_t id;
 
 	pthread_mutex_lock(&data->sources_mutex);
@@ -263,11 +265,7 @@ void obs_source_remove(obs_source_t source)
 
 	pthread_mutex_unlock(&data->sources_mutex);
 
-	calldata_setptr(&cd, "source", source);
-	signal_handler_signal(obs->signals, "source-remove", &cd);
-	signal_handler_signal(source->signals, "remove", &cd);
-	calldata_free(&cd);
-
+	obs_source_dosignal(source, "source-remove", "remove");
 	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)
 {
-	struct calldata data = {0};
-
 	if (source->info.activate)
 		source->info.activate(source->data);
-
-	calldata_setptr(&data, "source", source);
-	signal_handler_signal(obs->signals, "source-activate", &data);
-	signal_handler_signal(source->signals, "activate", &data);
-	calldata_free(&data);
+	obs_source_dosignal(source, "source-activate", "activate");
 }
 
 static void deactivate_source(obs_source_t source)
 {
-	struct calldata data = {0};
-
 	if (source->info.deactivate)
 		source->info.deactivate(source->data);
+	obs_source_dosignal(source, "source-deactivate", "deactivate");
+}
 
-	calldata_setptr(&data, "source", source);
-	signal_handler_signal(obs->signals, "source-deactivate", &data);
-	signal_handler_signal(source->signals, "deactivate", &data);
-	calldata_free(&data);
+static void show_source(obs_source_t source)
+{
+	if (source->info.show)
+		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)
@@ -343,25 +343,57 @@ static void deactivate_tree(obs_source_t parent, obs_source_t child,
 	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->activate_refs == 1) {
-		activate_source(source);
-		obs_source_enum_tree(source, activate_tree, NULL);
-		obs_source_set_present_volume(source, 1.0f);
+	if (++source->show_refs == 1) {
+		show_source(source);
+		obs_source_enum_tree(source, show_tree, NULL);
+	}
+
+	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->activate_refs == 0) {
-		deactivate_source(source);
-		obs_source_enum_tree(source, deactivate_tree, NULL);
-		obs_source_set_present_volume(source, 0.0f);
+	if (--source->show_refs == 0) {
+		hide_source(source);
+		obs_source_enum_tree(source, hide_tree, NULL);
+	}
+
+	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->activate_refs > 0)
-		obs_source_activate(child);
+	for (int i = 0; i < parent->show_refs; i++) {
+		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)
 {
 	if (!parent || !child) return;
 
-	if (parent->activate_refs > 0)
-		obs_source_deactivate(child);
+	for (int i = 0; i < parent->show_refs; i++) {
+		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,

+ 9 - 3
libobs/obs-source.h

@@ -151,15 +151,21 @@ struct obs_source_info {
 	 */
 	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);
 
 	/**
-	 * Called when the source has been deactivated (no longer being
-	 * played/displayed)
+	 * Called when the source has been deactivated from the main view
+	 * (no longer being played/displayed)
 	 */
 	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
 	 *

+ 2 - 2
libobs/obs-view.c

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

+ 2 - 2
libobs/obs.c

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

+ 1 - 1
obs/forms/OBSBasicSettings.ui

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