Commit Graph

135 Commits

Author SHA1 Message Date
wm4 cc52a03401 audio: slightly simplify pull underrun message printing
A previous commit moved the underrun reporting to report_underruns(),
and called it from get_space(). One reason was that I worried about
printing a log message from a "realtime" callback, so I tried to move it
out of the way. (Though there's little justification other than a bad
feeling. While an older version of the pull code tried to avoid any
mutexes at all in the callback to accommodate "requirements" from APIs
like jackaudio, we gave up on that. Nobody has complained yet.)

Simplify this and move underrun reporting back to the callback. But
instead of printing the message from there, move the message into the
playloop. Change the message slightly, because ao->log is inaccessible,
and without the log prefix (e.g. "[ao/alsa]"), some context is missing.
2020-02-13 18:02:16 +01:00
wm4 5bf433b16f player: consider audio buffer if AO driver does not report underruns
AOs can report audio underruns, but only ao_alsa and ao_sdl (???)
currently do so. If the AO was marked as not reporting it, the cache
state was used to determine whether playback was interrupted due to slow
input.

This caused problems in some cases, such as video with very low video
frame rate: when a new frame is displayed, a new frame has to be
decoded, and since there it's so much further into the file (long frame
durations), the cache gets into an underrun state for a short moment,
even though both audio and video are playing fine. Enlarging the audio
buffer didn't help.

Fix this by making all AOs report underruns. If the AO driver does not
report underruns, fall back to using the buffer state.

pull.c behavior is slightly changed. Pull AOs are normally intended to
be used by pseudo-realtime audio APIs that fetch an audio buffer from
the API user via callback. I think it makes no sense to consider a
buffer underflow not an underrun in any situation, since we return
silence to the reader. (OK, maybe the reader could check the return
value? But let's not go there as long as there's no implementation.)
Remove the flag from ao_sdl.c, since it just worked via the generic
mechanism. Make the redundant underrun message verbose only.

push.c seems to log a redundant underflow message when resuming (because
somehow ao_play_data() is called when there's still no new data in the
buffer). But since ao_alsa does its own underrun reporting, and I only
use ao_alsa, I don't really care.

Also in all my tests, there seemed to be a rather high delay until the
underflow was logged (with audio only). I have no idea why this happened
and didn't try to debug this, but there's probably something wrong
somewhere.

This commit may cause random regressions.

See: #7440
2020-02-13 01:32:58 +01:00
wm4 f3c498c7f1 ao: avoid unnecessary wakeups
If ao_add_events() is used, but all events flags are already set, then
we don't need to wakeup the core again.

Also, make the underrun message "exact" by avoiding the race condition
mentioned in the comment.

Avoiding redundant wakeups is not really worth the trouble, and it's
actually just a bonus in the change making the ao_underrun_event()
function return whether a new underrun was set, which is needed by the
following commit.
2020-02-13 01:28:14 +01:00
wm4 025e77eaf1 audio: react to --ao and --audio-buffer runtime changes
Before this commit, runtime changes were only applied if something else
caused audio to be reinitialized. Now setting them reinitializes audio
explicitly.
2019-12-27 17:56:22 +01:00
Aman Gupta 03fbb57bd9 audio: add ao_audiotrack for android 2019-11-19 12:10:26 -08:00
Stefano Pigozzi 899e0bd16b input: add gamepad support through SDL2
The code is very basic:

- only handles gamepads, could be extended for generic joysticks in the
  future.
- only has button mappings for controllers natively supported by SDL2.
  I heard more can be added through env vars, there's also ways to load
  mappings from text files, but I'd rather not go there yet. Common ones
  like Dualshock are supported natively.
- analog buttons (TRIGGER and AXIS) are mapped to discrete buttons using an
  activation threshold.
- only supports one gamepad at a time. the feature is intented to use
  gamepads as evolved remote controls, not play multiplayer games in mpv :)
2019-10-23 09:40:30 +02:00
wm4 c84ec02128 ao: add API for underrun reporting
AOs can now call ao_underrun_event() (in any context) if an underrun has
happened. It will print a message.

This will be used in the following commits. But for now, audio.c only
clears the underrun bit, so that subsequent underruns still print the
warning message.

Since the underrun flag will be used in fragile ways by the playback
state machine, there is the "reports_underruns" field that signals
strong support for underrun reporting. (Otherwise, underrun events will
not be used by it.)
2019-10-11 19:25:45 +02:00
wm4 fb22bf2317 ao: use a local option struct
Instead of accessing MPOpts.
2018-05-24 19:56:35 +02:00
wm4 e02c9b9902 build: make encoding mode non-optional
Makes it easier to not break the build by confusing the ifdeffery.
2018-05-03 01:08:44 +03:00
wm4 0ab3184526 encode: get rid of the output packet queue
Until recently, ao_lavc and vo_lavc started encoding whenever the core
happened to send them data. Since audio and video are not initialized at
the same time, and the muxer was not necessarily opened when the first
encoder started to produce data, the resulting packets were put into a
queue. As soon as the muxer was opened, the queue was flushed.

Change this to make the core wait with sending data until all encoders
are initialized. This has the advantage that we don't need to queue up
the packets.
2018-05-03 01:08:44 +03:00
wm4 f40e0cb0f2 ao: do not allow actual buffer size of 0
You can use --audio-buffer=0 to minimize the audio buffer size. But if
the AO reports no device buffer size (like e.g. ao_jack does), then the
buffer size is actually 0, and playback can never work properly.

Make it fallback to a size of 1, which is unlikely to work properly, but
you get what you asked for, instead of a freeze.
2018-03-08 17:12:32 -08:00
wm4 1dcf511376 build: drop support for SDL1
For some reason it was supported for ao_sdl because we've only used SDL1
API.
2018-02-13 17:45:29 -08:00
wm4 b56f109219 ao: minor simplification to gain processing code
Cosmetic move of a variable, and consider an adjustment below 1/256 or
so not worth applying (even in the float case).
2017-11-30 01:31:37 +01:00
wm4 6f8cf73f54 ao: simplify hack for float atomics
stdatomic.h defines no atomic_float typedef. We can't just use _Atomic
unconditionally, because we support compilers without C11 atomics. So
just create a custom atomic_float typedef in the wrapper, which uses
_Atomic in the C11 code path.
2017-11-30 01:20:03 +01:00
wm4 d725630b5f audio: add audio softvol processing to AO
This does what af_volume used to do. Since we couldn't relicense it,
just rewrite it. Since we don't have a new filter mechanism yet, and the
libavfilter is too inconvenient, do applying the volume gain in ao.c
directly. This is done before handling the audio data to the driver.

Since push.c runs a separate thread, and pull.c is called asynchronously
from the audio driver's thread, the volume value needs to be
synchronized. There's no existing central mutex, so do some shit with
atomics. Since there's no atomic_float type predefined (which is at
least needed when using the legacy wrapper), do some nonsense about
reinterpret casting the float value to an int for the purpose of atomic
access. Not sure if using memcpy() is undefined behavior, but for now I
don't care.

The advantage of not using a filter is lower complexity (no filter auto
insertion), and lower latency (gain processing is done after our
internal audio buffer of at least 200ms).

Disavdantages include inability to use native volume control _before_
other filters with custom filter chains, and the need to add new
processing for each new sample type.

Since this doesn't reuse any of the old GPL code, nor does indirectly
rely on it, volume and replaygain handling now works in LGPL mode.

How to process the gain is inspired by libavfilter's af_volume (LGPL).
In particular, we use exactly the same rounding, and we quantize
processing for integer sample types by 256 steps. Some of libavfilter's
copyright may or may not apply, but I think not, and it's the same
license anyway.
2017-11-29 21:30:51 +01:00
wm4 b6af3db568 command: drop "audio-out-detected-device" property
Coreaudio stopped setting it a few releases ago (66a958bb4f). There is
not much of a user- or API-visible change, so remove it without
deprecation.
2017-10-09 15:48:47 +02:00
wm4 1f593beeb4 audio: introduce a new type to hold audio frames
This is pretty pointless, but I believe it allows us to claim that the
new code is not affected by the copyright of the old code. This is
needed, because the original mp_audio struct was written by someone who
has disagreed with LGPL relicensing (it was called af_data at the time,
and was defined in af.h).

The "GPL'ed" struct contents that surive are pretty trivial: just the
data pointer, and some metadata like the format, samplerate, etc. - but
at least in this case, any new code would be extremely similar anyway,
and I'm not really sure whether it's OK to claim different copyright. So
what we do is we just use AVFrame (which of course is LGPL with 100%
certainty), and add some accessors around it to adapt it to mpv
conventions.

Also, this gets rid of some annoying conventions of mp_audio, like the
struct fields that require using an accessor to write to them anyway.

For the most part, this change is only dumb replacements of mp_audio
related functions and fields. One minor actual change is that you can't
allocate the new type on the stack anymore.

Some code still uses mp_audio. All audio filter code will be deleted, so
it makes no sense to convert this code. (Audio filters which are LGPL
and which we keep will have to be ported to a new filter infrastructure
anyway.) player/audio.c uses it because it interacts with the old filter
code. push.c has some complex use of mp_audio and mp_audio_buffer, but
this and pull.c will most likely be rewritten to do something else.
2017-08-16 21:10:54 +02:00
Kevin Mitchell e9f729c17c audio/out: fix comment typo 2017-07-09 13:46:13 -07:00
wm4 90dd229871 audio/out: add helper code to do 24 bit conversion in AO
I plan to remove the S24 sample formats in mpv. It seems like we should
still support this _somehow_ in AOs though. So the idea is to convert
the data to more obscure representations (that would not be useful for
filtering etc. anyway) within the AO.

This commit adds helper to enable this. ao_convert_fmt is meant to
provide mechanisms for this, rather than a generic audio format
description (as the latter leads only to overly generic misery). The
conversion also supports only cases which we think will be needed at
all.

The main advantage of this approach is that we get S24 out of sight,
and that we could support other crazy formats (like S20). The main
disadvantage is that usually S32 will be selected (if both S32 and S24
are available), and there's no user control to force S24. That doesn't
really matter though, and at worst makes testing harder or will lead
to unpleasant arguments with audiophiles (they'd be wrong anyway).

ao_convert_fmt.pad_lsb is ignored, although if we ever find a case in
which playing S32 with data in the LSBs breaks when playing it as padded
24 bit format. (For example, WAVEFORMATEXTENSIBLE recommends setting the
unused bits to 0 if wValidBitsPerSample implies LSB padding.)
2017-07-07 17:54:05 +02:00
wm4 037c37519b audio/out: require AO drivers to report period size and correct buffer
Before this change, AOs could have internal alignment, and play() would
not consume the trailing data if the size passed to it is not aligned.
Change this to require AOs to report their alignment (via period_size),
and make sure to always send aligned data.

The buffer reported by get_space() now always has to be correct and
reliable. If play() does not consume all data provided (which is bounded
by get_space()), an error is printed.

This is preparation for potential further AO changes.

I casually checked alsa/lavc/null/pcm, the other AOs might or might not
work.
2017-06-25 15:57:43 +02:00
wm4 7840125e22 audio/out: change license of some core files to LGPL
All contributors of the current code have agreed. ao.c requires a
"driver" entry for each audio output - we assume that if someone who
didn't agree to LGPL added a line, it's fine for ao.c to be LGPL
anyway. If the affected audio output is not disabled at compilation
time, the resulting binary will be GPL anyway, and ootherwise the
code is not included.

The audio output code itself was inspired or partially copied from
libao in 7a2eec4b59 (thus why MPlayer's audio code is named libao2).
Just to be sure we got permission from Aaron Holtzman, Jack Moffitt, and
Stan Seibert, who according to libao's SVN history and README are the
initial author. (Something similar was done for libvo, although the
commit relicensing it forgot to mention it.)

242aa6ebd40: anders mostly disagreed with the LGPL relicensing, but we
got permission for this particular commit.

0ef8e555735: nick could not be reached, but the include statement was
removed again anyway.

879e05a7c17: iive agreed to LGPL v3+ only, but this line of code was
removed anyway, so ao_null.c can be LGPL v2.1+.

9dd8f241ac2: patch author could not be reached, but the corresponding
code (old slave mode interface) was completely removed later.
2017-05-20 11:43:57 +02:00
wm4 6b9d3f4f7b audio: lower "Disabling multichannel output." warning to verbose
Not sure why it was a warning in the first place.
2017-04-02 17:23:11 +02:00
Kevin Mitchell df30b217d9 ao: never set ao->device = ""
For example, previously, --audio-device='alsa/' would provide ao->device="" to
the alsa driver in spite of the fact that this is an already parsed option. To
avoid requiring a check of ao->device[0] in every driver, make sure this never
happens.
2017-02-20 22:56:30 -08:00
wm4 06619f53a8 ao: fix potential NULL deref in ao_device_list_add()
Probably didn't happen in practice, but anyway.

Found by coverity.
2017-02-20 13:50:37 +01:00
wm4 1a2319f3e4 options: remove deprecated sub-option handling for --vo and --ao
Long planned. Leads to some sanity.

There still are some rather gross things. Especially g_groups is ugly,
and a hack that can hopefully be removed. (There is a plan for it, but
whether it's implemented depends on how much energy is left.)
2016-11-25 21:17:25 +01:00
wm4 a2b93e0c27 audio: make empty device ID mean default device
This will make it easier for AOs to add explicit default device entries.
(See next commit.)

Hopefully this change doesn't lead accidentally to bogus "Default"
entries to appear, but then it can only happen if the device ID is
empty, which would mean the underlying audio API returned bogus entries.
2016-11-14 13:42:41 +01:00
wm4 84513ba58b audio: avoid returning audio-device-list entries without description
Use the device name as fallback. This is ugly, but still better than
skipping the description entirely. This can be an issue on ALSA, where
the API can return entries without proper description.
2016-11-14 13:33:53 +01:00
Aman Gupta 3f5b41dfa3 audio/out: add AudioUnit output driver for iOS 2016-11-01 16:25:40 +01:00
wm4 b8ade7c99b player, ao, vo: don't call mp_input_wakeup() directly
Currently, calling mp_input_wakeup() will wake up the core thread (also
called the playloop). This seems odd, but currently the core indeed
calls mp_input_wait() when it has nothing more to do. It's done this way
because MPlayer used input_ctx as central "mainloop".

This is probably going to change. Remove direct calls to this function,
and replace it with mp_wakeup_core() calls. ao and vo are changed to use
opaque callbacks and not use input_ctx for this purpose. Other code
already uses opaque callbacks, or has legitimate reasons to use
input_ctx directly (such as sending actual user input).
2016-09-16 14:37:48 +02:00
wm4 633eb30cbe options: add automagic hack for handling sub-option deprecations
I decided that it's too much work to convert all the VO/AOs to the new
option system manually at once. So here's a shitty hack instead, which
achieves almost the same thing. (The only user-visible difference is
that e.g. --vo=name:help will list the sub-options normally, instead of
showing them as deprecation placeholders. Also, the sub-option parser
will verify each option normally, instead of deferring to the global
option parser.)

Another advantage is that once we drop the deprecated options,
converting the remaining things will be easier, because we obviously
don't need to add the compatibility hacks.

Using this mechanism is separate in the next commit to keep the diff
noise down.
2016-09-05 21:26:39 +02:00
wm4 4ab860cddc options: add a mechanism to make sub-option replacement slightly easier
Instead of requiring each VO or AO to manually add members to MPOpts and
the global option table, make it possible to register them automatically
via vo_driver/ao_driver.global_opts members. This avoids modifying
options.c/options.h every time, including having to duplicate the exact
ifdeffery used to enable a driver.
2016-09-05 21:04:17 +02:00
wm4 a85eecfe40 ao_alsa: change sub-options to global options
Same deal as with vo_opengl.

Also edit the outdated information about multichannel output a little.
2016-09-02 21:21:47 +02:00
wm4 4fa6bcbb90 m_config: add helper function for initializing af/ao/vf/vo suboptions
Normally I'd prefer a bunch of smaller functions with fewer parameters
over a single function with a lot of parameters. But future changes will
require messing with the parameters in a slightly more complex way, so a
combined function will be needed anyway. The now-unused "global"
parameter is required for later as well.
2016-09-02 14:49:34 +02:00
wm4 6b4f560f3c vo, ao: disable positional parameter suboptions
Positional parameters cause problems because they can be ambiguous with
flag options. If a flag option is removed or turned into a non-flag
option, it'll usually be interpreted as value for the first sub-option
(as positional parameter), resulting in very confusing error messages.
This changes it into a simple "option not found" error.

I don't expect that anyone really used positional parameters with --vo
or --ao. Although the docs for --ao=pulse seem to encourage positional
parameters for the host/sink options, which means it could possibly
annoy some PulseAudio users.

--vf and --af are still mostly used with positional parameters, so this
must be a configurable option in the option parser.
2016-09-01 14:21:32 +02:00
wm4 eab92cec60 player: add --audio-stream-silence
Completely insane that this has to be done. Crap for compensating HDMI
crap.
2016-08-09 17:09:29 +02:00
wm4 0b144eac39 audio: use --audio-channels=auto behavior, except on ALSA
This commit adds an --audio-channel=auto-safe mode, and makes it the
default. This mode behaves like "auto" with most AOs, except with
ao_alsa. The intention is to allow multichannel output by default on
sane APIs. ALSA is not sane as in it's so low level that it will e.g.
configure any layout over HDMI, even if the connected A/V receiver does
not support it. The HDMI fuckup is of course not ALSA's fault, but other
audio APIs normally isolate applications from dealing with this and
require the user to globally configure the correct output layout.

This will help with other AOs too. ao_lavc (encoding) is changed to the
new semantics as well, because it used to force stereo (perhaps because
encoding mode is supposed to produce safe files for crap devices?).
Exclusive mode output on Windows might need to be adjusted accordingly,
as it grants the same kind of low level access as ALSA (requires more
research).

In addition to the things mentioned above, the --audio-channels option
is extended to accept a set of channel layouts. This is supposed to be
the correct way to configure mpv ALSA multichannel output. You need to
put a list of channel layouts that your A/V receiver supports.
2016-08-04 20:49:20 +02:00
wm4 deb1c3c7a8 audio: don't add default entry to audio-device-list if AO support listing
In such cases there isn't really a reason to do so, and using such an
entry would probably fail anyway.

Also convenient for the following commit.
2016-06-29 17:38:57 +02:00
Ilya Zhuravlev 72aea5a12b ao: initial OpenSL ES support
OpenSL ES is used on Android. At the moment only stereo output is
supported. Two options are supported: 'frames-per-buffer' and
'sample-rate'. To get better latency the user of libmpv should pass
values obtained from AudioManager.getProperty(PROPERTY_OUTPUT_FRAMES_PER_BUFFER)
and AudioManager.getProperty(PROPERTY_OUTPUT_SAMPLE_RATE).
2016-02-27 00:00:36 +01:00
Dmitrij D. Czarkoff ea442fa047 mpv_talloc.h: rename from talloc.h
This change helps avoiding conflict with talloc.h from libtalloc.
2016-01-11 21:05:55 +01:00
wm4 3e90a5fe81 ao_dsound: remove this audio output
It existed for XP-compatibility only. There was also a time where
ao_wasapi caused issues, but we're relatively confident that ao_wasapi
works better or at least as good as ao_dsound on Windows Vista and
later.
2016-01-06 13:52:15 +01:00
wm4 eec844a06e ao: disambiguate default device list entries
If there were many AO drivers without device selection, this added a
"Default" entry for each AO. These entries were not distinguishable, as
the device list feature is meant not to require to display the "raw"
device name in GUIs.

Disambiguate them by adding the driver name. If the AO is the first, the
name will remain just "Default". (The condition checks "num > 1",
because the very first entry is the dummy for AO autoselection.)
2015-11-27 14:42:10 +01:00
wm4 ec27d573f4 audio: always log channel maps before determining final map
Until now, this was done only in debug verbosity, while some AOs logged
equivalent information in verbose mode. Clean this up.
2015-10-26 15:52:08 +01:00
wm4 54fbda2ba4 audio: add option for falling back to ao_null
The manpage entry explains this.

(Maybe this option could be always enabled and removed. I don't quite
remember what valid use-cases there are for just disabling audio
entirely, other than that this is also needed for audio decoder init
failure.)
2015-10-05 19:12:23 +02:00
wm4 e694d67366 ao: rework audio output driver probing
Make the code a bit more uniform. Always build a "dummy" audio output
list before probing, which means that opening preferred devices and
pure auto-probing is done with the same code. We can drop the second
ao_init() call.

This also makes the next commit easier, which wants to selectively
fallback to ao_null. This could have been implemented by passing a
different requested audio output list (instead of reading it from
MPOptions), but I think it's better if this rather special feature
is handled internally in the AO code. This also makes sure the AO
code can handle its own options (such as the audio output list) in
a self-contained way.
2015-10-05 19:10:22 +02:00
wm4 fc79fd0474 ao: don't pass along AO arguments when redirecting
Only causes problems.
2015-07-03 19:28:01 +02:00
wm4 6147bcce35 audio: fix format function consistency issues
Replace all the check macros with function calls. Give them all the
same case and naming schema.

Drop af_fmt2bits(). Only af_fmt2bps() survives as af_fmt_to_bytes().

Introduce af_fmt_is_pcm(), and use it in situations that used
!AF_FORMAT_IS_SPECIAL. Nobody really knew what a "special" format
was. It simply meant "not PCM".
2015-06-26 23:06:37 +02:00
wm4 5a3cdb8f1e audio: output human-readable channel layouts too
This gets you the "logical" channel layout, instead of the exact thing
we're sending to the AO. (Tired of the cryptic shit ALSA gives me.)
2015-06-25 19:10:24 +02:00
wm4 5d71188c99 ao: standardize channel layout name in debug output further 2015-06-25 13:15:32 +02:00
wm4 37d505f363 ao: allow ao_uninit(NULL) 2015-06-02 21:03:04 +02:00
wm4 ca9964a4fb ao: make better use of atomics
The main reason for this was compatibility; but some associated problems
have been solved in the previous commit.
2015-05-11 23:27:41 +02:00