Make sure that subtraction of performance counters is done correctly.
Follow the *exact* instructions for converting performance counter to something
comparable to the QPCposition returned by IAudioClient::GetPosition
https://msdn.microsoft.com/en-us/library/windows/desktop/dd370889%28v=vs.85%29.aspx
Also make sure that subtraction of unsigned integers is stored into a signed
integer to avoid nastiness. Also be more careful about overflow in the
conversion of the device position into number of samples.
Avoid casting mp_time_us() to a double, and use llrint to convert the
double precision delay_us back to integer for ao_read_data.
Finally, actually check the return value of ao_read_data and add a verbose
message if it is not the expected value. Unfortunately,
there is no way to tell WASAPI when this happens since the frame_count in
ReleaseBuffer must match GetBuffer.
Do not try and set/get master volume in exclusive if there is no
hardware support. This would just uselessly change the master slider,
but have no effect on the actual volume.
Furthermore if getting hardware volume support information fails, then assume
it has none.
It was complicated and not even very intuitive to the user.
If you are controlling the master volume, you just have to be
prepared to deal with the consequences.
A manually added af_volume could lead to muted audio when switching to a
new file. af_volume keeps the last volume set by AF_CONTROL_SET_VOLUME
to return it with AF_CONTROL_GET_VOLUME, but the initial value is 0. So
the mixer volume was forced to 0 when unintializing the filter chain and
reading back the previously set volume.
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.)
Of course, only FFmpeg has av_clipd(), while Libav does not. (Nevermind
that it doesn't do much more than the mpv MPCLAMP() macro. Supposedly,
libavutil can provide optimized platform-specific versions for av_clip*,
but of course nothing actually does for av_clipf() or av_clipd().)
libswresample doesn't do it - although it should, but the patch is stuck
in limbo.
Probably reduces problems with artifacts on downmixing in some cases.
Remove known useless device entries from the --audio-device list (and
corresponding property). Do this because the list is supposed to be a
high level list of devices the user can select. ALSA does not provide
such a list (in an useable manner), and ao_alsa.c is still in the best
position to improve the situation somewhat.
The ALSA doxygen says:
IOID - input / output identification ("Input" or "Output"), NULL
means both
This bug was blatantly introduced with commit cf94fce4.
Apparently, some audio drivers do not support the DTS subtype, but
passthrough works anyway if the AC3 subtype is set. Just retry with
AC3 if the proper format doesn't work. The audio device which
exposed this behavior reported itself as
"M601d-A3/A3R (Intel(R) Display Audio)".
xbmc/kodi even always passes DTS as AC3.
Just set the ratio directly by working around the intended semantics of
the API function. The silly rounding stuff we had isn't needed anymore
(and not entirely correct anyway).
Note that since the compensation is virtually active forever, we need to
reset if it's not needed. So always run this code to be sure to reset
it.
Also note that libswresample itself had a precision issue, until it
was fixed in FFmpeg commit 351e625d.
Deal with jittering Matroska crap timestamps. This reuses the mechanism
that is needed for frames without PTS, and adds a heuristic to it. If
the interpolated timestamp is less than 1ms away from the real one, it
might be due to Matroska timestamp rounding (or other file formats with
such rounding, or files remuxed from Matroska).
While there actually isn't much of a need to do this (audio PTS
jittering by such a low amount doesn't negatively influence much), it
helps with identifying jitter from other sources.
Instead of requiring the decoder to set the PTS directly on the
dec_audio context (including handling absence of PTS etc.), transfer the
packet PTS to the decoded audio frame. Marginally simpler, and gives
more control to the generic code.
Essentially we'd use something random, just because it's part of the srt
of traditionally used ALSA channel mappings. But each driver can do its
own things.
This doesn't let me sleep at night, so remove it.
This could accidentally change some spdif formats to AAC (because AAC is
the first on the list and will match first). spdif formats are
inherently uninterchangeable, so treat them as their own class of
formats (like int vs. float).
Might fix some issues with ao_wasapi.c.
Actually, it didn't really require that before (most work was avoided),
but some bits had to be run anyway. Separate the speed change into a
light-weight function, which merely updates already created filters, and
a heavy-weight one which messes with filter insertion.
This also happens to fix the case where the filters would "forget" the
current speed (force resampling, change speed, hit a volume control to
force af_volume insertion - it will reset speed and desync).
Since we now always run the light-weight function, remove the
af_scaletempo verbose message that is printed on speed setting. Other
than that, all setters are cheap.
For some reason, the encoder didn't like that the AVPacket already had
fields set. I'm not quite sure, but this might just be invalid API
usage. Do it as it's recommended.
We need to effectively swap the last channel pair. See commit 4e358a96
and 5a18c5ea for details.
Doing this seems rather strange, as 7.1 just extends 5.1 with 2 new
speakers, and 5.1 doesn't need this change. Going by the HDMI standard
and the Intel HDA sources (cited in the referenced commits), it also
looks like 7.1 should simply append two channels to 5.1 as well. But
swapping them is apparently correct. This is also what XBMC does. (I
didn't find any other applications doing 7.1 PCM using the ALSA channel
map API. VLC seems to ignore the 7.1 case.) Testing reveals that at
least the end result is correct.
"Normal" ALSA 7.1 is unaffected by this, as it reports a different
(and saner) channel layout.
Instead of constructing an ALSA channel map from mpv ones from scratch,
try to find the original ALSA channel map again. Th result is that we
need to convert channel maps only in one direction. If we need to map
a mp_chmap to ALSA, we fetch the device's channel map list, convert
each entry to mp_chmap, and find the first one which fits.
This seems helpful for the following commit. For now, this only gets rid
of mapping back the trivial MONO mapping, which alone would still be
acceptable, but with other channel layout mogrifications it gets messy
fast. While we need to do something awkward to keep our channel map
reordering for VAR chmaps (which basically gives nicer output and
possibly slightly better performance), this is still the better
solution.
This reverts commit 4e358a9636.
Testing shows the channel pairs must indeed be swapped (details see
commit message of the reverted commit). Making the downmix code move
sl/sr to sdl/sdr is not an appropriate solution anymore, and it's
better to fix the unusual channel layout in ao_alsa.c directly.
(Not reverting the change in chmap.c; this is still correct.)
ao_alsa: attempt to fix 7.1 over HDMI
The last 2 channels of 7.1 (RLC/RRC in ALSA) were exported as sdl/sdr
instead of sl/sr (I don't even know why I chose sdl/sdr, but SL/SR
and RLC/RRC are different in the ALSA API). libsw/avresample do not
move the sl/sr channels to sdl/sdr when rematrixing, so silence was
sent for 2 channels. If my selection of sdl/sdr is essentially API
abuse, there's no reason why they should do this differently.
The mess here is really that ALSa doesn't map the HDMI layouts cleanly.
Most ALSA drivers export 7.1 in a way compatible to our expectations,
but Intel HDA/HDMI does not:
mpv/ffmpeg: fl-fr-fc-lfe-bl-br-sl-sr
ALSA/generic: FL FR FC LFE RL RR SL SR [1]
ALSA/HDMI: FL FR LFE FC RL RR RLC RRC [2]
The HDMI layout is layout 0x13 (going by CEA-861-B). The comment in
the kernel code has to be correct too. The early standard defines only
1 other layout, which replaces RLC/RRC with FRC/FLC - this probably
corresponds to what we call "7.1(wide)".
So it appears when ALSA requests RLC/RRC, we should feed it sl/sr.
To make it more complicated, Kodi/xbmc apparently also have to deal with
ALSA being special, but instead of sending sl/sr to RLC/RRC, they swap
the last two pairs of the layout, and send sl/sr to RL/RR and bl/br to
RLC/RRC. Or I might have misunderstood their code. I don't have a
7.1-capable A/V receiver, so I can't test this.
For now, go with the simpler solution, and wait until someone tests it.
If the speakers end up swapped, a completely different solution will be
needed.
[1] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/core/pcm_lib.c?id=refs/tags/v4.3#n2434
[2] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/sound/pci/hda/patch_hdmi.c?id=refs/tags/v4.3#n307
These calls actually can leave the ALSA configuration space empty (how
very useful), which is why snd_pcm_hw_params() can fail. An earlier
change intended to make this non-fatal, but it didn't work for this
reason.
Backup the old parameters, so we can retry with the non-empty
configuration space. (It has to be non-empty, because the previous
setters didn't fail.)
Note that the buffer settings are not very important to us. They're
a leftover from MPlayer, which needed to write enough data to the
audio device to not underrun while decoding and displaying a video
frame. In mpv, most of these things happen asynchronously, _and_
there is a dedicated thread just for feeding the audio device, so
we should be pretty imune even against extreme buffer settings. But
I suppose it's still useful to prevent PulseAudio from making the
buffer too large, so still keep this code.
Again, this could have bad access, is unlikely, and has no bad
consequences. It's noteworthy that vlc and the ALSA PCM example both do
this first, even if they set the sample rate later.