[pulseaudio-discuss] [PATCH v6 15/25] alsa-{source, sink}.c: Handle PA_{SOURCE, SINK}_MESSAGE_GET_RAW_LATENCY

Georg Chini georg at chini.tk
Sun Jun 5 19:05:18 UTC 2016


Implement handling for PA_SINK_MESSAGE_GET_RAW_LATENCY in alsa source and sink
to improve the latency reports for alsa devices.
Use *_get_raw_latency_within_thread() calls in module loopback. This will remove
latency discontinuities for alsa devices.

---
 src/modules/alsa/alsa-sink.c   | 25 ++++++++++++++++++-------
 src/modules/alsa/alsa-source.c | 20 +++++++++++++++++---
 src/modules/module-loopback.c  |  8 ++++----
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 2fdebe0..ec867cb 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -892,8 +892,7 @@ static void update_smoother(struct userdata *u) {
     u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
 }
 
-static pa_usec_t sink_get_latency(struct userdata *u) {
-    pa_usec_t r;
+static pa_usec_t sink_get_latency(struct userdata *u, bool raw) {
     int64_t delay;
     pa_usec_t now1, now2;
 
@@ -904,12 +903,13 @@ static pa_usec_t sink_get_latency(struct userdata *u) {
 
     delay = (int64_t) pa_bytes_to_usec(u->write_count, &u->sink->sample_spec) - (int64_t) now2;
 
-    r = delay >= 0 ? (pa_usec_t) delay : 0;
-
     if (u->memchunk.memblock)
-        r += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
+        delay += pa_bytes_to_usec(u->memchunk.length, &u->sink->sample_spec);
 
-    return r;
+    if (raw)
+       return delay;
+    else
+       return delay >= 0 ? (pa_usec_t) delay : 0;
 }
 
 static int build_pollfd(struct userdata *u) {
@@ -1153,13 +1153,24 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse
             pa_usec_t r = 0;
 
             if (u->pcm_handle)
-                r = sink_get_latency(u);
+                r = sink_get_latency(u, false);
 
             *((pa_usec_t*) data) = r;
 
             return 0;
         }
 
+        case PA_SINK_MESSAGE_GET_RAW_LATENCY: {
+            int64_t r = 0;
+
+            if (u->pcm_handle)
+                r = sink_get_latency(u, true);
+
+            *((int64_t *) data) = r;
+
+            return 0;
+        }
+
         case PA_SINK_MESSAGE_SET_STATE:
 
             switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 4683dfe..8f3571c 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -809,7 +809,7 @@ static void update_smoother(struct userdata *u) {
     u->smoother_interval = PA_MIN (u->smoother_interval * 2, SMOOTHER_MAX_INTERVAL);
 }
 
-static pa_usec_t source_get_latency(struct userdata *u) {
+static pa_usec_t source_get_latency(struct userdata *u, bool raw) {
     int64_t delay;
     pa_usec_t now1, now2;
 
@@ -820,7 +820,10 @@ static pa_usec_t source_get_latency(struct userdata *u) {
 
     delay = (int64_t) now2 - (int64_t) pa_bytes_to_usec(u->read_count, &u->source->sample_spec);
 
-    return delay >= 0 ? (pa_usec_t) delay : 0;
+    if (raw)
+       return delay;
+    else
+       return delay >= 0 ? (pa_usec_t) delay : 0;
 }
 
 static int build_pollfd(struct userdata *u) {
@@ -1035,13 +1038,24 @@ static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t off
             pa_usec_t r = 0;
 
             if (u->pcm_handle)
-                r = source_get_latency(u);
+                r = source_get_latency(u, false);
 
             *((pa_usec_t*) data) = r;
 
             return 0;
         }
 
+        case PA_SOURCE_MESSAGE_GET_RAW_LATENCY: {
+            int64_t r = 0;
+
+            if (u->pcm_handle)
+                r = source_get_latency(u, true);
+
+            *((int64_t *) data) = r;
+
+            return 0;
+        }
+
         case PA_SOURCE_MESSAGE_SET_STATE:
 
             switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index f370ae2..c54b531 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -110,12 +110,12 @@ struct userdata {
 
     struct {
         int64_t send_counter;
-        pa_usec_t source_latency;
+        int64_t source_latency;
         pa_usec_t source_timestamp;
 
         int64_t recv_counter;
         size_t sink_input_buffer;
-        pa_usec_t sink_latency;
+        int64_t sink_latency;
         pa_usec_t sink_timestamp;
     } latency_snapshot;
 };
@@ -400,7 +400,7 @@ static int source_output_process_msg_cb(pa_msgobject *obj, int code, void *data,
 
             u->latency_snapshot.send_counter = u->send_counter;
             /* Add content of delay memblockq to the source latency */
-            u->latency_snapshot.source_latency = pa_source_get_latency_within_thread(u->source_output->source) +
+            u->latency_snapshot.source_latency = pa_source_get_raw_latency_within_thread(u->source_output->source) +
                                                  pa_bytes_to_usec(length, &u->source_output->source->sample_spec);
             u->latency_snapshot.source_timestamp = pa_rtclock_now();
 
@@ -748,7 +748,7 @@ static int sink_input_process_msg_cb(pa_msgobject *obj, int code, void *data, in
             u->latency_snapshot.recv_counter = u->recv_counter;
             u->latency_snapshot.sink_input_buffer = pa_memblockq_get_length(u->memblockq);
             /* Add content of render memblockq to sink latency */
-            u->latency_snapshot.sink_latency = pa_sink_get_latency_within_thread(u->sink_input->sink) +
+            u->latency_snapshot.sink_latency = pa_sink_get_raw_latency_within_thread(u->sink_input->sink) +
                                                pa_bytes_to_usec(length, &u->sink_input->sink->sample_spec);
             u->latency_snapshot.sink_timestamp = pa_rtclock_now();
 
-- 
2.8.1



More information about the pulseaudio-discuss mailing list