23.02.2014 23:47, Tanu Kaskinen wrote: > Some people want module-rtp-send to send silence when the sink that is > monitored goes idle, and some people want module-rtp-send to pause the > RTP stream to avoid unnecessary bandwidth consumption. > --- > src/modules/rtp/module-rtp-send.c | 63 ++++++++++++++++++++++++++++++++++++++- > 1 file changed, 62 insertions(+), 1 deletion(-) Again, I have not tested this. But the logic looks right. > diff --git a/src/modules/rtp/module-rtp-send.c b/src/modules/rtp/module-rtp-send.c > index 454e781..a2bc395 100644 > --- a/src/modules/rtp/module-rtp-send.c > +++ b/src/modules/rtp/module-rtp-send.c > @@ -68,7 +68,8 @@ PA_MODULE_USAGE( > "port=<port number> " > "mtu=<maximum transfer unit> " > "loop=<loopback to local host?> " > - "ttl=<ttl value>" > + "ttl=<ttl value> " > + "allow_suspending_on_idle=<always|never|only_with_monitor_sources>" > ); > > #define DEFAULT_PORT 46000 > @@ -92,9 +93,16 @@ static const char* const valid_modargs[] = { > "mtu" , > "loop", > "ttl", > + "allow_suspending_on_idle", > NULL > }; > > +enum allow_suspending_on_idle { > + ALLOW_SUSPENDING_ON_IDLE_ALWAYS, > + ALLOW_SUSPENDING_ON_IDLE_NEVER, > + ALLOW_SUSPENDING_ON_IDLE_ONLY_WITH_MONITOR_SOURCES > +}; > + > struct userdata { > pa_module *module; > > @@ -106,6 +114,8 @@ struct userdata { > size_t mtu; > > pa_time_event *sap_event; > + > + enum allow_suspending_on_idle allow_suspending_on_idle; > }; > > /* Called from I/O thread context */ > @@ -139,6 +149,39 @@ static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) > pa_rtp_send(&u->rtp_context, u->mtu, u->memblockq); > } > > +static pa_source_output_flags_t get_dont_inhibit_auto_suspend_flag(pa_source *source, > + enum allow_suspending_on_idle allow_suspending_on_idle) { > + pa_assert(source); > + > + switch (allow_suspending_on_idle) { > + case ALLOW_SUSPENDING_ON_IDLE_ALWAYS: > + return PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; > + > + case ALLOW_SUSPENDING_ON_IDLE_NEVER: > + return 0; > + > + case ALLOW_SUSPENDING_ON_IDLE_ONLY_WITH_MONITOR_SOURCES: > + return source->monitor_of ? PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND : 0; > + } > + > + pa_assert_not_reached(); > +} > + > +/* Called from the main thread. */ > +static void source_output_moving_cb(pa_source_output *o, pa_source *dest) { > + struct userdata *u; > + > + pa_assert(o); > + > + u = o->userdata; > + > + if (!dest) > + return; > + > + o->flags &= ~PA_SOURCE_OUTPUT_DONT_INHIBIT_AUTO_SUSPEND; > + o->flags |= get_dont_inhibit_auto_suspend_flag(dest, u->allow_suspending_on_idle); > +} > + > /* Called from main context */ > static void source_output_kill_cb(pa_source_output* o) { > struct userdata *u; > @@ -188,6 +231,8 @@ int pa__init(pa_module*m) { > socklen_t k; > char hn[128], *n; > bool loop = false; > + enum allow_suspending_on_idle allow_suspending_on_idle = ALLOW_SUSPENDING_ON_IDLE_ONLY_WITH_MONITOR_SOURCES; > + const char *allow_suspending_on_idle_str; > pa_source_output_new_data data; > > pa_assert(m); > @@ -207,6 +252,19 @@ int pa__init(pa_module*m) { > goto fail; > } > > + if ((allow_suspending_on_idle_str = pa_modargs_get_value(ma, "allow_suspending_on_idle", NULL))) { > + if (pa_streq(allow_suspending_on_idle_str, "always")) > + allow_suspending_on_idle = ALLOW_SUSPENDING_ON_IDLE_ALWAYS; > + else if (pa_streq(allow_suspending_on_idle_str, "never")) > + allow_suspending_on_idle = ALLOW_SUSPENDING_ON_IDLE_NEVER; > + else if (pa_streq(allow_suspending_on_idle_str, "only_with_monitor_sources")) > + allow_suspending_on_idle = ALLOW_SUSPENDING_ON_IDLE_ONLY_WITH_MONITOR_SOURCES; > + else { > + pa_log("Failed to parse \"allow_suspending_on_idle\" parameter."); > + goto fail; > + } > + } > + > ss = s->sample_spec; > pa_rtp_sample_spec_fixup(&ss); > cm = s->channel_map; > @@ -377,6 +435,7 @@ int pa__init(pa_module*m) { > pa_source_output_new_data_set_source(&data, s, false); > pa_source_output_new_data_set_sample_spec(&data, &ss); > pa_source_output_new_data_set_channel_map(&data, &cm); > + data.flags |= get_dont_inhibit_auto_suspend_flag(s, allow_suspending_on_idle); > > pa_source_output_new(&o, m->core, &data); > pa_source_output_new_data_done(&data); > @@ -388,6 +447,7 @@ int pa__init(pa_module*m) { > > o->parent.process_msg = source_output_process_msg; > o->push = source_output_push_cb; > + o->moving = source_output_moving_cb; > o->kill = source_output_kill_cb; > > pa_log_info("Configured source latency of %llu ms.", > @@ -440,6 +500,7 @@ int pa__init(pa_module*m) { > pa_sap_send(&u->sap_context, 0); > > u->sap_event = pa_core_rttime_new(m->core, pa_rtclock_now() + SAP_INTERVAL, sap_event_cb, u); > + u->allow_suspending_on_idle = allow_suspending_on_idle; > > pa_source_output_put(u->source_output); > > -- Alexander E. Patrakov