diff --git a/libobs/obs-source.c b/libobs/obs-source.c index f435bd4a627b8be321b3ce42666e26de95f8ee71..d5c22193c0e28d76a92d56204b3c39888ff7b195 100644 --- a/libobs/obs-source.c +++ b/libobs/obs-source.c @@ -2968,19 +2968,19 @@ struct source_enum_data { void *param; }; -static void enum_source_tree_callback(obs_source_t *parent, obs_source_t *child, - void *param) +static void enum_source_active_tree_callback(obs_source_t *parent, + obs_source_t *child, void *param) { struct source_enum_data *data = param; bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION; if (is_transition) obs_transition_enum_sources(child, - enum_source_tree_callback, param); + enum_source_active_tree_callback, param); if (child->info.enum_active_sources) { if (child->context.data) { child->info.enum_active_sources(child->context.data, - enum_source_tree_callback, data); + enum_source_active_tree_callback, data); } } @@ -3027,11 +3027,67 @@ void obs_source_enum_active_tree(obs_source_t *source, obs_source_addref(source); if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) - obs_transition_enum_sources(source, enum_source_tree_callback, - &data); + obs_transition_enum_sources(source, + enum_source_active_tree_callback, &data); if (source->info.enum_active_sources) source->info.enum_active_sources(source->context.data, - enum_source_tree_callback, &data); + enum_source_active_tree_callback, &data); + + obs_source_release(source); +} + +static void enum_source_full_tree_callback(obs_source_t *parent, + obs_source_t *child, void *param) +{ + struct source_enum_data *data = param; + bool is_transition = child->info.type == OBS_SOURCE_TYPE_TRANSITION; + + if (is_transition) + obs_transition_enum_sources(child, + enum_source_full_tree_callback, param); + if (child->info.enum_all_sources) { + if (child->context.data) { + child->info.enum_active_sources(child->context.data, + enum_source_full_tree_callback, data); + } + } else if (child->info.enum_active_sources) { + if (child->context.data) { + child->info.enum_active_sources(child->context.data, + enum_source_full_tree_callback, data); + } + } + + data->enum_callback(parent, child, data->param); +} + +static void obs_source_enum_full_tree(obs_source_t *source, + obs_source_enum_proc_t enum_callback, + void *param) +{ + struct source_enum_data data = {enum_callback, param}; + bool is_transition; + + if (!data_valid(source, "obs_source_enum_active_tree")) + return; + + is_transition = source->info.type == OBS_SOURCE_TYPE_TRANSITION; + if (!is_transition && !source->info.enum_active_sources) + return; + + obs_source_addref(source); + + if (source->info.type == OBS_SOURCE_TYPE_TRANSITION) + obs_transition_enum_sources(source, + enum_source_full_tree_callback, &data); + + if (source->info.enum_all_sources) { + source->info.enum_all_sources(source->context.data, + enum_source_full_tree_callback, &data); + + } else if (source->info.enum_active_sources) { + source->info.enum_active_sources(source->context.data, + enum_source_full_tree_callback, &data); + } obs_source_release(source); } diff --git a/libobs/obs-source.h b/libobs/obs-source.h index 42efaccf2f849226bcec659c0e8fa0db05a713f3..dfd4a76ec0dda9dc97ecf979b41c1fc65addd4e6 100644 --- a/libobs/obs-source.h +++ b/libobs/obs-source.h @@ -400,6 +400,21 @@ struct obs_source_info { 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); + + /** + * Called to enumerate all active and inactive sources being used + * within this source. If this callback isn't implemented, + * enum_active_sources will be called instead. + * + * This is typically used if a source can have inactive child sources. + * + * @param data Filter data + * @param enum_callback Enumeration callback + * @param param User data to pass to callback + */ + void (*enum_all_sources)(void *data, + obs_source_enum_proc_t enum_callback, + void *param); }; EXPORT void obs_register_source_s(const struct obs_source_info *info,