summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Chini <georg@chini.tk>2017-04-10 21:47:23 +0200
committerGeorg Chini <georg@chini.tk>2017-04-10 21:47:23 +0200
commit5bc363d4b84ccbb07727d7d0603598a3b664b1b1 (patch)
tree8f10a240becb494f6d94296f7a59bf22b0815af1
parent6f2e22e7ad5671f687687ff2a8d66b95a7a30bef (diff)
loopback: Add hooks to track port latency offsets
The previous patch assumed constant port latency offsets. The offsets can however be changed by the user, therefore these changes need to be tracked as well. This patch adds the necessary hooks. Also the print_msg argument was removed from update_minimum_latency() and update_latency_boundaries() because the message should always be logged.
-rw-r--r--src/modules/module-loopback.c52
-rw-r--r--src/pulsecore/core.h2
-rw-r--r--src/pulsecore/sink.c2
-rw-r--r--src/pulsecore/source.c2
4 files changed, 45 insertions, 13 deletions
diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c
index 442bc8a9..2242c62c 100644
--- a/src/modules/module-loopback.c
+++ b/src/modules/module-loopback.c
@@ -335,7 +335,7 @@ static void update_adjust_timer(struct userdata *u) {
* depends on the reported latency ranges. In cases were the lower bounds of
* source and sink latency are not reported correctly (USB) the result will
* be wrong. */
-static void update_minimum_latency(struct userdata *u, pa_sink *sink, bool print_msg) {
+static void update_minimum_latency(struct userdata *u, pa_sink *sink) {
u->minimum_latency = u->min_sink_latency;
if (u->fixed_alsa_source)
@@ -370,16 +370,14 @@ static void update_minimum_latency(struct userdata *u, pa_sink *sink, bool print
else
u->output_thread_info.minimum_latency = u->minimum_latency;
- if (print_msg) {
- pa_log_info("Minimum possible end to end latency: %0.2f ms", (double)u->minimum_latency / PA_USEC_PER_MSEC);
- if (u->latency < u->minimum_latency)
- pa_log_warn("Configured latency of %0.2f ms is smaller than minimum latency, using minimum instead", (double)u->latency / PA_USEC_PER_MSEC);
- }
+ pa_log_info("Minimum possible end to end latency: %0.2f ms", (double)u->minimum_latency / PA_USEC_PER_MSEC);
+ if (u->latency < u->minimum_latency)
+ pa_log_warn("Configured latency of %0.2f ms is smaller than minimum latency, using minimum instead", (double)u->latency / PA_USEC_PER_MSEC);
}
/* Called from main thread
* Calculates minimum and maximum possible latency for source and sink */
-static void update_latency_boundaries(struct userdata *u, pa_source *source, pa_sink *sink, bool print_msg) {
+static void update_latency_boundaries(struct userdata *u, pa_source *source, pa_sink *sink) {
const char *s;
if (source) {
@@ -423,7 +421,7 @@ static void update_latency_boundaries(struct userdata *u, pa_source *source, pa_
u->min_sink_latency = u->max_sink_latency;
}
- update_minimum_latency(u, sink, print_msg);
+ update_minimum_latency(u, sink);
}
/* Called from output context
@@ -626,7 +624,7 @@ static void source_output_moving_cb(pa_source_output *o, pa_source *dest) {
pa_sink_input_set_property(u->sink_input, PA_PROP_DEVICE_ICON_NAME, n);
/* Set latency and calculate latency limits */
- update_latency_boundaries(u, dest, u->sink_input->sink, true);
+ update_latency_boundaries(u, dest, u->sink_input->sink);
set_source_output_latency(u, dest);
update_effective_source_latency(u, dest, u->sink_input->sink);
@@ -995,7 +993,7 @@ static void sink_input_moving_cb(pa_sink_input *i, pa_sink *dest) {
pa_source_output_set_property(u->source_output, PA_PROP_MEDIA_ICON_NAME, n);
/* Set latency and calculate latency limits */
- update_latency_boundaries(u, NULL, dest, true);
+ update_latency_boundaries(u, NULL, dest);
set_sink_input_latency(u, dest);
update_effective_source_latency(u, u->source_output->source, dest);
@@ -1087,7 +1085,7 @@ static int loopback_process_msg_cb(pa_msgobject *o, int code, void *userdata, in
* source implementations. */
pa_log_warn("Source minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
u->configured_source_latency = current_latency;
- update_latency_boundaries(u, u->source_output->source, u->sink_input->sink, false);
+ update_latency_boundaries(u, u->source_output->source, u->sink_input->sink);
}
return 0;
@@ -1102,7 +1100,7 @@ static int loopback_process_msg_cb(pa_msgobject *o, int code, void *userdata, in
* implementations. */
pa_log_warn("Sink minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
u->configured_sink_latency = current_latency;
- update_latency_boundaries(u, u->source_output->source, u->sink_input->sink, false);
+ update_latency_boundaries(u, u->source_output->source, u->sink_input->sink);
}
return 0;
@@ -1111,6 +1109,28 @@ static int loopback_process_msg_cb(pa_msgobject *o, int code, void *userdata, in
return 0;
}
+static pa_hook_result_t sink_port_latency_offset_changed_cb(pa_core *core, pa_sink *sink, struct userdata *u) {
+
+ if (sink != u->sink_input->sink)
+ return PA_HOOK_OK;
+
+ u->sink_latency_offset = sink->port_latency_offset;
+ update_minimum_latency(u, sink);
+
+ return PA_HOOK_OK;
+}
+
+static pa_hook_result_t source_port_latency_offset_changed_cb(pa_core *core, pa_source *source, struct userdata *u) {
+
+ if (source != u->source_output->source)
+ return PA_HOOK_OK;
+
+ u->source_latency_offset = source->port_latency_offset;
+ update_minimum_latency(u, u->sink_input->sink);
+
+ return PA_HOOK_OK;
+}
+
int pa__init(pa_module *m) {
pa_modargs *ma = NULL;
struct userdata *u;
@@ -1342,7 +1362,7 @@ int pa__init(pa_module *m) {
u->source_output->update_source_fixed_latency = update_source_latency_range_cb;
u->source_output->userdata = u;
- update_latency_boundaries(u, u->source_output->source, u->sink_input->sink, true);
+ update_latency_boundaries(u, u->source_output->source, u->sink_input->sink);
set_sink_input_latency(u, u->sink_input->sink);
set_source_output_latency(u, u->source_output->source);
@@ -1383,6 +1403,12 @@ int pa__init(pa_module *m) {
&& (n = pa_proplist_gets(u->source_output->source->proplist, PA_PROP_DEVICE_ICON_NAME)))
pa_proplist_sets(u->sink_input->proplist, PA_PROP_MEDIA_ICON_NAME, n);
+ /* Hooks to track changes of latency offsets */
+ pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SINK_PORT_LATENCY_OFFSET_CHANGED],
+ PA_HOOK_NORMAL, (pa_hook_cb_t) sink_port_latency_offset_changed_cb, u);
+ pa_module_hook_connect(m, &m->core->hooks[PA_CORE_HOOK_SOURCE_PORT_LATENCY_OFFSET_CHANGED],
+ PA_HOOK_NORMAL, (pa_hook_cb_t) source_port_latency_offset_changed_cb, u);
+
/* Setup message handler for main thread */
u->msg = pa_msgobject_new(loopback_msg);
u->msg->parent.process_msg = loopback_process_msg_cb;
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 212f6f71..df71a118 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -75,6 +75,7 @@ typedef enum pa_core_hook {
PA_CORE_HOOK_SINK_FLAGS_CHANGED,
PA_CORE_HOOK_SINK_VOLUME_CHANGED,
PA_CORE_HOOK_SINK_MUTE_CHANGED,
+ PA_CORE_HOOK_SINK_PORT_LATENCY_OFFSET_CHANGED,
PA_CORE_HOOK_SOURCE_NEW,
PA_CORE_HOOK_SOURCE_FIXATE,
PA_CORE_HOOK_SOURCE_PUT,
@@ -86,6 +87,7 @@ typedef enum pa_core_hook {
PA_CORE_HOOK_SOURCE_FLAGS_CHANGED,
PA_CORE_HOOK_SOURCE_VOLUME_CHANGED,
PA_CORE_HOOK_SOURCE_MUTE_CHANGED,
+ PA_CORE_HOOK_SOURCE_PORT_LATENCY_OFFSET_CHANGED,
PA_CORE_HOOK_SINK_INPUT_NEW,
PA_CORE_HOOK_SINK_INPUT_FIXATE,
PA_CORE_HOOK_SINK_INPUT_PUT,
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index fb16d574..39689437 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -3295,6 +3295,8 @@ void pa_sink_set_port_latency_offset(pa_sink *s, int64_t offset) {
pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT_LATENCY_OFFSET, NULL, offset, NULL) == 0);
else
s->thread_info.port_latency_offset = offset;
+
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SINK_PORT_LATENCY_OFFSET_CHANGED], s);
}
/* Called from main context */
diff --git a/src/pulsecore/source.c b/src/pulsecore/source.c
index 09c953f1..14250825 100644
--- a/src/pulsecore/source.c
+++ b/src/pulsecore/source.c
@@ -2586,6 +2586,8 @@ void pa_source_set_port_latency_offset(pa_source *s, int64_t offset) {
pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT_LATENCY_OFFSET, NULL, offset, NULL) == 0);
else
s->thread_info.port_latency_offset = offset;
+
+ pa_hook_fire(&s->core->hooks[PA_CORE_HOOK_SOURCE_PORT_LATENCY_OFFSET_CHANGED], s);
}
/* Called from main thread */