Ver código fonte

libobs: Implement composite sources (skip)

(Note: This commit breaks libobs compilation.  Skip if bisecting)

Adds a "composite" source type which is used for sources that composite
one or more sub-sources.  The audio_render callback is called for
composite sources to allow those types of sources to do custom
processing of the audio of its sub-sources.
jp9000 9 anos atrás
pai
commit
ddfd89a673
4 arquivos alterados com 58 adições e 6 exclusões
  1. 4 2
      libobs/obs-internal.h
  2. 25 0
      libobs/obs-module.c
  3. 14 4
      libobs/obs-source.c
  4. 15 0
      libobs/obs-source.h

+ 4 - 2
libobs/obs-internal.h

@@ -498,6 +498,7 @@ struct obs_source {
 
 	/* audio */
 	bool                            audio_failed;
+	bool                            audio_pending;
 	bool                            muted;
 	struct obs_source               *next_audio_source;
 	struct obs_source               **prev_next_audio_source;
@@ -567,8 +568,6 @@ extern const struct obs_source_info *find_source(struct darray *list,
 extern bool obs_source_init_context(struct obs_source *source,
 		obs_data_t *settings, const char *name,
 		obs_data_t *hotkey_data);
-extern bool obs_source_init(struct obs_source *source,
-		const struct obs_source_info *info);
 
 extern void obs_source_save(obs_source_t *source);
 extern void obs_source_load(obs_source_t *source);
@@ -586,6 +585,9 @@ extern void obs_source_video_tick(obs_source_t *source, float seconds);
 extern float obs_source_get_target_volume(obs_source_t *source,
 		obs_source_t *target);
 
+extern void obs_source_audio_render(obs_source_t *source, uint32_t mixers,
+		size_t channels, size_t sample_rate, size_t size);
+
 
 /* ------------------------------------------------------------------------- */
 /* outputs  */

+ 25 - 0
libobs/obs-module.c

@@ -546,6 +546,27 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size)
 		goto error;
 	}
 
+	memcpy(&data, info, size);
+
+	/* mark audio-only filters as an async filter categorically */
+	if (data.type == OBS_SOURCE_TYPE_FILTER) {
+		if ((data.output_flags & OBS_SOURCE_VIDEO) == 0)
+			data.output_flags |= OBS_SOURCE_ASYNC;
+	}
+
+	if ((data.output_flags & OBS_SOURCE_COMPOSITE) != 0) {
+		if ((data.output_flags & OBS_SOURCE_AUDIO) != 0) {
+			blog(LOG_WARNING, "Source '%s': Composite sources "
+					"cannot be audio sources", info->id);
+			goto error;
+		}
+		if ((data.output_flags & OBS_SOURCE_ASYNC) != 0) {
+			blog(LOG_WARNING, "Source '%s': Composite sources "
+					"cannot be async sources", info->id);
+			goto error;
+		}
+	}
+
 #define CHECK_REQUIRED_VAL_(info, val, func) \
 	CHECK_REQUIRED_VAL(struct obs_source_info, info, val, func)
 	CHECK_REQUIRED_VAL_(info, get_name, obs_register_source);
@@ -558,6 +579,10 @@ void obs_register_source_s(const struct obs_source_info *info, size_t size)
 		CHECK_REQUIRED_VAL_(info, get_width,  obs_register_source);
 		CHECK_REQUIRED_VAL_(info, get_height, obs_register_source);
 	}
+
+	if ((info->output_flags & OBS_SOURCE_COMPOSITE) != 0) {
+		CHECK_REQUIRED_VAL_(info, audio_render, obs_register_source);
+	}
 #undef CHECK_REQUIRED_VAL_
 
 	if (size > sizeof(data)) {

+ 14 - 4
libobs/obs-source.c

@@ -132,9 +132,18 @@ static void allocate_audio_output_buffer(struct obs_source *source)
 	}
 }
 
+static inline bool is_audio_source(const struct obs_source *source)
+{
+	return source->info.output_flags & OBS_SOURCE_AUDIO;
+}
+
+static inline bool is_composite_source(const struct obs_source *source)
+{
+	return source->info.output_flags & OBS_SOURCE_COMPOSITE;
+}
+
 /* internal initialization */
-bool obs_source_init(struct obs_source *source,
-		const struct obs_source_info *info)
+bool obs_source_init(struct obs_source *source)
 {
 	pthread_mutexattr_t attr;
 
@@ -158,9 +167,10 @@ bool obs_source_init(struct obs_source *source,
 	if (pthread_mutex_init(&source->async_mutex, NULL) != 0)
 		return false;
 
-	if (info && info->output_flags & OBS_SOURCE_AUDIO) {
+	if (is_audio_source(source) || is_composite_source(source))
 		allocate_audio_output_buffer(source);
 
+	if (is_audio_source(source)) {
 		pthread_mutex_lock(&obs->data.audio_sources_mutex);
 
 		source->next_audio_source = obs->data.first_audio_source;
@@ -303,7 +313,7 @@ obs_source_t *obs_source_create(enum obs_source_type type, const char *id,
 	if (info && info->get_defaults)
 		info->get_defaults(source->context.settings);
 
-	if (!obs_source_init(source, info))
+	if (!obs_source_init(source))
 		goto fail;
 
 	obs_source_init_audio_hotkeys(source);

+ 15 - 0
libobs/obs-source.h

@@ -103,6 +103,17 @@ enum obs_source_type {
  */
 #define OBS_SOURCE_INTERACTION (1<<5)
 
+/**
+ * Source composites sub-sources
+ *
+ * When used specifies that the source composites one or more sub-sources.
+ * Sources that render sub-sources must implement the audio_render callback
+ * in order to perform custom mixing of sub-sources.
+ *
+ * This capability flag is always set for transitions.
+ */
+#define OBS_SOURCE_COMPOSITE (1<<6)
+
 /** @} */
 
 typedef void (*obs_source_enum_proc_t)(obs_source_t *parent,
@@ -388,6 +399,10 @@ struct obs_source_info {
 	 * If defined, called to free private data on shutdown
 	 */
 	void (*free_type_data)(void *type_data);
+
+	bool (*audio_render)(void *data, uint64_t *ts_out,
+			struct obs_source_audio_mix *audio_output,
+			uint32_t mixers, size_t channels, size_t sample_rate);
 };
 
 EXPORT void obs_register_source_s(const struct obs_source_info *info,