[pulseaudio-discuss] [PATCH v2] rtp-send: Add "allow_suspending_on_idle" module argument
Alexander E. Patrakov
patrakov at gmail.com
Sun Feb 23 10:03:26 PST 2014
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
More information about the pulseaudio-discuss
mailing list