The original intention was probably to avoid unnecessarily high numbers
of wakeups. Change it to wait at most 25% of buffer time instead of 75%
until refilling. Might help with the dsound problems in issue #1024, but
I don't know if success is guaranteed.
Reduce from 1000ms to 100ms. Since there is an audio thread updating AOs
quickly enough now, requesting such a large buffer size makes no sense
anymore.
Some ALSA plugins take non-interleaved audio, but treat it as
interleaved, which results in various funny bugs. Users keep hitting
this issue, and it just doesn't seem worth the trouble.
CC: @mpv-player/stable
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 was needed by very old (0.9) versions only. Get rid of it.
Unfortunately, I can't cross-check with the original bug report, since
the bug URL leads to this:
Internal Server Error
TracError: IOError: [Errno 2] No such file or directory: '/home/lennart/svn/trac/pulseaudio/VERSION'
ao_null is used to stop autoprobing (if all AOs before fail to init).
After it come things like ao_pcm, which should never be automatically
selected.
Remove a certain theoretically possible failure case, and force "some"
fallback.
mp_make_wakeup_pipe() always fails on win32. If this call fails on Linux
(and e.g. ao_alsa is used), this will probably burn CPU since poll()
won't work on the invalid file descriptor, but whatever, the failure
case is obscure enough.
There was confusion about what should go into audio pts calculation and
what not (mainly due to the audio push thread). This has been fixed by
using the playing - not written - audio pts (which properly takes into
account the ao's buffer), and incrementing the samples count only by the
amount of samples actually taken from the buffer (unfortunately this
now forces us to keep the lock too long for my taste).
Logic for this was missing from pull.c. For push.c it was missing if the
driver didn't support it. But even if the driver supported it (such as
with ao_alsa), strange behavior was observed by users. See issue #933.
Always check explicitly whether the AO is in paused mode, and if so,
don't drain.
Possibly fixes#933.
CC: @mpv-player/stable
Doesn't work quite right, and will pause for the latency duration after
seeking. Some users use --ao=null to disable audio (even though they
should probably use --no-audio), and this use-case is broken by this
issue too.
CC: @mpv-player/stable
Previous code was completly wrong. This still doesn't report the device
latency, but we report the buffer latency (as before the AO refactoring) and
the AudioUnit's latency (this is a new 'feature').
Apparently we can also report the device actual latency and we should also
calculate the actual sample rate of the audio device instead of using the
nominal sample rate, but I'll leave this for a later commit.
The mplayer1/2/mpv CoreAudio audio output historically contained both usage
of AUHAL APIs (these go through the CoreAudio audio server) and the Device
based APIs (used only for output of compressed formats in exclusive mode).
The latter is a very unwieldy and low level API and pretty much forces us to
write a lot of code for little workr. Also with the widespread of HDMI, the
actual need for outputting compressed audio directly to the device is getting
lower (it was very useful with S/PDIF for bandwidth constraints not allowing
a number if channels transmitted in LPCM).
Considering how invasive it is (uses hog/exclusive mode), the new AO
(`ao_coreaudio_device`) is not going to be autoprobed but the user will have
to select it.
Something like "char *s = ...; isdigit(s[0]);" triggers undefined
behavior, because char can be signed, and thus s[0] can be a negative
value. The is*() functions require unsigned char _or_ EOF. EOF is a
special value outside of unsigned char range, thus the argument to the
is*() functions can't be a char.
This undefined behavior can actually trigger crashes if the
implementation of these functions e.g. uses lookup tables, which are
then indexed with out-of-range values.
Replace all <ctype.h> uses with our own custom mp_is*() functions added
with misc/ctype.h. As a bonus, these functions are locale-independent.
(Although currently, we _require_ C locale for other reasons.)
While I'm not very fond of "const", it's important for declarations
(it decides whether a symbol is emitted in a read-only or read/write
section). Fix all these cases, so we have writeable global data only
when we really need.
So the device buffer can be refilled quickly. Fixes dropouts in certain
cases: if all data is moved from the soft buffer to the audio device
buffer, the waiting code thinks it has to enter the mode in which it
waits for new data from the decoder. This doesn't work, because the
get_space() logic tries to keep the total buffer size down. get_space()
will return 0 (or a very low value) because the device buffer is full,
and the decoder can't refill the soft buffer. But this means if the AO
buffer runs out, the device buffer can't be refilled from the soft
buffer. I guess this mess happened because the code is trying to deal
with both AOs with proper event handling, and AOs with arbitrary
behavior.
Unfortunately this increases latency, as the total buffered audio
becomes larger. There are other ways to fix this again, but not today.
Fixes#818.
Apparently this can happen. So actually only return from waiting if ALSA
excplicitly signals that new output is available, or if we are woken up
externally.
This did not flush remaining audio in the buffer correctly (in case an
AO has an internal block size). So we have to make the audio feed thread
to write the remaining audio, and wait until it's done.
Checking the avoid_ao_wait variable should be enough to be sure that all
data that can be written was written to the AO driver.
This code handles buggy AOs (even if all AOs are bug-free, it's good for
robustness). Move handling of it to the AO feed thread. Now this check
doesn't require magic numbers and does exactly what's it supposed to do.
Until now, we've always calculated a timeout based on a heuristic when
to refill the audio buffers. Allow AOs to do it completely event-based
by providing wait and wakeup callbacks.
This also shuffles around the heuristic used for other AOs, and there is
a minor possibility that behavior slightly changes in real-world cases.
But in general it should be much more robust now.
ao_pulse.c now makes use of event-based waiting. It already did before,
but the code for time-based waiting was also involved. This commit also
removes one awkward artifact of the PulseAudio API out of the generic
code: the callback asking for more data can be reentrant, and thus
requires a separate lock for waiting (or a recursive mutex).
There were subtle and minor race conditions in the pull.c code, and AOs
using it (jack, portaudio, sdl, wasapi). Attempt to remove these.
There was at least a race condition in the ao_reset() implementation:
mp_ring_reset() was called concurrently to the audio callback. While the
ringbuffer uses atomics to allow concurrent access, the reset function
wasn't concurrency-safe (and can't easily be made to).
Fix this by stopping the audio callback before doing a reset. After
that, we can do anything without needing synchronization. The callback
is resumed when resuming playback at a later point.
Don't call driver->pause, and make driver->resume and driver->reset
start/stop the audio callback. In the initial state, the audio callback
must be disabled.
JackAudio of course is different. Maybe there is no way to suspend the
audio callback without "disconnecting" it (what jack_deactivate() would
do), so I'm not trying my luck, and implemented a really bad hack doing
active waiting until we get the audio callback into a state where it
won't interfere. Once the callback goes from AO_STATE_WAIT to NONE, we
can be sure that the callback doesn't access the ringbuffer or anything
else anymore. Since both sched_yield() and pthread_yield() apparently
are not always available, use mp_sleep_us(1) to avoid burning CPU during
active waiting.
The ao_jack.c change also removes a race condition: apparently we didn't
initialize _all_ ao fields before starting the audio callback.
In ao_wasapi.c, I'm not sure whether reset really waits for the audio
callback to return. Kovensky says it's not guaranteed, so disable the
reset callback - for now the behavior of ao_wasapi.c is like with
ao_jack.c, and active waiting is used to deal with the audio callback.
In most places where af_fmt2bits is called to get the bits/sample, the
result is immediately converted to bytes/sample. Avoid this by getting
bytes/sample directly by introducing af_fmt2bps.