Commit Graph

1346 Commits

Author SHA1 Message Date
wm4 dcfde2934d audio: use idiotic FFmpeg ABI rules for public-except-not-public fields
The FFmpeg API is incredibly weird and inconsistent about this. This is
also a FFmpeg-only issue and nothing like this is in Libav - which
doesn't really show FFmpeg in a very positive light.

(To make it even worse: this is a full-blown Libav API incompatibility,
even though this crap was added for Libav ABI-compatibility. It's
absurd.)

Quoting the FFmpeg header for the AVFrame.channels field:

    /**
     * number of audio channels, only used for audio.
     * Code outside libavutil should access this field using:
     * av_frame_get_channels(frame)
     * - encoding: unused
     * - decoding: Read by user.
     */
    int channels;

It says "should" not must, and it doesn't even mention
av_frame_set_channels(). It's also in the section for public fields (not
below a marker that indicates private fields in a public struct, like
it's done e.g. in AVCodecContext).

But not using the accessor will cause silent failures on ABI changes.
The failure that happened due to this code didn't even make it apparent
what was wrong. So just use the idiotic accessor.

Also harmonize the FFmpeg-cursing in the code. (It's fully justified.)

Fixes #3295.

Note that mpv will still check the exact library version numbers, and
reject mismatches - to protect itself from such issues in the future.
2016-07-24 19:33:20 +02:00
wm4 3623cec7d2 af_lavcac3enc: use common code for AVFrame setup 2016-07-24 19:06:00 +02:00
wm4 77e1e8e38e audio: refactor mixer code and delete mixer.c
mixer.c didn't really deserve to be separate anymore, as half of its
contents were unnecessary glue code after recent changes. It also
created a weird split between audio.c and af.c due to the fact that
mixer.c could insert audio filters. With the code being in audio.c
directly, together with other code that unserts filters during runtime,
it will be possible to cleanup this code a bit and make it work like the
video filter code.

As part of this change, make the balance code work like the volume code,
and add an option to back the current balance value. Also, since the
balance semantics are unexpected for most users (panning between the
audio channels, instead of just changing the relative volume), and there
are some other volumes, formally deprecate both the old property and the
new option.
2016-07-17 19:21:28 +02:00
wm4 79974e7ad9 audio: fix crashes due to broken uninit check
Since mixer->ao is always NULL now (it was really just forgotten to be
removed), the uninit call never actually cleared the af field, leaving
a dangling pointer that could be accessed by volume control.
2016-07-15 23:11:25 +02:00
wm4 f29bba1123 af: avoid rebuilding filter chain in another minor case
No need to create additional noise of we can trivially see that
rebuiding the chain won't change anything.
2016-07-15 13:04:17 +02:00
wm4 d191d76e52 ao_pulse: fix some volume control rounding issues
Volume could get easily "stuck" or making too huge steps when doing
things like "add ao-volume 1".
2016-07-14 18:11:14 +02:00
wm4 f53d73b9dc ao_creoaudio: print OSStatus as decimal signed integer too
OSStatus is quite inconsistent. Sometimes it's a FourCC, sometimes it
reads as decimal signed number.
2016-07-13 17:07:06 +02:00
wm4 79f48500e2 ao_coreaudio: use correct free function on errors 2016-07-13 16:34:00 +02:00
wm4 e246c3f060 audio: fix code for adjusting conversion filters
This code was supposed to adjust existing conversion filters (to make
them output a different format). But the code was just broken,
apparently a refactoring accident. It accessed af instead of af->prev.

The bug tended to add new conversion filters, even if an existing one
could have been used. (Can be tested by inserting a dummy lavrresample
filter followed by a format filter which forces conversion.)

In addition, it's probably better to return the actual error code if
reinitializing the filter fails. It would then respect an AF_FALSE
return value, which means format negotiation failed, instead of a
generic error.
2016-07-11 12:23:32 +02:00
wm4 61afe3820a af_volume: don't let softvol overwrite af_volume volumedb sub-option
af_volume has a volumedb sub-option, which allows the user to set an
explicit volume. Until recently, the player read back this value and
used it as initial softvol volume. But now it just overwrites it.

Instead of overwriting it, multiply the different gain values. Above
all, this will do the right thing if only softvol is used, or if the
user only adds the af_volume filter manually.
2016-07-11 11:03:36 +02:00
wm4 60048b7eb9 audio: add heuristic to move auto-downmixing before other filters
Normally, you want downmixing to happen first thing in the filter chain.
This is reflected in codec downmixing, which feeds the filter chain
downmixed audio in the first place. Doing this has the advantage of
needing less data to process. But the main motivation is that if there
is a drc filter in the chain, you want to process it the downmixed
audio.

Add an idiotic heuristic to achieve this. It tries to detect whether the
audio was indeed automatically downmixed (or upmixed). To detect what
the output format is going to be, it builds the filter chain normally,
and then retries with the heuristic applied (and for extra paranoia,
retries without the heuristic again if it fails to successfully rebuild
the filter chain for unknown reasons). This is simple and will work in
almost all cases.

Doing it in a more complete way is rather hard, because filters are so
generic. For example, we know absolutely nothing about the behavior of
af_lavfi, which creates an opaque filter graph with libavfilter. We
don't know why a filter would e.g. change the channel layout on its
output. (Our heuristic bails out in this case.) We're also slave to the
lowest common denominator of how our format negotiation works, and how
libavfilter's works.

In theory, we could make this mechanism explicit by introducing a
special dummy filter. The filter chain would then try to convert between
input and output formats at the dummy filter, which would give the user
more control over how downmix happens. On the other hand, the user could
just insert explicit conversion filters instead, so this would probably
have questionable value.
2016-07-10 19:53:53 +02:00
wm4 7be98ef1b2 audio: add auto-inserted flag to filter list logging
Like the video filter chain.
2016-07-10 19:51:09 +02:00
wm4 2eac58eaa9 audio: cleanup audio filter format negotiation
The algorithm and functionality is the same, but the code becomes much
simpler and easier to follow.

The assumption that there is only 1 conversion filter (lavrresample)
helps with the simplification, but the main change is to use the same
code for format/channels/rate. Get rid of the different AF_CONTROL_SET_*
controls, and change the af->data parameters directly. (af->data is
badly named, but essentially is a placeholder for the output format.)

Also, instead of trying to use the af_reinit() loop to init inserted
conversion filters or filters with changed output formats, do it inline,
and move the common code to a filter_reinit() function. This gets rid of
the awful retry variable.

In general, this should not change any runtime behavior.
2016-07-10 19:51:09 +02:00
wm4 e518bf2c72 audio: insert audio-inserted filters at end of chain
This happens to be better for the af_volume filter (for softvol), and
saves some code too. It's "better" because you want to affect the
final filtered audio, such as after a manually inserted drc filter.
2016-07-09 20:23:15 +02:00
wm4 d47b708f00 audio: don't crash when changing volume if no audio is initialized
Oversight.
2016-07-09 19:34:45 +02:00
wm4 995c47da9a audio: drop --softvol=no and --softvol=auto
Drop the code for switching the volume options and properties between
af_volume and AO volume controls. interface-changes.rst mentions the
changes in detail.

Do this because this was exceedingly complex and had other problems as
well. It was also very hard to test. It's just not worth the trouble.

Some leftovers like AOCONTROL_HAS_PER_APP_VOLUME will be removed at a
later point.

Fixes #3322.
2016-07-09 18:31:18 +02:00
wm4 885e991312 ao_coreaudio: error out when selecting invalid device
When selecting a device that simply doesn't exist with --audio-device,
AudioUnit will still initialize and start playback without complaining.
But it will never call the audio render callback, which leads to audio
playback simply not progressing.

I couldn't find a way to get AudioUnit to report an error at all, so
here's a crappy hack that takes care of this in most cases. We assume
that all devices have a kAudioDevicePropertyDeviceIsAlive property.
Invalid devices will error when querying the property (with 'obj!' as
status code).

This is not the correct fix, because we try to double-guess AudioUnit's
behavior by accessing a lower label API. Suggestions welcome.
2016-07-08 16:11:03 +02:00
wm4 5d2f1da7c5 vf, af: print filter labels in verbose mode 2016-07-06 14:13:03 +02:00
wm4 614efea3e6 ad_lavc: work around braindead ffmpeg behavior
The libavcodec wmapro decoder will skip some bytes at the start of the
first packet and return each time. It will not return any audio data in
this state.

Our own code as well as libavcodec's new API handling
(avcodec_send_packet() etc.) discard the PTS on the first return, which
means the PTS is never known for the first packet. This results in a
"Failed audio resync." message.

Fixy it by remember the PTS in next_pts. This field is used only if the
decoder outputs no PTS, and is updated after each frame - and thus
should be safe to set.

(Possibly this should be fixed in libavcodec new API handling by not
setting the PTS to NOPTS as long as no real data has been output. It
could even interpolate the PTS if the timebase is known.)

Fixes the failure message seen in #3297.
2016-07-01 15:51:34 +02:00
wm4 c6953bfa8c ao_oss: do not add an entry to audio-device-list if device file missing
This effectively makes it go away on Linux (unless you have OSS
emulation loaded).
2016-06-29 17:40:04 +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
wm4 4ce53025cb audio: add a helper for getting frame end PTS
Although I don't see any use for it yet, why not.
2016-06-27 15:12:21 +02:00
wm4 3e58ce96ac dec_audio: fix segment boudnary switching
Some bugs in this code are exposed by e.g. playing lossless audio files
with --ad-lavc-threads=16. (libavcodec doesn't really support threaded
audio decoding, except for lossless files.) In these cases, a major
amount of audio can be buffered, which makes incorrect handling of this
buffering obvious.

For one, draining the decoder can take a while, so if there's a new
segment, we shouldn't read audio.

The segment end check was completely wrong, and used the start value.
2016-06-27 15:12:21 +02:00
Rudolf Polzer acb74236ac ao_lavc, vo_lavc: Migrate to new encoding API.
Also marked some places for possible later refactoring, as they became
quite similar in this commit.
2016-06-27 08:33:12 -04:00
stepshal c5094206ce Fix misspellings 2016-06-26 13:47:21 +02:00
wm4 1c3bbd9318 af_lavcac3enc: use av_err2str() call (fixes Libav build)
I added this call because I thought it'd be nice, but Libav doesn't have
this function (macro, actually).
2016-06-23 12:41:41 +02:00
wm4 e911e208b8 af_lavcac3enc: make encoder configurable 2016-06-23 12:14:45 +02:00
wm4 5c74da4503 af_lavcac3enc: implement flushing on seek
There's a lot of data that could have been buffered, and which has to be
discarded.
2016-06-23 12:07:05 +02:00
wm4 c071c30bcd af_lavcac3enc: port to new encode API 2016-06-23 12:04:04 +02:00
wm4 b01855714b af_lavcac3enc: automatically configure most encoder parameters
Instead of hardcoding what the libavcodec ac3 encoder expects, configure
it based on the AVCodec fields.

Unfortunately, it doesn't export the list of sample rates, so that is
done manually. This commit actually fixes the rate always to 48Khz. I
don't even know whether the other rates worked. (Possibly did, but
they'd still change the spdif parameters, and would work differently
from ad_spdif.c.)
2016-06-23 12:02:36 +02:00
wm4 5a60f594e5 af_lavcac3enc: drop log message prefixes
MPlayer leftover. They're already added by the logging code.
2016-06-23 10:45:56 +02:00
wm4 31b73d5ca0 af_lavcac3enc: fix custom bitrates
Probably has been broken for ages.

(Not sure why anyone would use this feature, though.)
2016-06-23 10:43:54 +02:00
wm4 7ea22fe889 ad_lavc: resume from mid-stream EOF conditions with new decode API
Workaround for an awful corner-case. The new decode API "locks" the
decoder into the EOF state once a drain packet has been sent. The
problem starts with a file containing a 0-sized packet, which is
interpreted as drain packet.

This should probably be changed in libavcodec (not treating 0-sized
packets as drain packets with the new API) or in libavformat (discard
0-sized packets as invalid), but efforts to do so have been fruitless.

Note that vd_lavc.c already does something similar, but originally for
other reasons.

Fixes #3106.
2016-06-22 21:37:36 +02:00
wm4 b00eab525a audio: apply an upper bound timeout when draining
This helps with shitty APIs and even shittier drivers (I'm looking at
you, ALSA). Sometimes they won't send proper wakeups. This can be fine
during playback, when for example playing video, because mpv still will
wakeup the AO outside of its own wakeup mechanisms when sending new data
to it. But when draining, it entirely relies on the driver's wakeup
mechanism. So when the driver wakeup mechanism didn't work, it could
hard freeze while waiting for the audio thread to play the rest of the
data.

Avoid this by waiting for an upper bound. We set this upper bound at the
total mpv audio buffer size plus 1 second. We don't use the get_delay
value, because the audio API could return crap for it, and we're being
paranoid here. I couldn't confirm whether this works correctly, because
my driver issue fixed itself.

(In the case that happened to me, the driver somehow stopped getting
interrupts. aplay froze instead of playing audio, and playing audio-only
files resulted in a chop party. Video worked, for reasons mentioned
above, but drainign froze hard. The driver problem was solved when
closing all audio output streams in the system. Might have been a dmix
related problem too.)
2016-06-12 21:05:10 +02:00
wm4 972ea9ca59 audio: do not wake up core during EOF
When we're draining, don't wakeup the core on every buffer fill, since
unlike during normal playback, we won't actually get more data. The
wakeup here conceptually works like wakeups with condition variables, so
redundant wakeups do not hurt, so this is just a minor change and
nothing of consequence.

(Final EOF also requires waking up the core, but there is separate code
to send this notification.)

Also dump the p->still_playing field in trace logging.
2016-06-12 20:59:11 +02:00
Niklas Haas 5b5db336e9 build: silence -Wunused-result
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.
2016-06-07 14:12:33 +02:00
Kevin Mitchell b3e74f652b ao_wasapi: initialize COM in main thread with MTA
Since the main thread is shared by other things in the player, using STA (single
threaded aparement) may have caused problems. Instead initialize in MTA
(multithreaded apartment).
2016-06-05 16:31:03 -07:00
Josh de Kock 4aa017e301 ao_opensles: remove 32bit audio
It's unsupported by android, and can cause problems when trying to play 32bit audio. Removing 32bit fixes it by forcing 16 bit or 8 bit audio.
2016-05-22 14:31:37 +02:00
wm4 a93fb460cd ao_alsa: add more shitty workarounds
This reportedly makes it work on ODROID-C2. The idea for this hack is
taken from kodi; they unconditionally set some or all of those flags.
I don't trust ALSA enough to hope that setting these flags couldn't
break something else, so we try without them first.

It's not clear whether this is a driver bug or a bug in the ALSA libs.
There is no ALSA bug tracker (the ALSA website has had a dead link to
a deleted bug tracker fo years). There's not much we can do other than
piling up ridiculous hacks. At least I think that at this point invalid
API usage by mpv can be excluded as a cause.

ALSA might be the worst audio API ever.
2016-05-06 17:20:02 +02:00
wm4 51e4c065ff ao_alsa: log final hwparams too
snd_pcm_hw_params() updates them.
2016-05-03 11:24:47 +02:00
James Ross-Gowan 622bcb0e37 win32: replace libuuid.a usage with initguid.h
Including initguid.h at the top of a file that uses references to GUIDs
causes the GUIDs to be declared globally with __declspec(selectany). The
'selectany' attribute tells the linker to consolidate multiple
definitions of each GUID, which would be great except that, in Cygwin
and MinGW GCC 6.1, this method of linking makes the GUIDs conflict with
the ones declared in libuuid.a.

Since initguid.h obsoletes libuuid.a in modern compilers that support
__declspec(selectany), add initguid.h to all files that use GUIDs and
remove libuuid.a from the build.

Fixes #3097
2016-05-01 21:10:24 +10:00
wm4 d30634b104 ao_alsa: log hwparams while restricting them
They can sometimes fail, so I want logging to determine what's going on.

Most of them are at debug log-level, except the final hwparams.
2016-04-28 13:31:13 +02:00
wm4 66a958bb4f ao_coreaudio: remove detected_device
Setting this here is a race condition. It's called from a CoreAudio
callbacks, and there are no locks. It's a string, so this can be
potentially severe.

It's hard to fix and only CoreAudio supported it, so remove it.

This causes the "audio-out-detected-device" property to return nothing
on all platforms.
2016-04-26 18:35:37 +02:00
wm4 78346e9c9a ad_spdif: take care of deprecated libavcodec API usage 2016-04-20 19:37:45 +02:00
wm4 607ba5f235 ao_coreaudio_exclusive: list formats when searching substream
Should help debug problems with AC3 passthrough not working.
2016-04-15 14:19:22 +02:00
wm4 1aa943d8ab ao_coreaudio: remove unused function 2016-04-15 14:14:42 +02:00
Rudolf Polzer 160497b8ff encode_lavc: Migrate to codecpar API. 2016-04-11 14:57:20 -04:00
wm4 64791a0832 ao_coreaudio_exclusive: add missing newline to log message 2016-04-01 12:24:39 +02:00
wm4 c971220cdd demux_lavf, ad_lavc, ad_spdif, vd_lavc: handle FFmpeg codecpar API change
AVFormatContext.codec is deprecated now, and you're supposed to use
AVFormatContext.codecpar instead.

Handle this for all of the normal playback code.

Encoding mode isn't touched.
2016-03-31 22:00:45 +02:00
wm4 4300bfd518 ad_lavc, vd_lavc: support new Libav decoding API
For now only found in Libav.
2016-03-24 17:53:30 +01:00