mirror of https://github.com/mpv-player/mpv
ao_pulse: allow disabling timing bug workarounds
Add an option that enables using native PulseAudio auto-updated timing
information, instead of the manual calculations added in mplayer2 times.
You can use --ao=pulse:no-latency-hacks to enable the new code. The code
is almost the same as the code that was removed with commit de435ed5
,
but I didn't readd some bits I didn't understand. Likewise, the option
will disable the code added with that commit.
In my tests this seemed to work well, though the A/V sync display looks
funny when seeking.
The default is still the old behavior.
See issue #959.
This commit is contained in:
parent
77d9e4b8a9
commit
bc6359313f
|
@ -149,6 +149,12 @@ Available audio output drivers are:
|
|||
value makes the audio stream react faster, e.g. to playback speed
|
||||
changes. Default: 250.
|
||||
|
||||
``latency-hacks=<yes|no>``
|
||||
Enable hacks to workaround PulseAudio timing bugs (default: yes). If
|
||||
enabled, mpv will do elaborate latency calculations on its own. If
|
||||
disabled, it will use PulseAudio automatically updated timing
|
||||
information. Disabling this might help with e.g. networked audio.
|
||||
|
||||
``portaudio``
|
||||
PortAudio audio output driver. This works on all platforms, and has
|
||||
extensive MS Windows support.
|
||||
|
|
|
@ -63,6 +63,7 @@ struct priv {
|
|||
char *cfg_host;
|
||||
char *cfg_sink;
|
||||
int cfg_buffer;
|
||||
int cfg_latency_hacks;
|
||||
};
|
||||
|
||||
#define GENERIC_ERR_MSG(str) \
|
||||
|
@ -365,8 +366,13 @@ static int init(struct ao *ao)
|
|||
.minreq = -1,
|
||||
.fragsize = -1,
|
||||
};
|
||||
|
||||
int flags = PA_STREAM_NOT_MONOTONIC;
|
||||
if (!priv->cfg_latency_hacks)
|
||||
flags |= PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE;
|
||||
|
||||
if (pa_stream_connect_playback(priv->stream, sink, &bufattr,
|
||||
PA_STREAM_NOT_MONOTONIC, NULL, NULL) < 0)
|
||||
flags, NULL, NULL) < 0)
|
||||
goto unlock_and_fail;
|
||||
|
||||
/* Wait until the stream is ready */
|
||||
|
@ -463,8 +469,7 @@ static int get_space(struct ao *ao)
|
|||
return space / ao->sstride;
|
||||
}
|
||||
|
||||
// Return the current latency in seconds
|
||||
static float get_delay(struct ao *ao)
|
||||
static float get_delay_hackfixed(struct ao *ao)
|
||||
{
|
||||
/* This code basically does what pa_stream_get_latency() _should_
|
||||
* do, but doesn't due to multiple known bugs in PulseAudio (at
|
||||
|
@ -519,6 +524,34 @@ static float get_delay(struct ao *ao)
|
|||
return latency / 1e6;
|
||||
}
|
||||
|
||||
static float get_delay_pulse(struct ao *ao)
|
||||
{
|
||||
struct priv *priv = ao->priv;
|
||||
pa_usec_t latency = (pa_usec_t) -1;
|
||||
pa_threaded_mainloop_lock(priv->mainloop);
|
||||
while (pa_stream_get_latency(priv->stream, &latency, NULL) < 0) {
|
||||
if (pa_context_errno(priv->context) != PA_ERR_NODATA) {
|
||||
GENERIC_ERR_MSG("pa_stream_get_latency() failed");
|
||||
break;
|
||||
}
|
||||
/* Wait until latency data is available again */
|
||||
pa_threaded_mainloop_wait(priv->mainloop);
|
||||
}
|
||||
pa_threaded_mainloop_unlock(priv->mainloop);
|
||||
return latency == (pa_usec_t) -1 ? 0 : latency / 1000000.0;
|
||||
}
|
||||
|
||||
// Return the current latency in seconds
|
||||
static float get_delay(struct ao *ao)
|
||||
{
|
||||
struct priv *priv = ao->priv;
|
||||
if (priv->cfg_latency_hacks) {
|
||||
return get_delay_hackfixed(ao);
|
||||
} else {
|
||||
return get_delay_pulse(ao);
|
||||
}
|
||||
}
|
||||
|
||||
/* A callback function that is called when the
|
||||
* pa_context_get_sink_input_info() operation completes. Saves the
|
||||
* volume field of the specified structure to the global variable volume.
|
||||
|
@ -648,11 +681,13 @@ const struct ao_driver audio_out_pulse = {
|
|||
.priv_size = sizeof(struct priv),
|
||||
.priv_defaults = &(const struct priv) {
|
||||
.cfg_buffer = 250,
|
||||
.cfg_latency_hacks = 1,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_STRING("host", cfg_host, 0),
|
||||
OPT_STRING("sink", cfg_sink, 0),
|
||||
OPT_CHOICE_OR_INT("buffer", cfg_buffer, 0, 1, 2000, ({"native", -1})),
|
||||
OPT_FLAG("latency-hacks", cfg_latency_hacks, 0),
|
||||
{0}
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue