[6/6] tunnel: Make fixed latency configurable

Submitted by Georg Chini on April 9, 2018, 4:33 p.m.

Details

Message ID 20180409163321.17279-7-georg@chini.tk
State New
Headers show
Series "combine-sink, tunnel-sink: Latency fixes" ( rev: 1 ) in PulseAudio

Not browsing as part of any series.

Commit Message

Georg Chini April 9, 2018, 4:33 p.m.
Currently, module-tunnel uses the default fixed latency of 250ms as fixed
latency.

There is no reason for such a large latency. This patch adds a parameter
latency_msec to the module to set the fixed latency at load time of the
module. The parameter can range from 5 to 500 milliseconds. With this
patch, I was able to run a tunnel sink at 7ms latency without problems.
---
 src/modules/module-tunnel.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/modules/module-tunnel.c b/src/modules/module-tunnel.c
index c21c7847..2068deca 100644
--- a/src/modules/module-tunnel.c
+++ b/src/modules/module-tunnel.c
@@ -79,6 +79,7 @@  PA_MODULE_USAGE(
         "format=<sample format> "
         "channels=<number of channels> "
         "rate=<sample rate> "
+        "latency_msec=<fixed latency in ms> "
         "channel_map=<channel map>");
 #else
 PA_MODULE_DESCRIPTION("Tunnel module for sources");
@@ -92,6 +93,7 @@  PA_MODULE_USAGE(
         "format=<sample format> "
         "channels=<number of channels> "
         "rate=<sample rate> "
+        "latency_msec=<fixed latency in ms> "
         "channel_map=<channel map>");
 #endif
 
@@ -106,6 +108,7 @@  static const char* const valid_modargs[] = {
     "format",
     "channels",
     "rate",
+    "latency_msec",
 #ifdef TUNNEL_SINK
     "sink_name",
     "sink_properties",
@@ -135,8 +138,7 @@  enum {
     SINK_MESSAGE_POST
 };
 
-#define DEFAULT_TLENGTH_MSEC 150
-#define DEFAULT_MINREQ_MSEC 25
+#define DEFAULT_LATENCY_MSEC 100
 
 #else
 
@@ -147,7 +149,7 @@  enum {
     SOURCE_MESSAGE_GET_LATENCY_SNAPSHOT
 };
 
-#define DEFAULT_FRAGSIZE_MSEC 25
+#define DEFAULT_LATENCY_MSEC 25
 
 #endif
 
@@ -213,6 +215,7 @@  struct userdata {
     uint32_t ctag;
     uint32_t device_index;
     uint32_t channel;
+    uint32_t latency;
 
     int64_t counter;
     uint64_t receive_counter;
@@ -1672,11 +1675,11 @@  static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t
         u->maxlength = 4*1024*1024;
 
 #ifdef TUNNEL_SINK
-    u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_TLENGTH_MSEC, &u->sink->sample_spec);
-    u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_MINREQ_MSEC, &u->sink->sample_spec);
+    u->tlength = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * u->latency, &u->sink->sample_spec);
+    u->minreq = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * u->latency / 4, &u->sink->sample_spec);
     u->prebuf = u->tlength;
 #else
-    u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * DEFAULT_FRAGSIZE_MSEC, &u->source->sample_spec);
+    u->fragsize = (uint32_t) pa_usec_to_bytes(PA_USEC_PER_MSEC * u->latency, &u->source->sample_spec);
 #endif
 
 #ifdef TUNNEL_SINK
@@ -1946,6 +1949,7 @@  int pa__init(pa_module*m) {
     pa_sample_spec ss;
     pa_channel_map map;
     char *dn = NULL;
+    uint32_t latency_msec;
 #ifdef TUNNEL_SINK
     pa_sink_new_data data;
 #else
@@ -2009,6 +2013,15 @@  int pa__init(pa_module*m) {
         goto fail;
     }
 
+    /* Allow latencies between 5ms and 500ms */
+    latency_msec = DEFAULT_LATENCY_MSEC;
+    if (pa_modargs_get_value_u32(ma, "latency_msec", &latency_msec) < 0 || latency_msec < 5 || latency_msec > 500) {
+        pa_log("Invalid latency specification");
+        goto fail;
+    }
+
+    u->latency = latency_msec;
+
     cookie_path = pa_modargs_get_value(ma, "cookie", NULL);
     server = pa_xstrdup(pa_modargs_get_value(ma, "server", NULL));
 
@@ -2190,6 +2203,7 @@  int pa__init(pa_module*m) {
 
     pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
     pa_sink_set_rtpoll(u->sink, u->rtpoll);
+    pa_sink_set_fixed_latency(u->sink, latency_msec * PA_USEC_PER_MSEC);
 
 #else
 
@@ -2230,6 +2244,7 @@  int pa__init(pa_module*m) {
 
     pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
     pa_source_set_rtpoll(u->source, u->rtpoll);
+    pa_source_set_fixed_latency(u->source, latency_msec * PA_USEC_PER_MSEC);
 
     u->mcalign = pa_mcalign_new(pa_frame_size(&u->source->sample_spec));
 #endif