mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-03 09:01:50 -05:00
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.
This commit is contained in:
parent
6f2e22e7ad
commit
5bc363d4b8
4 changed files with 45 additions and 13 deletions
|
|
@ -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
|
* 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
|
* source and sink latency are not reported correctly (USB) the result will
|
||||||
* be wrong. */
|
* 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;
|
u->minimum_latency = u->min_sink_latency;
|
||||||
if (u->fixed_alsa_source)
|
if (u->fixed_alsa_source)
|
||||||
|
|
@ -370,16 +370,14 @@ static void update_minimum_latency(struct userdata *u, pa_sink *sink, bool print
|
||||||
else
|
else
|
||||||
u->output_thread_info.minimum_latency = u->minimum_latency;
|
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);
|
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)
|
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_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
|
/* Called from main thread
|
||||||
* Calculates minimum and maximum possible latency for source and sink */
|
* 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;
|
const char *s;
|
||||||
|
|
||||||
if (source) {
|
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;
|
u->min_sink_latency = u->max_sink_latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
update_minimum_latency(u, sink, print_msg);
|
update_minimum_latency(u, sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from output context
|
/* 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);
|
pa_sink_input_set_property(u->sink_input, PA_PROP_DEVICE_ICON_NAME, n);
|
||||||
|
|
||||||
/* Set latency and calculate latency limits */
|
/* 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);
|
set_source_output_latency(u, dest);
|
||||||
update_effective_source_latency(u, dest, u->sink_input->sink);
|
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);
|
pa_source_output_set_property(u->source_output, PA_PROP_MEDIA_ICON_NAME, n);
|
||||||
|
|
||||||
/* Set latency and calculate latency limits */
|
/* 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);
|
set_sink_input_latency(u, dest);
|
||||||
update_effective_source_latency(u, u->source_output->source, 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. */
|
* source implementations. */
|
||||||
pa_log_warn("Source minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
|
pa_log_warn("Source minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
|
||||||
u->configured_source_latency = current_latency;
|
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;
|
return 0;
|
||||||
|
|
@ -1102,7 +1100,7 @@ static int loopback_process_msg_cb(pa_msgobject *o, int code, void *userdata, in
|
||||||
* implementations. */
|
* implementations. */
|
||||||
pa_log_warn("Sink minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
|
pa_log_warn("Sink minimum latency increased to %0.2f ms", (double)current_latency / PA_USEC_PER_MSEC);
|
||||||
u->configured_sink_latency = current_latency;
|
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;
|
return 0;
|
||||||
|
|
@ -1111,6 +1109,28 @@ static int loopback_process_msg_cb(pa_msgobject *o, int code, void *userdata, in
|
||||||
return 0;
|
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) {
|
int pa__init(pa_module *m) {
|
||||||
pa_modargs *ma = NULL;
|
pa_modargs *ma = NULL;
|
||||||
struct userdata *u;
|
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->update_source_fixed_latency = update_source_latency_range_cb;
|
||||||
u->source_output->userdata = u;
|
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_sink_input_latency(u, u->sink_input->sink);
|
||||||
set_source_output_latency(u, u->source_output->source);
|
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)))
|
&& (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);
|
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 */
|
/* Setup message handler for main thread */
|
||||||
u->msg = pa_msgobject_new(loopback_msg);
|
u->msg = pa_msgobject_new(loopback_msg);
|
||||||
u->msg->parent.process_msg = loopback_process_msg_cb;
|
u->msg->parent.process_msg = loopback_process_msg_cb;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ typedef enum pa_core_hook {
|
||||||
PA_CORE_HOOK_SINK_FLAGS_CHANGED,
|
PA_CORE_HOOK_SINK_FLAGS_CHANGED,
|
||||||
PA_CORE_HOOK_SINK_VOLUME_CHANGED,
|
PA_CORE_HOOK_SINK_VOLUME_CHANGED,
|
||||||
PA_CORE_HOOK_SINK_MUTE_CHANGED,
|
PA_CORE_HOOK_SINK_MUTE_CHANGED,
|
||||||
|
PA_CORE_HOOK_SINK_PORT_LATENCY_OFFSET_CHANGED,
|
||||||
PA_CORE_HOOK_SOURCE_NEW,
|
PA_CORE_HOOK_SOURCE_NEW,
|
||||||
PA_CORE_HOOK_SOURCE_FIXATE,
|
PA_CORE_HOOK_SOURCE_FIXATE,
|
||||||
PA_CORE_HOOK_SOURCE_PUT,
|
PA_CORE_HOOK_SOURCE_PUT,
|
||||||
|
|
@ -86,6 +87,7 @@ typedef enum pa_core_hook {
|
||||||
PA_CORE_HOOK_SOURCE_FLAGS_CHANGED,
|
PA_CORE_HOOK_SOURCE_FLAGS_CHANGED,
|
||||||
PA_CORE_HOOK_SOURCE_VOLUME_CHANGED,
|
PA_CORE_HOOK_SOURCE_VOLUME_CHANGED,
|
||||||
PA_CORE_HOOK_SOURCE_MUTE_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_NEW,
|
||||||
PA_CORE_HOOK_SINK_INPUT_FIXATE,
|
PA_CORE_HOOK_SINK_INPUT_FIXATE,
|
||||||
PA_CORE_HOOK_SINK_INPUT_PUT,
|
PA_CORE_HOOK_SINK_INPUT_PUT,
|
||||||
|
|
|
||||||
|
|
@ -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);
|
pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SINK_MESSAGE_SET_PORT_LATENCY_OFFSET, NULL, offset, NULL) == 0);
|
||||||
else
|
else
|
||||||
s->thread_info.port_latency_offset = offset;
|
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 */
|
/* Called from main context */
|
||||||
|
|
|
||||||
|
|
@ -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);
|
pa_assert_se(pa_asyncmsgq_send(s->asyncmsgq, PA_MSGOBJECT(s), PA_SOURCE_MESSAGE_SET_PORT_LATENCY_OFFSET, NULL, offset, NULL) == 0);
|
||||||
else
|
else
|
||||||
s->thread_info.port_latency_offset = offset;
|
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 */
|
/* Called from main thread */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue