From bf1b3bb157e6140ca094f720350d9361d1a81642 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Apr 2023 16:12:35 +0200 Subject: [PATCH] audioconvert: handle recursive Props set_param When the node receives a set_param Props, it calls the follower set_param implementation. If that one calls set_param again on the adapter, discards the original set_param. This makes it possible for the follower to intercept the Props param and set a modified version on the converter. This can be used to intercept volume changes. --- spa/plugins/audioconvert/audioadapter.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spa/plugins/audioconvert/audioadapter.c b/spa/plugins/audioconvert/audioadapter.c index 90d583b8c..b96a3ac24 100644 --- a/spa/plugins/audioconvert/audioadapter.c +++ b/spa/plugins/audioconvert/audioadapter.c @@ -51,6 +51,7 @@ struct impl { uint64_t follower_flags; struct spa_audio_info follower_current_format; struct spa_audio_info default_format; + int in_set_param; struct spa_handle *hnd_convert; struct spa_node *convert; @@ -675,13 +676,16 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags, } case SPA_PARAM_Props: - if (this->target != this->follower) - res = spa_node_set_param(this->target, id, flags, param); - res2 = spa_node_set_param(this->follower, id, flags, param); + { + int in_set_param = ++this->in_set_param; + res = spa_node_set_param(this->follower, id, flags, param); + if (this->target != this->follower && this->in_set_param == in_set_param) + res2 = spa_node_set_param(this->target, id, flags, param); if (res < 0 && res2 < 0) return res; res = 0; break; + } case SPA_PARAM_ProcessLatency: res = spa_node_set_param(this->follower, id, flags, param); break;