1
0
mirror of https://github.com/mpv-player/mpv synced 2024-12-24 15:52:25 +00:00
Commit Graph

591 Commits

Author SHA1 Message Date
Stefano Pigozzi
d16e4b836a ao_coreaudio: remove useless comments 2014-07-02 21:43:08 +02:00
Stefano Pigozzi
0ffbd05e99 ao_coreaudio: rename init_lpcm -> init_audiounit 2014-07-02 21:43:08 +02:00
Stefano Pigozzi
80ec0ba6d0 ao_coreaudio: fill asbd with an helper function 2014-07-02 21:43:07 +02:00
Stefano Pigozzi
fa85bfde69 ao_coreaudio: split control to helper functions 2014-07-02 21:43:07 +02:00
Stefano Pigozzi
f317d24a39 ao_coreaudio: move device related functions to the new AO 2014-07-02 21:43:07 +02:00
Stefano Pigozzi
a8ef70b0f8 ao_coreaudio: remove useless call to print_asbd 2014-07-02 21:43:07 +02:00
Stefano Pigozzi
041557b639 ao_coreaudio: move spdif code to a new AO
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.
2014-07-02 21:43:07 +02:00
wm4
9a210ca2d5 Audit and replace all ctype.h uses
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.)
2014-07-01 23:11:08 +02:00
Mohammad Alsaleh
8b06fc86f3 af_volume: fix calculations including replay-gain
rgain is not an additive value. It's a multiplier/gain.

Previous behaviour produced negative level values in some cases
(when rgain < 1.0) which caused volume to be louder when its value
was lowered.

CC: @mpv-player/stable

Signed-off-by: Mohammad Alsaleh <CE.Mohammad.AlSaleh@gmail.com>
Signed-off-by: wm4 <wm4@nowhere>
2014-06-28 15:56:16 +02:00
Amos Onn
8593c4f70b ao_pcm: fix message strings
Signed-off-by: wm4 <wm4@nowhere>
2014-06-15 09:25:15 +02:00
Rudolf Polzer
ee2e91dce1 encode: get rid of the recursion that led to a deadlock.
Instead, the recursive call has been flattened away by instead
overwriting a parameter and continuing.
2014-06-12 11:42:00 +02:00
wm4
9a0baa4c53 audio: more detailed debugging output
Dump what the AO does on driver->play().
2014-06-12 00:55:13 +02:00
wm4
d07cd11b14 audio: don't wait when draining and paused
A corner case that could possibly lead to infinite waiting. Though
I'm not aware that this actually happened in practice.
2014-06-12 00:55:13 +02:00
wm4
7f7aa03eda ad_lavc: make option struct local
Similar to previous commit.
2014-06-11 01:39:51 +02:00
wm4
99f5fef0ea Add more const
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.
2014-06-11 00:39:14 +02:00
wm4
da89af1076 player: show "neutral" position markers for OSD bars
This commit implements them for volume and some video properties.
2014-06-08 23:52:58 +02:00
wm4
35f87dc692 audio/out/push: don't attempt to fill AO buffer when paused
Doing so will implicitly resume playback. Broken in commit 5929dc45.
2014-06-03 15:58:25 +02:00
wm4
b8cb860471 audio: prefer dsound over wasapi
ao_wasapi has too many subtle failures that were reported, but there's
nobody to fix them. ao_dsound seems to be more robust; so prefer it.
2014-06-01 19:00:44 +02:00
wm4
498c997474 player: hide audio/video codec and file format messages
None of these are very important usually. For error analysis, the plain
log is useless anyway, and this information is still printed with "-v".
2014-05-31 22:07:36 +02:00
wm4
9f6e8d64de ao_alsa: make device the first sub option
This is more convenient.
2014-05-31 01:40:12 +02:00
wm4
4fa3ffebfe audio/out/push: keep some extra buffer
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.
2014-05-31 01:26:50 +02:00
wm4
9c9f23eee9 ao_alsa: reduce spurious wakeups
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.
2014-05-30 23:54:11 +02:00
wm4
8ba346a554 audio/out/push: handle draining correctly
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.
2014-05-30 02:17:15 +02:00
wm4
c79689206c audio: change handling of an EOF corner case
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.
2014-05-30 02:16:43 +02:00
wm4
b7c6981278 ao_alsa: use poll() to wait for device
This means the audio feed thread is woken up exactly at the time new
data is needed, instead of using a time-based heuristic.
2014-05-30 02:16:35 +02:00
wm4
5dcfc4f604 audio/out/push: add a way to wait for the audio device with poll()
Will be used for ALSA.
2014-05-30 02:16:25 +02:00
wm4
5929dc458f audio/out/push: add mechanism for event-based waiting
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).
2014-05-30 02:15:47 +02:00
wm4
35aba9675d audio/out: adjust documentation comments 2014-05-30 02:15:38 +02:00
wm4
c36faf8c49 audio/out/pull: remove race conditions
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.
2014-05-29 02:24:17 +02:00
Marcoen Hirschberg
696733d077 ad_lavc: don't overwrite lavc bitrate
If the bitrate is already known in avcodec there is no need to overwrite
it again with the value from sh_audio.
2014-05-28 21:38:20 +02:00
Marcoen Hirschberg
1fa48a2452 ao_wasapi: simplify nAvgBytesPerSec calculation
Calculate nBlockAlign seperately to reuse in the calculation of
nAvgBytesPerSec.
2014-05-28 21:38:15 +02:00
Marcoen Hirschberg
31a10f7c38 af_fmt2bits: change to af_fmt2bps (bytes/sample) where appropriate
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.
2014-05-28 21:38:00 +02:00
Marcoen Hirschberg
434242adb5 audio: rename i_bps to 'bitrate' to avoid confusion
Since i_bps now contains bits/sec, rename it to reflect this change.
2014-05-28 21:37:50 +02:00
Marcoen Hirschberg
6e58b20cce audio: change values from bytes-per-second to bits-per-second
The i_bps members of the sh_audio and dev_video structs are mostly used
for displaying the average audio and video bitrates. Keeping them in
bits-per-second avoids truncating them to bytes-per-second and changing
them back lateron.
2014-05-28 21:37:44 +02:00
wm4
8e7cf4bc99 atomics: switch to C11 stdatomic.h
In my opinion, we shouldn't use atomics at all, but ok.

This switches the mpv code to use C11 stdatomic.h, and for compilers
that don't support stdatomic.h yet, we emulate the subset used by mpv
using the builtins commonly provided by gcc and clang.

This supersedes an earlier similar attempt by Kovensky. That attempt
unfortunately relied on a big copypasted freebsd header (which also
depended on much more highly compiler-specific functionality, defined
reserved symbols, etc.), so it had to be NIH'ed.

Some issues:
- C11 says default initialization of atomics "produces a valid state",
  but it's not sure whether the stored value is really 0. But we rely on
  this.
- I'm pretty sure our use of the __atomic... builtins is/was incorrect.
  We don't use atomic load/store intrinsics, and access stuff directly.
- Our wrapper actually does stricter typechecking than the stdatomic.h
  implementation by gcc 4.9. We make the atomic types incompatible with
  normal types by wrapping them into structs. (The FreeBSD wrapper does
  the same.)
- I couldn't test on MinGW.
2014-05-21 02:21:18 +02:00
wm4
f47a4fc3d9 threads: use mpv time for mpthread_cond_timedwait wrapper
Use the time as returned by mp_time_us() for mpthread_cond_timedwait(),
instead of calculating the struct timespec value based on a timeout.
This (probably) makes it easier to wait for a specific deadline.
2014-05-18 19:20:32 +02:00
wm4
c78b8b2c0c audio/out: fix previous commit
This didn't quite work. The main issue was that get_space tries to be
clever to reduce overall buffering, so it will cause the playloop to
decode and queue only as much audio as is needed to refill the AO in
reasonable time. Also, even if ignoring the problem, the logic of the
previous commit was slightly broken. (This required a few retries,
because I couldn't reproduce the issue on my own machine.)
2014-05-11 20:51:49 +02:00
wm4
665c8b59be audio/out: avoid wakeup feedback loop
When the audio buffer went low, but could not be refilled yet, it could
happen that the AO playback thread and the decode thread could enter a
wakeup feedback loop, causing up to 100% CPU usage doing nothing. This
happened because the decoder thread would wake up the AO thread when
writing 0 bytes of newly decoded data, and the AO thread in reaction
wakes up the decoder thread after writing 0 bytes to the AO buffer.

Fix this by waking up the decoder thread only if data was actually
played or queued. (This will still cause some redundant wakeups, but
will eventually settle down, reducing CPU usage close to ideal.)
2014-05-11 19:00:05 +02:00
wm4
77ce54c698 mixer: make code more readable
You wouldn't have guessed that the bottom-most "level[i] = 0.f;" line
was actually required. It even confused cppcheck.
2014-05-11 16:41:19 +02:00
wm4
09ecf7a68a audio/out: more debugging info for --dump-stats 2014-05-11 16:41:19 +02:00
Stefano Pigozzi
b4e598badf ao_coreaudio: skip unknown channel labels
I don't think this is really a very good idea because it is conceptually
incorrect but other prominent multimedia programs use this approach
(VLC and xbmc), and it seems to make the conversion more robust in certain
cases.

For example it has been reported, that configuring a receiver that can output
7.1 to output 5.1, will make CoreAudio report 8 channel descriptions, and the
last 2 descriptions will be tagged kAudioChannelLabel_Unknown.

Fixes #737
2014-05-10 14:07:45 +02:00
Stefano Pigozzi
1a4f4f80bf ao_coreaudio: remove useless code
This code doesn't actually makes much of a difference, and the AudioUnit
mostly wants layout tags anyway.
2014-05-10 14:07:45 +02:00
Stefano Pigozzi
2a0a13425f ao_coreaudio: don't fallback to full waveext
The code was falling back to the full waveext chmap_sel when less than 2
channels were detected. This new code is slightly more correct since it only
fills the chmap_sel with the stereo or mono chmap in the fallback case.
2014-05-10 14:07:45 +02:00
Stefano Pigozzi
39b316ff06 ao_coreaudio: cosmetic change of loop ending condition 2014-05-10 14:07:45 +02:00
Stefano Pigozzi
eb9d7d5c78 ao_coreaudio: print an error when channel mapping fails 2014-05-10 14:07:45 +02:00
Stefano Pigozzi
b46ffaec7c ao_coreaudio: use description-based channel layouts
CoreAudio supports 3 kinds of layouts: bitmap based, tag based, and speaker
description based (using either channel labels or positional data).

Previously we tried to convert everything to bitmap based channel layouts,
but it turns out description based ones are the most generic and there are
built-in CoreAudio APIs to perform the conversion in this direction.

Moreover description based layouts support waveext extensions (like SDL and
SDR), and are easier to map to mp_chmaps.
2014-05-10 14:07:45 +02:00
Stefano Pigozzi
e2f26f01fe ao_coreaudio: pass layout by reference to logging function
Apparently passing the struct by value somehow messed with the value of some
fields.
2014-05-10 14:07:45 +02:00
Stefano Pigozzi
e7d1c12131 chmap_sel: add channel replacement for sl/sr <-> sdl/sdr
This can be use useful for the 7.1 rear layout. In particular it looks like
OS X likes to use sdl/sdr as opposed to sl/sr.
2014-05-10 14:07:45 +02:00
wm4
fc385baf02 encode: fix PTS unit mismatch
This used MP_NOPTS_VALUE to compare with ffmpeg-style int64_t PTS
values. This probably happened to work, because both constants use the
same value.
2014-05-10 10:44:16 +02:00
wm4
b7669d533b mixer: don't restore volume with different --softvol-max settings
Changing --softvol-max and then resuming would change the volume level
on resume to something different than the original volume. This is
because the user volume setting is always between 0-100, and 100
corresponds to --softvol-max gain.

Avoid that changing -softvol-max and resuming an older file could lead
to a too loud volume level by refusing to restore if --softvol-max
changed.
2014-05-06 20:09:36 +02:00