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

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

 



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);


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

  Powered by Linux