[PATCH v2] rtp-send: Add "allow_suspending_on_idle" module argument

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux