[pulseaudio-discuss] GSOC: bluetooth latency - status report [2/?]

poljarinho at gmail.com poljarinho at gmail.com
Fri Jun 8 06:12:57 PDT 2012


Hello mailing list, time for the second status report.

The cleaned up port implementation for the bluetooth device is already
on the mailing list as you already saw.

Now I would like some feedback for the next stage of my GSOC project.
I have added a latency variable to the pa_device_port struct. This
latency from the port should then be added to the sink if the port is
currently active.

I have some problems following where I should add the latency so it
will become active. As I have discovered there are two types of sinks.
Some are with dynamic and some are with fixed latency. 

If I add the extra latency just to sink->min_latency would that do the
job? Or is that a bad idea?

The current changes can be seen in the attached diff.

Thanks for your attention.
-------------- next part --------------
diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c
index fc9465b..92a0b72 100644
--- a/src/pulsecore/cli-command.c
+++ b/src/pulsecore/cli-command.c
@@ -135,6 +135,7 @@ static int pa_cli_command_update_source_output_proplist(pa_core *c, pa_tokenizer
 static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
+static int pa_cli_command_latency_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail);
 
 /* A method table for all available commands */
@@ -168,6 +169,7 @@ static const struct command commands[] = {
     { "set-card-profile",        pa_cli_command_card_profile,       "Change the profile of a card (args: index|name, profile-name)", 3},
     { "set-sink-port",           pa_cli_command_sink_port,          "Change the port of a sink (args: index|name, port-name)", 3},
     { "set-source-port",         pa_cli_command_source_port,        "Change the port of a source (args: index|name, port-name)", 3},
+    { "set-latency-offset",      pa_cli_command_latency_offset,     "Change the latency of a port (args: port-name)", 2},
     { "suspend-sink",            pa_cli_command_suspend_sink,       "Suspend sink (args: index|name, bool)", 3},
     { "suspend-source",          pa_cli_command_suspend_source,     "Suspend source (args: index|name, bool)", 3},
     { "suspend",                 pa_cli_command_suspend,            "Suspend all sinks and all sources (args: bool)", 2},
@@ -1723,6 +1725,49 @@ static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *bu
     return 0;
 }
 
+static int pa_cli_command_latency_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
+    const char *n, *p, *l;
+    pa_device_port *port;
+    pa_card *card;
+    uint32_t latency;
+
+    pa_core_assert_ref(c);
+    pa_assert(t);
+    pa_assert(buf);
+    pa_assert(fail);
+
+    if (!(n = pa_tokenizer_get(t, 1))) {
+        pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n");
+        return -1;
+    }
+
+    if (!(p = pa_tokenizer_get(t, 2))) {
+        pa_strbuf_puts(buf, "You need to specify a profile by its name.\n");
+        return -1;
+    }
+
+    if (!(l = pa_tokenizer_get(t, 3))) {
+        pa_strbuf_puts(buf, "You need to specify a latency offset.\n");
+        return -1;
+    }
+
+    if (pa_atou(l, &latency) < 0) {
+        pa_strbuf_puts(buf, "Failed to parse latency.\n");
+        return -1;
+    }
+
+    if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) {
+        pa_strbuf_puts(buf, "No card found by this name or index.\n");
+        return -1;
+    }
+
+    port = pa_hashmap_get(card->ports, p);
+
+    pa_device_port_set_latency_offset(port, (pa_usec_t) latency);
+
+    return 0;
+}
+
 static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) {
     pa_module *m;
     pa_sink *sink;
diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c
index 5870913..19a29f4 100644
--- a/src/pulsecore/device-port.c
+++ b/src/pulsecore/device-port.c
@@ -97,6 +97,7 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des
     p->profiles = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
     p->is_input = FALSE;
     p->is_output = FALSE;
+    p->latency_offset = 0;
     p->proplist = pa_proplist_new();
 
     return p;
@@ -112,3 +113,23 @@ void pa_device_port_hashmap_free(pa_hashmap *h) {
 
     pa_hashmap_free(h, NULL, NULL);
 }
+
+void pa_device_port_set_latency_offset(pa_device_port *p, pa_usec_t latency) {
+    uint32_t state;
+    pa_sink *sink;
+    
+    pa_assert(p);
+
+    p->latency_offset = latency;
+    PA_IDXSET_FOREACH(sink, p->core->sinks, state)
+        if (sink->active_port == p) {
+            pa_sink_set_latency_offset(sink, p->latency_offset);
+            break;
+        }
+}
+
+pa_usec_t pa_device_port_get_latency_offset(pa_device_port *p) {
+    pa_assert(p);
+
+    return p->latency_offset;
+}
diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h
index 4e90a62..8cb0b70 100644
--- a/src/pulsecore/device-port.h
+++ b/src/pulsecore/device-port.h
@@ -51,6 +51,7 @@ struct pa_device_port {
     pa_hashmap *profiles; /* Can be NULL. Does not own the profiles */
     pa_bool_t is_input:1;
     pa_bool_t is_output:1;
+    pa_usec_t latency_offset;
 
     /* .. followed by some implementation specific data */
 };
@@ -67,4 +68,9 @@ void pa_device_port_hashmap_free(pa_hashmap *h);
 /* The port's available status has changed */
 void pa_device_port_set_available(pa_device_port *p, pa_port_available_t available);
 
+/* Functions for handling the extra latency */
+void pa_device_port_set_latency_offset(pa_device_port *p, pa_usec_t latency);
+
+pa_usec_t pa_device_port_get_latency_offset(pa_device_port *p);
+
 #endif
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index e4c343d..45e30de 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -3223,6 +3223,9 @@ void pa_sink_set_fixed_latency_within_thread(pa_sink *s, pa_usec_t latency) {
     pa_source_set_fixed_latency_within_thread(s->monitor_source, latency);
 }
 
+void pa_sink_set_latency_offset(pa_sink *s, pa_usec_t latency) {
+}
+
 /* Called from main context */
 size_t pa_sink_get_max_rewind(pa_sink *s) {
     size_t r;
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 0b5048a..64ebafd 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -385,6 +385,7 @@ void pa_sink_set_max_rewind(pa_sink *s, size_t max_rewind);
 void pa_sink_set_max_request(pa_sink *s, size_t max_request);
 void pa_sink_set_latency_range(pa_sink *s, pa_usec_t min_latency, pa_usec_t max_latency);
 void pa_sink_set_fixed_latency(pa_sink *s, pa_usec_t latency);
+void pa_sink_set_latency_offset(pa_sink *s, pa_usec_t latency);
 
 void pa_sink_detach(pa_sink *s);
 void pa_sink_attach(pa_sink *s);


More information about the pulseaudio-discuss mailing list