Browse Source

Add functions to enumerate source children/tree

jp9000 11 years ago
parent
commit
14c95ac421
5 changed files with 109 additions and 0 deletions
  1. 3 0
      libobs/obs-internal.h
  2. 24 0
      libobs/obs-scene.c
  3. 57 0
      libobs/obs-source.c
  4. 15 0
      libobs/obs-source.h
  5. 10 0
      libobs/obs.h

+ 3 - 0
libobs/obs-internal.h

@@ -186,6 +186,9 @@ struct obs_source {
 	signal_handler_t                signals;
 	proc_handler_t                  procs;
 
+	/* prevents infinite recursion when enumerating sources */
+	int                             enum_refs;
+
 	/* used to indicate that the source has been removed and all
 	 * references to it should be released (not exactly how I would prefer
 	 * to handle things but it's the best option) */

+ 24 - 0
libobs/obs-scene.c

@@ -82,6 +82,29 @@ static void scene_destroy(void *data)
 	bfree(scene);
 }
 
+static void scene_enum_sources(void *data,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	struct obs_scene *scene = data;
+	struct obs_scene_item *item;
+
+	pthread_mutex_lock(&scene->mutex);
+
+	item = scene->first_item;
+	while (item) {
+		struct obs_scene_item *next = item->next;
+
+		obs_sceneitem_addref(item);
+		enum_callback(scene->source, item->source, param);
+		obs_sceneitem_release(item);
+
+		item = next;
+	}
+
+	pthread_mutex_unlock(&scene->mutex);
+}
+
 static inline void detach_sceneitem(struct obs_scene_item *item)
 {
 	if (item->prev)
@@ -170,6 +193,7 @@ static const struct obs_source_info scene_info =
 	.video_render = scene_video_render,
 	.getwidth     = scene_getwidth,
 	.getheight    = scene_getheight,
+	.enum_sources = scene_enum_sources
 };
 
 obs_scene_t obs_scene_create(const char *name)

+ 57 - 0
libobs/obs-source.c

@@ -1162,3 +1162,60 @@ int64_t obs_source_get_sync_offset(obs_source_t source)
 {
 	return source ? source->sync_offset : 0;
 }
+
+struct source_enum_data {
+	obs_source_enum_proc_t enum_callback;
+	void *param;
+};
+
+static void enum_source_tree_callback(obs_source_t parent, obs_source_t child,
+		void *param)
+{
+	struct source_enum_data *data = param;
+
+	if (child->info.enum_sources && !child->enum_refs) {
+		child->enum_refs++;
+
+		child->info.enum_sources(child->data,
+				enum_source_tree_callback, data);
+
+		child->enum_refs--;
+	}
+
+	data->enum_callback(parent, child, data->param);
+}
+
+void obs_source_enum_sources(obs_source_t source,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	if (!source || !source->info.enum_sources || source->enum_refs)
+		return;
+
+	obs_source_addref(source);
+
+	source->enum_refs++;
+	source->info.enum_sources(source->data, enum_callback, param);
+	source->enum_refs--;
+
+	obs_source_release(source);
+}
+
+void obs_source_enum_tree(obs_source_t source,
+		obs_source_enum_proc_t enum_callback,
+		void *param)
+{
+	struct source_enum_data data = {enum_callback, param};
+
+	if (!source || !source->info.enum_sources || source->enum_refs)
+		return;
+
+	obs_source_addref(source);
+
+	source->enum_refs++;
+	source->info.enum_sources(source->data, enum_source_tree_callback,
+			&data);
+	source->enum_refs--;
+
+	obs_source_release(source);
+}

+ 15 - 0
libobs/obs-source.h

@@ -87,6 +87,9 @@ enum obs_source_type {
 
 /** @} */
 
+typedef void (*obs_source_enum_proc_t)(obs_source_t parent, obs_source_t child,
+		void *param);
+
 /**
  * Source definition structure
  */
@@ -226,6 +229,18 @@ struct obs_source_info {
 	 */
 	struct filtered_audio *(*filter_audio)(void *data,
 			struct filtered_audio *audio);
+
+	/**
+	 * Called to enumerate all sources being used within this source.
+	 * If the source has children it must implement this callback.
+	 *
+	 * @param  data           Source data
+	 * @param  enum_callback  Enumeration callback
+	 * @param  param          User data to pass to callback
+	 */
+	void (*enum_sources)(void *data,
+			obs_source_enum_proc_t enum_callback,
+			void *param);
 };
 
 /**

+ 10 - 0
libobs/obs.h

@@ -510,6 +510,16 @@ EXPORT void obs_source_set_sync_offset(obs_source_t source, int64_t offset);
 /** Gets the audio sync offset (in nanoseconds) for a source */
 EXPORT int64_t obs_source_get_sync_offset(obs_source_t source);
 
+/** Enumerates child sources used by this source */
+EXPORT void obs_source_enum_sources(obs_source_t source,
+		obs_source_enum_proc_t enum_callback,
+		void *param);
+
+/** Enumerates the entire child source tree used by this source */
+EXPORT void obs_source_enum_tree(obs_source_t source,
+		obs_source_enum_proc_t enum_callback,
+		void *param);
+
 /* ------------------------------------------------------------------------- */
 /* Functions used by sources */