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.
This commit is contained in:
Cheng Sun 2017-03-16 21:23:07 +00:00 committed by wm4
parent d26788fbd7
commit d17a719f4e
1 changed files with 34 additions and 7 deletions

View File

@ -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;