This is a small oversight. The client name (as set on command line
options or, more importantly, the client API) was not set when listing
devices e.g. via the "audio-device-list" property.
Might or might not fix#1578.
Also adjust the log level for an unrelated message.
(cherry picked from commit c152c59084)
Previously we let the user use the audio device ID, but this is not persistent
and can change when plugging in new devices. That of course made it quite
worthless for storing it as a user setting for GUIs, or for user scripts.
In theory getting the kAudioDevicePropertyDeviceUID can fail but it doesn't
on any of my devices, so I'm leaving the error reporting quite high and see if
someone complains.
The MSDN documentation for IsFormatSupported says a return code of
AUDCLNT_E_UNSUPPORTED_FORMAT means the function "succeeded but the
specified format is not supported in exclusive mode." This seems to
imply that the format is supported in shared mode, and that's what the
old code assumed, however try_format would incorrectly return success
with some drivers.
The remarks section of the documentation contradicts that assumption. It
says that in shared mode, if the audio engine does not support the
caller-specified format or any similar format, ppClosestMatch is set to
NULL and the function returns AUDCLNT_E_UNSUPPORTED_FORMAT. This is the
same as in exclusive mode, so treat AUDCLNT_E_UNSUPPORTED_FORMAT the
same regardless of opt_exclusive. In shared mode, the format selection
code will fall back to the mix format, which should always be supported.
Apparently, physically disconnecting the audio device (consider USB
audio) breaks the ALSA device handle forever. It will signal ENODEV.
Fortunately, it's easy for us to handle this, and we can just use
existing mechanisms that will make the playback core close and reopen
the AO. Whether the immediate reopening will actually succeeds really is
ALSA's problem, though.
In general, you need to check errno when using strtol(), but as far as I
know, strtol() won't reset errno on success. This has to be done
manually. The code could have failed sporadically if strtol() succeeded,
and errno was already set to one of the checked values.
(This strtol() still isn't fully error checked, but I don't know if it's
intentional, e.g. for parsing a numeric prefix only.)
Before this commit, ao_null was used as last fallback. This doesn't make
too much sense. Why would you decode audio just to discard it? Let audio
initialization fail instead. This also handles the weird but possible
corner-case that ao_null might fail initializing, in which case e.g.
ao_pcm could be autoselected. (This happened once, and had to be fixed
manually.)
This removes the slightly duplicated code for picking the required AO
driver if --audio-device forces one. Now --audio-device reuses the same
code as --ao for this.
As a consequence, ao_alloc_pb() and ao_create() can be merged into
ao_init(). Although the ao_init() argument list, which is already pretty
big, grows by one, it's better than having all these similar sounding
functions around.
Actually, I just wanted to do the change the following commit will do,
but I found this code was more of a mess than it had to be.
We must not try to remap channels with this. Whethever ALSA gives us,
and whatever we do with it, the result will probably be nonsense.
Untested, as I don't have the required hardware.
This used to be required to workaround PulseAudio bugs. Even later, when
the bugs were (partially?) fixed in PulseAudio, I had the feeling the
hacks gave better behavior. On the other hand, I couldn't actually
reproduce any bad behavior without the hacks lately. On top of this, it
seems our hacks sometimes perform much worse than PulseAudio's native
implementation (see #1430).
So disable the hacks by default, but still leave the code and the option
in case it still helps somewhere. Also, being able to blame PulseAudio's
code by using its native API is much easier than trying to debug our own
(mplayer2-derived) hacks.
* bits instead of bytes
* add valid_bits argument
* just pass in the mp_chmap and get the number and wavext channel map from that
* indicate valid bits in waveformat_to_str
* make appropriate accomodations in try_format
This message is printed when the audio device advertised a channel map,
but couldn't set it - which is probably a dmix bug (we'll never know,
ALSA doesn't take bug reports).
Print the requested map, so that the user (maybe) can make a connection
when seeing the message and the actually used channel map, which might
be less confusing. Or at least less useless.
There where 3 major errors in the previous code:
1) The kAudioDevicePropertyPreferredChannelLayout selector returns a single
layout not an array.
2) The check for AudioChannelLayout allocation size was wrong (didn't account
for variable sized struct).
3) Didn't query the kAudioDevicePropertyPreferredChannelsForStereo selector
since I didn't know about it's existence.
All of these are fixed.
Might help with #1367
AudioChannelLayout uses a trailing variable sized array so we need to
query CoreAudio for the size of the struct it is going to need (or the
conversion of that particular layout would fail).
Fixes#1366
snd_pcm_prepare() was not always called, which could result in an
infinite loop.
Whether snd_pcm_prepare() was actually called depended on whether the
device was a hw device (or other characteristics; depending on
snd_pcm_hw_params_can_pause()), and required real suspend (annoying for
testing), so it was somewhat tricky to reproduce without knowing these
things.
When setting the ALSA channel map, we never actually set the map we got
from ALSA directly, but convert it to mpv's, and then back to ALSA's.
mpv and ALSA use different conventions for mono, and there is already an
exception for ALSA->mpv, but not mpv->ALSA.
This was only added recently (c1e97161) as an attempt to minimize the
bad impact of channel layout device aliases. But use of these was
removed in commit 49df0132. Now this code does pretty much nothing, and
shouldn't be needed anymore. It does something when using spdif, but
this fallback won't work anyway.
The "old" method (before the ALSA channel map API) used device aliases
like "surround51" to set the channel layout. The "interesting" part was
that these devices usually redirect to a hardware device. This means
playing stereo would lead you to the "default" device (dmix), while e.g.
5.1 to "surround51", which automatically takes care of the fact that
dmix can't do 5.1.
This is pretty much nonsense, though. It shouldn't depend on the damn
input media file whether the player is going to use shared access (dmix)
or exclusive access (direct hw device).
As a consequence, by default ao_alsa will do only what dmix can do. If
the user actually wants multichannel, he has to select a suitable hw
device with --audio-device. From there on, the correct speaker mapping
will be ensured via the channel mapping API.
The change is preparation for making multichannel output the default (as
far as supported by the audio output API). Of the common APIs, only ALSA
messes up beyond repair, so I feel like this change is needed.
On ancient alsa-lib versions, only stereo and mono can be played with
this branch.
dmix reports channel layouts it doesn't support. The rest of the
technical part of the story is in the code comment.
This seems to be the only reasonable way to fallback from trying to
initialize certain devices (like dmix) with multichannel audio. We could
probably add support for such padding channels to our audio chain or to
ao_alsa itself, but this would probably be much more work than this
commit.
What dmix does is probably a bug. I've tried to report it to ALSA. Thay
have a link on their website to a bug tracker, but it's a dead link, and
has been for years. I've posted to alsa-devel, but received no reply.
I'm thus assuming this absolutely retarded behavior is by design, and
nothing will happen to improve upon it.
I'm considering sending Lennart Poettering a "thank you" email, because
with PulseAudio, multichannel audio just works (although some other
things just don't work).
Whether we print it as warning or error doesn't really matter; we
continue anyway. (I don't actually know what the implications of running
in non-blocking mode are; for what's it worth, when I tested with
explicitly changing to non-blocking, it seemed to work fine anyway, so
don't change that part.)
ALSA returns "FL" as channel layout when trying to play mono. mpv and
libavresample don't like this; in particular, using libavresample to
convert stereo to "FL" fails.
If no-block was given, the device would be opened with SND_PCM_NOBLOCK.
Also, after opening, blocking mode was unconditionally enabled anyway
with snd_pcm_nonblock(). Further, if opening with SND_PCM_NOBLOCK
failed, opening was retried without this flag.
This doesn't make any sense to me, and I've never heard of someone using
this suboption. I suspect it has to do with ancient ALSA bugs or API
caveats. Remove it and simplify the code.
ALSA is crap. It's impossible to make multichannel playback just do the
right thing. dmix (the default on most distros) can do stereo only, and
will refuse to play multichannel. On the other hand, if you try like mpv
(and mplayer) to open a multichannel device (like "surround51" etc.),
this will actually open a hardware device, which will either fail if
dmix is active, or block out dmix if opening succeeds.
This commit falls back to "default" (i.e. dmix) if opening a
multichannel device fails, which is a tiny step towards the right
behavior. (Although fixing it fully is impossible.)