summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorCheng Sun <chengsun9@gmail.com>2017-03-16 21:23:07 +0000
committerwm4 <wm4@nowhere>2017-03-18 14:15:34 +0100
commitd17a719f4e665d873a552e46632e4d73154ce011 (patch)
tree77915959fe27b1280d33b090aff030ffef15c334 /audio
parentd26788fbd7e804aa44fcb01331893fc20b4a381f (diff)
downloadmpv-d17a719f4e665d873a552e46632e4d73154ce011.tar.bz2
mpv-d17a719f4e665d873a552e46632e4d73154ce011.tar.xz
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.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_jack.c41
1 files 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;