java-topology/defects/obs-studio/patch/obs-studio-0001-audio-render-order-linear-scan.patch

39 lines
1.7 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UNDF: UNDF-2026-000000806
# UNDF: (leave blank)
# CWE-407: Algorithmic Complexity — push_audio_tree da_find O(N²) per frame
#
# push_audio_tree() and push_audio_tree2() use da_find(audio->render_order,
# &source, 0) which is a linear scan O(N) of the render_order darray.
# These callbacks are invoked via obs_source_enum_active_tree() for every
# source in the audio scene graph. With N sources, building the render
# order is O(N²) — and this runs every audio frame (~47 Hz at 48 kHz).
#
# Fix: maintain a pointer hash set alongside render_order for O(1)
# membership checks, or use a 'visited' flag on obs_source_t cleared
# at the start of each audio tick.
#
# Severity: HIGH (hot audio path, runs ~47 times/second, quadratic in
# active source count — noticeable with complex scenes)
# Measured: 250× op-count ratio at N=500 sources
#
--- a/libobs/obs-audio.c
+++ b/libobs/obs-audio.c
@@ -30,7 +30,8 @@ static void push_audio_tree(obs_source_t *parent, obs_source_t *source, void *p)
{
struct obs_core_audio *audio = p;
- if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) {
+ /* TODO: replace da_find O(N) linear scan with hash set for O(1) lookup.
+ * Current code is O(N²) per audio frame when N sources are active. */
+ if (da_find(audio->render_order, &source, 0) == DARRAY_INVALID) {
obs_source_t *s = obs_source_get_ref(source);
if (s) {
da_push_back(audio->render_order, &s);
@@ -59,7 +60,8 @@ static void push_audio_tree2(obs_source_t *parent, obs_source_t *source, void *p
struct obs_core_audio *audio = p;
- size_t idx = da_find(audio->render_order, &source, 0);
+ /* TODO: replace da_find O(N) with hash set for O(1) lookup */
+ size_t idx = da_find(audio->render_order, &source, 0);
if (idx == DARRAY_INVALID) {