From d17a719f4e665d873a552e46632e4d73154ce011 Mon Sep 17 00:00:00 2001 From: Cheng Sun Date: Thu, 16 Mar 2017 21:23:07 +0000 Subject: ao_jack: update latency on buffer_size/graph change The buffer_size may be updated before the process callback is called for the first time. Or, the connection graph could change, which changes the latency of the pipeline after mpv's output. Ensure we keep on top of these changes by registering callbacks to update our latency estimation. --- audio/out/ao_jack.c | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/audio/out/ao_jack.c b/audio/out/ao_jack.c index 2ad3cad586..597835c989 100644 --- a/audio/out/ao_jack.c +++ b/audio/out/ao_jack.c @@ -33,6 +33,7 @@ #include "ao.h" #include "internal.h" #include "audio/format.h" +#include "osdep/atomic.h" #include "osdep/timer.h" #include "options/m_config.h" #include "options/m_option.h" @@ -67,7 +68,10 @@ static const struct m_sub_options ao_jack_conf = { struct priv { jack_client_t *client; - float jack_latency; + + atomic_uint graph_latency_max; + atomic_uint buffer_size; + int last_chunk; int num_ports; @@ -78,6 +82,29 @@ struct priv { struct jack_opts *opts; }; +static int graph_order_cb(void *arg) +{ + struct ao *ao = arg; + struct priv *p = ao->priv; + + jack_latency_range_t jack_latency_range; + jack_port_get_latency_range(p->ports[0], JackPlaybackLatency, + &jack_latency_range); + atomic_store(&p->graph_latency_max, jack_latency_range.max); + + return 0; +} + +static int buffer_size_cb(jack_nframes_t nframes, void *arg) +{ + struct ao *ao = arg; + struct priv *p = ao->priv; + + atomic_store(&p->buffer_size, nframes); + + return 0; +} + static int process(jack_nframes_t nframes, void *arg) { struct ao *ao = arg; @@ -88,8 +115,11 @@ static int process(jack_nframes_t nframes, void *arg) for (int i = 0; i < p->num_ports; i++) buffers[i] = jack_port_get_buffer(p->ports[i], nframes); + jack_nframes_t jack_latency = + atomic_load(&p->graph_latency_max) + atomic_load(&p->buffer_size); + int64_t end_time = mp_time_us(); - end_time += (p->jack_latency + nframes / (double)ao->samplerate) * 1000000.0; + end_time += (jack_latency + nframes) / (double)ao->samplerate * 1000000.0; ao_read_data(ao, buffers, nframes, end_time); @@ -212,11 +242,8 @@ static int init(struct ao *ao) ao->samplerate = jack_get_sample_rate(p->client); - jack_latency_range_t jack_latency_range; - jack_port_get_latency_range(p->ports[0], JackPlaybackLatency, - &jack_latency_range); - p->jack_latency = (float)(jack_latency_range.max + jack_get_buffer_size(p->client)) - / (float)ao->samplerate; + jack_set_buffer_size_callback(p->client, buffer_size_cb, ao); + jack_set_graph_order_callback(p->client, graph_order_cb, ao); if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports)) goto err_chmap_sel_get_def; -- cgit v1.2.3