[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