This was all dead code. Commit 995c47da9a (over 3 years ago) removed all
uses of the controls.
It would be nice if AOs could apply a linear gain volume, that only
affects the AO's audio stream for low-latency volume adjust and muting.
AOCONTROL_HAS_SOFT_VOLUME was supposed to signal this, but to use it,
we'd have to thoroughly check whether it really uses the expected
semantics, so there's really nothing useful left in this old code.
ioctl(..., SNDCTL_DSP_CHANNELS, &nchannels) for not supported
nchannels does not return an error and instead set nchannels to
the default value.
Instead of failing with no audio, fallback to stereo.
The af_get_best_sample_formats() function had an argument of
int[AF_FORMAT_COUNT], which is slightly incorrect, because it's 0
terminated and should in theory have AF_FORMAT_COUNT+1 entries. It won't
actually write this many formats (since some formats are fundamentally
incompatible), but it still feels annoying and incorrect. So fix it, and
require that callers pass an AF_FORMAT_COUNT+1 array.
Note that the array size has no meaning in C function arguments (just
another issue with C static arrays being weird and stupid), so get rid
of it completely.
Not changing the af_lavcac3enc use, since that is rewritten in another
branch anyway.
This commit eliminates the following clang warning:
warning: macro expansion producing 'defined' has undefined behavior [-Wexpansion-to-defined]
Going by the clang commit message, this seems to be explicitly specified
as UB by the standard, and they added this warning because MSVC
apparently results in different behavior. Whatever, we can just avoid
the warning with some small changes.
This should actually cover all of them, if you take into account that
some unchanged GPL source files include header files with such checks.
Also this was done already for the libaf derived code.
This is only for "safety" and to avoid misunderstandings.
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.
The user bugmen0t was apparently a shared github account with publicly
available login. Thus, we can't get LGPL relicensing permission from the
people who used this account. To relicense successfully, we have to
remove all their changes.
This commit should remove 20d1fc13, f26fb009, defbe48d. It also should
remove whatever test fragments were copied from the ancient configure,
as well as some configure logic (potentially that device path stuff).
I think this change still preserves the most important use-cases of OSS:
BSDs, and the Linux OSS emulation (the latter for testing only).
According to an OSS user, the 4front checks were probably broken anyway.
The SunAudio stuff was probably for (Open)Solaris, which is dead.
ao_oss.c itself will remain GPL, and still contains bugmen0t changes.
Fall back on PATH_DEV_DSP if nothing is set.
This mirrors the behaviour of --audio-device / --alsa-device.
There doesn't appear to be a general way to list devices with oss, so
--audio-device=help doesn't list oss devices except for the default one if the
file exists.
Previously --audio-device was ignored entirely by ao_oss.
fixes#4122
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.)
For clang, it's enough to just put (void) around usages we are
intentionally ignoring the result of.
Since GCC does not seem to want to respect this decision, we are forced
to disable the warning globally.
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".
They are useless. Not only are they actually rarely in use; but
libavcodec doesn't even output them, as libavcodec has no such sample
formats for decoded audio.
Even if it should happen that we actually still need them (e.g. if doing
direct hardware output), there are better solutions. Swapping the sign
is a fast and lossless operation and can be done inplace, so AO actually
needing it could do this directly.
If you wonder why we keep U8 instead of S8: because libavcodec does it.
...because everything is terrible.
strerror() is not documented as having to be thread-safe by POSIX and
C11. (Which is pretty much bullshit, because both mandate threads and
some form of thread-local storage - so there's no excuse why
implementation couldn't implement this in a thread-safe way. Especially
with C11 this is ridiculous, because there is no way to use threads and
convert error numbers to strings at the same time!)
Since we heavily use threads now, we should avoid unsafe functions like
strerror().
strerror_r() is in POSIX, but GNU/glibc deliberately fucks it up and
gives the function different semantics than the POSIX one. It's a bit of
work to convince this piece of shit to expose the POSIX standard
function, and not the messed up GNU one.
strerror_l() is also in POSIX, but only since the 2008 standard, and
thus is not widespread.
The solution is using avlibc (libavutil, by its official name), which
handles the unportable details for us, mostly. We avoid some pain.
The intention is to avoid using the timeout-based fallback.
There's some minor hope that this will help with OpenBSD (see #1239),
although it probably won't.
Some chance that this will cause trouble with obscure OSS
implementations or emulations.
Digital pass-through was probably broken. Possibly fix it (no way to
test). This also should make the logic slightly saner.
Fortunately, it's unlikely that anyone who uses OSS has a spdif setup.
Before this commit, there was AF_FORMAT_AC3 (the original spdif format,
used for AC3 and DTS core), and AF_FORMAT_IEC61937 (used for AC3, DTS
and DTS-HD), which was handled as some sort of superset for
AF_FORMAT_AC3. There also was AF_FORMAT_MPEG2, which used
IEC61937-framing, but still was handled as something "separate".
Technically, all of them are pretty similar, but may use different
bitrates. Since digital passthrough pretends to be PCM (just with
special headers that wrap digital packets), this is easily detectable by
the higher samplerate or higher number of channels, so I don't know why
you'd need a separate "class" of sample formats (AF_FORMAT_AC3 vs.
AF_FORMAT_IEC61937) to distinguish them. Actually, this whole thing is
just a mess.
Simplify this by handling all these formats the same way.
AF_FORMAT_IS_IEC61937() now returns 1 for all spdif formats (even MP3).
All AOs just accept all spdif formats now - whether that works or not is
not really clear (seems inconsistent due to earlier attempts to make
DTS-HD work). But on the other hand, enabling spdif requires manual user
interaction, so it doesn't matter much if initialization fails in
slightly less graceful ways if it can't work at all.
At a later point, we will support passthrough with ao_pulse. It seems
the PulseAudio API wants to know the codec type (or maybe not - feeding
it DTS while telling it it's AC3 works), add separate formats for each
codecs. While this reminds of the earlier chaos, it's stricter, and most
code just uses AF_FORMAT_IS_IEC61937().
Also, modify AF_FORMAT_TYPE_MASK (renamed from AF_FORMAT_POINT_MASK) to
include special formats, so that it always describes the fundamental
sample format type. This also ensures valid AF formats are never 0 (this
was probably broken in one of the earlier commits from today).
Until now, the audio chain could handle both little endian and big
endian formats. This actually doesn't make much sense, since the audio
API and the HW will most likely prefer native formats. Or at the very
least, it should be trivial for audio drivers to do the byte swapping
themselves.
From now on, the audio chain contains native-endian formats only. All
AOs and some filters are adjusted. af_convertsignendian.c is now wrongly
named, but the filter name is adjusted. In some cases, the audio
infrastructure was reused on the demuxer side, but that is relatively
easy to rectify.
This is a quite intrusive and radical change. It's possible that it will
break some things (especially if they're obscure or not Linux), so watch
out for regressions. It's probably still better to do it the bulldozer
way, since slow transition and researching foreign platforms would take
a lot of time and effort.
Pausing/unpausing while the audio device can't be reopened, and then
unpausing again when the device is finally reopened, can hang the
player for a while.
This happens because p->prepause_samples grows without bounds each
time the player is unpaused while the device is lost. On unpause,
ao_oss plays prepause_samples of silence to compensate for A/V timing
issues due to the partially lost buffer (we can't pause the device at
an arbitrary sample position, and the current period will be lost).
This in turn will make the player appear to be frozen if too much
audio is queued. (Normally, play() must never block, but here it
happens because more data is written than get_space() reports. A
better implementation would never let prepause_samples grow larger
than the period size.)
The unbounded growth happens because get_space() always returns that
the device can be written while the device is lost. So limit it to
200ms. (A better implementation would limit it to the period size.)
Also see #1080.
Apparently NetBSD users want/need this (see issue #1080).
In order not to break playback, we need at least to emulate get_delay().
We do this approximately by using the system clock.
Also, always close the audio device on reset. Reopen it on play only. If
we can't reopen it, don't retry until after the next time reset or
resume is called, to avoid spam and unexpectedly "stealing" back the
audio device.
Also do something about framestepping causing audio desync.
The context struct had an audio_buf_info field, but there's no reason
why this would be needed. It's a tiny struct, and it isn't permanent
state. It's always returned by SNDCTL_DSP_GETOSPACE. Keeping this as
field is just confusing, so get rid of it.
The code for reopening the audio device was separate, and duplicated
some of the "real" open code. This was very badly done, and major
required parts of initialization were skipped. Fix this by removing
the code duplication. This consists mainly of moving the code for
opening the device to a separate function, and adding some changes
to handle format changes gracefully. (We can't change the audio
format on the fly, but we can at least not explode and play noise
when that happens.)
As a minor change, actually always use SNDCTL_DSP_RESET when closing
the audio device. We don't want to wait until the rest of the buffer
is played.
Also, don't use strerror() when printing the error message that
reopening failed, simply because reopen_device() takes care of this,
and also errno might be clobbered at this point.
I have no idea whether this is true, because there literally doesn't
seem to exist documentation for SNDCTL_DSP_RESET. But at least on
Linux' OSS emulation, it is true. Also, it would be quite insane if
it would be needed.
It seems on NetBSD SNDCTL_DSP_RESET exists, but using it for pausing
is not feasible. We still use it to discard the audio buffer when
closing the audio device.
Replace select() usage with poll() (and reduce code duplication).
Also, while we're at it, drop --disable-audio-select, since it has the
wrong name anyway. And I have doubts that this is needed anywhere. If
it is, it should probably fallback to doing the right thing by default,
instead of requiring the user to do it manually. Since nobody has done
that yet, and since this configure option has been part of MPlayer ever
since ao_oss was added, it's probably safe to say it's not needed.
The '#ifdef SNDCTL_DSP_GETOSPACE' was pointless, since it's already used
unconditionally in another place.
Remove the unnecessary indirection through ao fields.
Also fix the inverted result of AOCONTROL_HAS_TEMP_VOLUME. Hopefully the
change is equivalent. But actually, it looks like the old code did it
wrong.
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.
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.
Until now, this was always conflated with uninit. This was ugly, and
also many AOs emulated this manually (or just ignored it). Make draining
an explicit operation, so AOs which support it can provide it, and for
all others generic code will emulate it.
For ao_wasapi, we keep it simple and basically disable the internal
draining implementation (maybe it should be restored later).
Tested on Linux only.
We want to move the AO to its own thread. There's no technical reason
for making the ao struct opaque to do this. But it helps us sleep at
night, because we can control access to shared state better.
Since m_option.h and options.h are extremely often included, a lot of
files have to be changed.
Moving path.c/h to options/ is a bit questionable, but since this is
mainly about access to config files (which are also handled in
options/), it's probably ok.