diff --git a/src/modules/module-remap-sink.c b/src/modules/module-remap-sink.c index 2822a7f..0c216d4 100644 --- a/src/modules/module-remap-sink.c +++ b/src/modules/module-remap-sink.c @@ -291,7 +291,7 @@ static pa_bool_t sink_input_may_move_to_cb(pa_sink_input *i, pa_sink *dest) { pa_sink_input_assert_ref(i); pa_assert_se(u = i->userdata); - return u->sink != dest; + return (u->sink != dest) && pa_sink_check_loop(dest, u->module); } /* Called from main context */ diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 2d214cf..9c7e2bb 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -1456,6 +1456,17 @@ pa_sink *pa_sink_get_master(pa_sink *s) { return s; } +/* Called from the main thread */ +/* Checks if "dest" is loaded by another instance of "m". This is meant to be + * used by filter modules to verify that they are not causing a loop. */ +pa_bool_t pa_sink_check_loop(pa_sink *dest, pa_module *m) { + pa_assert(dest->module); + pa_assert(dest->module->name); + pa_assert(m->name); + + return pa_streq(dest->module->name, m->name); +} + /* Called from main context */ pa_bool_t pa_sink_is_passthrough(pa_sink *s) { pa_sink_input *alt_i; diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 56fa735..812105f 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -421,6 +421,8 @@ pa_bool_t pa_sink_flat_volume_enabled(pa_sink *s); /* Get the master sink when sharing volumes */ pa_sink *pa_sink_get_master(pa_sink *s); +/* Make sure sink dest isn't loaded by an instance of module m */ +pa_bool_t pa_sink_check_loop(pa_sink *dest, pa_module *m); /* Is the sink in passthrough mode? (that is, is there a passthrough sink input * connected to this sink? */