0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00
Commit Graph

1296 Commits

Author SHA1 Message Date
Thomas Weißschuh
69fb378575 ao_pipewire: remove opencoded spa_zero() 2023-02-03 09:18:37 -08:00
Thomas Weißschuh
af3c7f3d31 ao_pipewire: remove some unnecessary linebreaks 2023-02-03 09:18:37 -08:00
Thomas Weißschuh
c2c36c0d57 ao_pipewire: reduce message level of unsuccessful connection
As ao_pipewire is probed first if a user does not have PipeWire running
they will see a scary warning message even if another AO afterwards is
probed fine.
Tone down the error message so as not to confuse users.
2023-02-03 09:18:37 -08:00
Thomas Weißschuh
469f7af210 ao_pipewire: remove unnecessary braces 2023-02-03 09:18:37 -08:00
Kacper Michajłow
2048125f0c ao_lavc: remove unused code 2023-02-02 14:23:02 +00:00
Thomas Weißschuh
fb137e8d88 ao_pipewire: align thread name with general conventions 2023-01-25 15:56:36 -08:00
Thomas Weißschuh
870512eb84 audio: simplify implementation of property ao-volume
ao-volume is represented in the code with a `struct ao_control_vol_t`
which contains volumes for two channels, left and right.

However the code implementing this property in command.c never treats
these values individually. They are always averaged together.
On the other hand the code in the AOs handling these values also has to
handle the case where *not* exactly two channels are handled.

So let's remove the `struct ao_control_vol_t` and replace it with a
simple float.
This makes the semantics clear to AO authors and allows us to drop some code from the AOs and command.c.
2023-01-25 15:49:21 -08:00
Thomas Weißschuh
98c2fa095d ao: remove trailing NULL element from driver array 2023-01-16 19:25:54 +00:00
Dudemanguy
9a9039deb2 audio: fix crash during uninit on ao_lavc
The buffer state can be null when using --ao=lavc, so just check it
first. Fixes #10175.
2023-01-13 16:02:38 +00:00
sfan5
1201d59f0b various: replace abort() with MP_ASSERT_UNREACHABLE() where appropriate
In debug mode the macro causes an assertion failure.
In release mode it works differently and tells the compiler that it can
assume the codepath will never execute. For this reason I was conversative
in replacing it, e.g. in mpv-internal code that exhausts all valid values
of an enum or when a condition is clear from directly preceding code.
2023-01-12 22:02:07 +01:00
sfan5
7b03cd367d various: replace if + abort() with MP_HANDLE_OOM()
MP_HANDLE_OOM also aborts but calls assert() first, which
will result in an useful message if compiled in debug mode.
2023-01-12 22:02:07 +01:00
sfan5
1e00e3119f ao_audiotrack: replace malloc with talloc 2023-01-12 22:02:07 +01:00
sfan5
833bff8738 {video,audio}: adjust unsafe strncpy usages 2023-01-12 22:02:07 +01:00
Li Chang
39f7f83351 ao_coreaudio: use AudioUnitReset as ao_driver.reset to prevent long restart
[motivation]
Seeking on MacOS appears to be lagged when users connect
to wireless audio output (airpods for example).

This commit attempts to fix mpv-player/mpv#10270

[observation]
1. When using other media player (VLC to be exact) simultaneously,
the lagging on seek disappear. We could guess that the AudioDevice
is on some sort of "warm-up" state.

See mpv-player/mpv#9243 for detailed description.

2. `AudioOutputUnitStart` takes significant longer time after each seek
or pause/play when using wireless output devices compares to wired devices.

[rationale]
After investigate codes in ao_coreaudio.c, it appears that the the `stop`
function was used as `ao_driver.reset` function. Therefore every seek
and pause would call `AudioOutputUnitStop`.

It turns out that `ao_driver.reset` function is used in `ao_reset`.
And `ao_reset` function is used to clean up the state of current `ao`
so I think `AudioUnitReset` is more proper than `AudioOutputUnitStop`
under this semantics.

Since ao_coreaudio use pull base mechanism, audio playback behaviors
upon pause/seek could be handled by callback function
(streaming silence when paused) so there is no need to stop AudioUnit when resetting.
Therefore using `AudioUnitReset` as `ao_driver.reset` looks proper.

Additionally, after using proper reset, the AudioUnit that represents
hardware I/O devices doesn't need to be restart everytime seek/pause actions happen.
Restarting wireless devices simply takes longer in MacOS which is
the root cause of lagging observed by users when they seek or pause/play media.

[method]
Use `AudioUnitReset` for ao_driver.reset.
2023-01-02 19:45:54 +01:00
Thomas Weißschuh
657fd2804c audio: reset pull AO at end of file
When a pull AO reaches reaches EOF then ao_read_data() will set
p->playing = false.
Because the ao is marked as not playing ao_set_pause(true) will not
reset the AO.
This keeps the output stream unintentionally open.

Fixes #9835
2022-12-22 15:14:08 -08:00
Philip Langdale
405073b9ca Revert "ao_pipewire: deactivate stream at end of playback"
This reverts commit b5373079f2.
2022-12-19 15:54:42 -08:00
Thomas Weißschuh
b5373079f2 ao_pipewire: deactivate stream at end of playback
By explictly shutting down the stream pipewire can deactivate the used
hardware, saving CPU and power.

Fixes #9835
2022-12-18 13:34:29 -08:00
Thomas Weißschuh
f9d0b0c08a ao_pipewire: clean up when hotplug_init fails 2022-12-12 21:36:04 +01:00
Thomas Weißschuh
f2ba5fdfd3 ao_pipewire: destroy context on connection failure 2022-12-12 21:36:04 +01:00
Thomas Weißschuh
64a7fd3a12 ao_pipewire: free properties on failure 2022-12-12 21:36:04 +01:00
rcombs
2fa1e7d0b4 ao_coreaudio: use device's nominal sample rate for latency properties
Fixes sync issues when using high-latency devices at non-native sample rates

Closes #10984
2022-12-10 18:15:46 +02:00
Thomas Weißschuh
7eb8f81091 ao_pipewire: log sample queueing
This allows us to more easily see the datapath from mpv to pipewire.

We know how often the callbacks are triggered, how big the buffers are
and how much data mpv provides to pipewire.
2022-11-28 16:43:24 -08:00
Thomas Weißschuh
d8fbe3c79f ao_pipewire: log version information and metadata 2022-11-13 20:40:14 -08:00
Thomas Weißschuh
2e5d0d6e07 ao_pipewire: reload ao on stream disconnect
This allows the core of mpv to know about issues in the AO.
Otherwise playback will just freeze as no more data callbacks are sent
by PipeWire.
Also it allows mpv to try to reconnect the AO or find another, working
AO.
2022-11-07 10:36:40 -08:00
Thomas Weißschuh
b7cf35c9a4 ao_pipewire: explicitly remove stream hook
We want to add more logic to the stream event handler.
This logic should not be triggered during normal stream shutdown, so we
remove the listener beforehand.
2022-11-07 10:36:40 -08:00
Thomas Weißschuh
bf7ade420d ao_pipewire: log generic stream errors 2022-11-07 10:36:40 -08:00
Aman Karmani
9f0381c51b Revert "ao/audiounit: include AVAudioSession buffer in latency calc"
This reverts commit 8b114e574a.
2022-11-07 18:45:55 +02:00
rcombs
89bd6ead6c ao_coreaudio: specify UTF-8 as text encoding for CFString conversions
This matches our internal expectations, as well as fixes handling
of non-ASCII device descriptions.
2022-10-29 00:00:09 +03:00
Thomas Weißschuh
c9af75e888 ao_pipewire: compatibility for libpipewire 0.3.19 2022-10-26 21:56:33 +03:00
Thomas Weißschuh
c3be7e2585 ao: promote ao_pipewire
The AO is feature-complete now.
As PipeWire also provides compatibility with PulseAudio, ALSA and Jack
we should put it before those for the autodetection to work.
2022-10-24 11:09:34 -07:00
Thomas Weißschuh
b9a9e0a6f1 ao_pipewire: test for session to contain audio sinks
The pure presence of PipeWire does not mean that it is actually driving
the audio session. For example it could only be meant for video.

Currently there is no proper API to detect this (see [0]), so we check
for the presence of audio sinks.

As soon as a proper API exists, we should use that.

[0] https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1835
2022-10-24 11:09:34 -07:00
Thomas Weißschuh
e4505ce744 ao_pipewire: init_boilerplate(): simplify errorhandling 2022-10-24 11:09:34 -07:00
Thomas Weißschuh
161bdd9359 ao_pipewire: allow specification of remote name 2022-10-06 13:16:35 -07:00
Thomas Weißschuh
a1e29f1555 ao_pipewire: small cleanups and restructring
* Remove unneeded braces.
* Don't use non-standard %m in printf.
* Organize struct priv a bit.
2022-10-06 13:16:35 -07:00
Thomas Weißschuh
b2aaf7250f ao_pipewire: don't try to lock nonexistent loop 2022-09-28 15:53:33 -07:00
Thomas Weißschuh
5e49c09f2e ao_pipewire: use target.object
Specifying the id of the target node during stream connect is
deprecated.  Instead the property target.object should be used to link
by target serial or name.  Using the name allows us to drop a bunch of
custom code.
2022-09-28 15:53:05 -07:00
rcombs
ba81e4ed88 ao_audiounit: get the channel layout from the AU itself
Fixes 5.1/7.1 output mapping on tvOS 16,
and also makes the AC3-layout hack unnecessary.

Also adds some diagnostic log messages.
2022-09-15 11:52:50 -05:00
Thomas Weißschuh
38a7562ebe ao_pipewire: listen to hotplug events 2022-09-11 20:24:42 -07:00
Thomas Weißschuh
f36eeaf4e8 ao_pipewire: use proper hotplug init APIs 2022-09-11 20:24:42 -07:00
Thomas Weißschuh
aa7223cd8c ao_pipewire: create is_sink_node helper 2022-09-11 20:24:42 -07:00
Thomas Weißschuh
235a66bfc8 audio: list devices for all AOs with hotplug_init
Previously we would only call list_devs() on available AOs if an AO
*did not* have a hotplug_init() callback or for the first one that *did*
have it.

This is problematic when multiple fully functional hotplug-capable AOs
are available.

The second one would not be able to contribute discovered devices.

This problem prevents ao_pipewire from introducing full hotplug support
with hotplug_init().
2022-09-11 20:24:42 -07:00
Thomas Weißschuh
013ec877f6 audio: try to use playback AO as hotplug AO first
When a platform has multiple valid AOs that can provide hotplug events
we should try to use the one that also provides playback.

Concretely this will help when introducing hotplug support for
ao_pipewire.

Currently ao_pulse is probed by ao_hotplug_get_device_list() before
ao_pipewire and on the common setups where both AOs could work pulse
will be selected for hotplug handling.
This means that hotplug_init() of ao_pipewire will never be called and
list_devs() has to do its own initialization.
But if ao_pulse is non-functional or not compiled-in suddenly
ao_pipewire *must* implement hotplug_init() for hotplugging events to
work for all.

Also if the hotplug ao_pulse connects to a PulseAudio instance that is
not emulated by the same PipeWire instance as the playback ao_pipewire
the hotplug events are useless.
2022-09-11 20:24:42 -07:00
Thomas Weißschuh
535cd6f313 ao_pipewire: handle AOCONTROL_UPDATE_MEDIA_ROLE 2022-09-10 12:32:52 -07:00
Thomas Weißschuh
3167a77aa3 audio: add AOCONTROL_UPDATE_MEDIA_ROLE
This is used to notify an AO about the type of media that is being
played.
Either a movie or music.
2022-09-10 12:32:52 -07:00
Thomas Weißschuh
221bf540a1 ao_pipewire: fix indent 2022-09-10 12:32:52 -07:00
Thomas Weißschuh
211ce69f74 ao_pipewire: for_each_sink(): report errors 2022-08-28 10:46:54 -07:00
Philip Langdale
ed7717298b audio: fix lack of reinitialization on format change with pull AOs
uau did some investigation and noticed that we do not send a wakeup
event when we encounter end-of-stream in ao_read_data(), in contrast to
the equivalent logic for push AOs in ao_play_data().

Inserting that wakeup fixes the original problem of lack of
reinitialization on a format change without the problems we saw with
the previous attempted fix.

Fixes #10566
2022-08-23 11:01:52 -07:00
Thomas Weißschuh
6c1f01d284 ao_pipewire: make sure not to exceed the available buffer
The error description in #10545 could indicate that we are overflowing
we are corrupting the buffer metadata ourselves through out-of-bound
writes.
This check is also present in pw-cat so it seems to be expected for
b->requested to exceed the actual available buffer space.

Potential fix for #10545
2022-08-21 18:38:53 +02:00
Thomas Weißschuh
e735f7f61a ao_pipewire: restructure logic a bit 2022-08-17 15:48:12 -07:00
Thomas Weißschuh
dbfee1be3d ao_pipewire: only try to read requested data 2022-08-17 15:48:12 -07:00
Thomas Weißschuh
0638a91ff4 ao_pipewire: report all available info about chunk
This allows the audio server better to make sense of the data instead of
having to use heuristics.
2022-08-17 15:48:12 -07:00
Thomas Weißschuh
c9ecaedc44 ao_pipewire: tell audio server about number of queued samples 2022-08-09 09:24:55 -07:00
Thomas Weißschuh
9add44b11a ao_pipewire: use mpv logging 2022-08-04 09:25:19 -07:00
Thomas Weißschuh
0044c19f0d ao_pipewire: prevent deprecation warning for pw_stream_get_time() 2022-07-08 17:19:23 -07:00
Wim Taymans
c7b17beaf1 ao_pipewire: pipewire uses linear volume
Don't use cube root volumes, pipewire uses linear volumes.
2022-07-08 07:45:09 -07:00
Wim Taymans
c01bb44e36 ao_pipewire: don't access core after disconnect
pw_core_disconnect frees the core, so accessing it afterward to
destroy the context is not allowed.

Instead, just destroy the context, the first thing it does is disconnect
all cores for us.
2022-07-08 07:45:09 -07:00
Wim Taymans
60ed51008d ao_pipewire: zero listeners
The listeners need to be cleared because removing them might invoke the
removed handler, which could otherwise point to invalid memory.
2022-07-08 07:45:09 -07:00
Alex B
d38ff1c958 ao_pipewire: support ao-volume on non-stereo channel layouts
mpv only remembers volume for two channels.
Always apply the same volume to all channels in case of
non-stereo layout similarly to ao_pulse.
Don't try to do anything smart when averaging volumes,
normally they are equal anyway.
2022-07-08 06:39:23 -07:00
Jan Ekström
7a3f9af67f ao_lavc: switch to AVChannelLayout when available 2022-06-12 21:05:59 +03:00
Guido Cella
fe9e074752 various: remove trailing whitespace 2022-05-14 14:51:34 +00:00
Cœur
bb5b4b1ba6 various: fix typos 2022-04-25 09:07:18 -04:00
Thomas Weißschuh
deedc3d418 ao_pipewire: Do not hold thread lock during loop stop
Stopping the thread is done using pw_thread_loop_stop(),
*which must be called without the lock held.*

Fixes #10033
2022-03-31 14:40:21 -07:00
Thomas Weißschuh
84dc9b1a02 ao_pipewire: fix resource lifetimes
We have to destroy the core before destroying the loop.
Also we have to lock the mainloop for operations on its objects.

Fixes #10003
2022-03-30 13:06:33 -07:00
LaserEyess
7ac4b7dfe7 ao_sndio: fix parentheses warning
No change in logic, but wrap the LT operator and the && in parentheses
to silence the compiler warning.
2022-03-11 16:43:31 +01:00
Alex B
bc9805c71a ao_pipewire: fix ao-volume handling
Pass channel volumes to `pw_stream_set_control` as array.
This is correct calling conventions and prevents
right channel muting every time ao-volume property is changed.

Terminate `pw_stream_set_control` calls with 0.
2022-02-11 11:27:57 -08:00
Thomas Weißschuh
09343bc86e ao_pipewire: validate pod creation
Our allocated buffers should be big enough, but add some errorhandling
just in case.
2022-02-06 22:44:40 -08:00
Thomas Weißschuh
b7a71ea706 ao_pipewire: add support for device selection 2022-02-06 22:44:40 -08:00
Andrew Krasavin
b01598510f ao_sndio: bugfix and small refactoring for #8314
Changes:
  * fixed hangups in the loop function and in some other cases
  * refactoring according to @michaelforney's recommendations in #8314
  * a few minor and/or cosmetic changes
  * ability to build ao_sndio using meson
2022-01-22 18:44:34 +00:00
rim
adc32e25e0 ao_sndio: add this audio output again
Changes:
- rewrite to use new internal MPV API;
- code refactoring;
- fix buffers size calculations;
- buffer set to auto;
- reset() - clean/reinit device only after errors;
2022-01-22 18:44:34 +00:00
Philip Langdale
22b0bac28e ao/pipewire: Add copyright header
Sometimes the most obvious things can be missed.

Reflects authorship described in the original commit.

* https://github.com/mpv-player/mpv/pull/7902
* fddb143282
* https://github.com/mpv-player/mpv/pull/9587
2022-01-17 13:48:44 -08:00
Thomas Weißschuh
87aba146ed ao_pipewire: Add PipeWire audio backend
The AO provides a way for mpv to directly submit audio to the PipeWire
audio server.
Doing this directly instead of going through the various compatibility
layers provided by PipeWire has the following advantages:

* It reduces complexity of going through the compatibility layers
* It allows a richer integration between mpv and PipeWire
  (for example for metadata)
* Some users report issues with the compatibility layers that to not
  occur with the native AO

For now the AO is ordered after all the other relevant AOs, so it will
most probably not be picked up by default.
This is for the following reasons:

* Currently it is not possible to detect if the PipeWire daemon that mpv
  connects to is actually driving the system audio.
  (https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1835)
* It gives the AO time to stabilize before it is used by everyone.

Based-on-patch-by: Oschowa <oschowa@web.de>
Based-on-patch-by: Andreas Kempf <aakempf@gmail.com>
Helped-by: Ivan <etircopyhdot@gmail.com>
2022-01-17 11:43:02 -08:00
Ivan
87ce3b31a9 ao_openal: enable AL_SOFT_direct_channels_remix extension by default
Prevent audio distortions caused by OpenAL's 3D effects.
2021-11-29 11:27:39 +01:00
Aman Karmani
ac3d567bd3 audio: stop corrupting audio on underreads
regression introduced in b74c09efbf

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-11-20 12:08:32 -08:00
Tom Yan
d1e9f4a159 ao_opensles: add guards for sample rate to use
Upstream "Wilhelm" (the Android OpenSLES implementation) supports
only 8000 <= rate <= 192000. Make sure mpv resamples the audio
when necessary.
2021-11-19 14:27:52 +01:00
Emil Velikov
37619c4cf5 options: remove always true m_obj_list::allow_unknown_entries
Ever instance of m_obj_list is a constant and for all of them, the field
is true. Just remove the field all together.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
2021-11-15 14:02:08 +00:00
Jan Ekström
e6a75075b2 ao_oss: define PATH_DEV_MIXER as it is an internal define
This fixes a mismatch between configure working and build time
failing with Linux + OSSv4, enabling compilation on Debian based
Linux systems with the oss4-dev package.

Fixes #9378
2021-11-10 17:08:16 +01:00
Aman Karmani
06392e7ec1 ao_audiotrack: change buffer sizing logic
Previously number of channels was being ignored.

The buffer will now be between 75ms and 150ms

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani
fa691e0f69 ao_audiotrack: allocate chunk buffer based on negotiated size
Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani
6473711dce ao_audiotrack: support delay up to 2s as normal
Fixes issues streaming to echo speaker pair from firetv devices.

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani
432c0255bc ao_audiotrack: set device_buffer based on underlying buffer size when available
Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
Aman Karmani
7356ee5339 ao_audiotrack: use new style initializer for AudioTrack when available
Fixes deprecation warnings printed when using this driver.

Signed-off-by: Aman Karmani <aman@tmm1.net>
2021-10-21 17:20:51 +02:00
sfan5
d2a56227df Revert "audio: fix ao_reset() not clearing paused state leading to stuck AO"
In hindsight this is obviously broken.
This reverts commit fb5d976cb0.
2021-07-18 12:21:15 +02:00
sfan5
fb5d976cb0 audio: fix ao_reset() not clearing paused state leading to stuck AO
This would happen when switching from playback stuck in cache wait
(underrun) to another file.
2021-07-16 20:58:54 +02:00
sfan5
aa300f8023 ao/pulse: fix incorrect state reported after reset
fixes #8768
2021-04-29 17:06:29 +02:00
rim
1b2e5137e0 ao_oss: add this audio output again
Changes:
- code refactored;
- mixer options removed;
- new mpv sound API used;
- add sound devices detect (mpv --audio-device=help will show all available devices);
- only OSSv4 supported now;

Tested on FreeBSD 12.2 amd64.
2021-03-15 12:42:35 +01:00
Thomas Weißschuh
63d71ba4ec ao/pulse: signal the mainloop when ops are done
Without the explicit signal the call to pa_threaded_mainloop_wait()
will not return as soon as possible.

Fixes 4f07607888
See #8633
2021-03-11 23:37:13 +02:00
Thomas Weißschuh
4f07607888 ao/pulse: wait for command completion when setting volume or mute
This makes the behavior of all control messages consistent,
fixing an inconsistency that has been with us since
4d8266c739 - which is the initial
rework of the polyaudio AO into the pulseaudio AO.

Muting the stream also directly triggers an update to the OSD.
When not waiting for the command completion this read of the mute
property may read the old state. A stale read.

Note that this somehow was not triggered on native Pulseaudio, but it is
an issue on Pipewire.

See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/868
2021-03-09 23:08:16 +02:00
Jan Ekström
8ddd4547fc ao_alsa: handle -EPIPE XRUNs from snd_pcm_status
Set pcm state to SND_PCM_STATE_XRUN in case -EPIPE is received,
and handle this state as per the usual logic.

This way snd_pcm_prepare gets called, and the loop continued.

Inspired by a patch posted by malc_ on #mpv.
2020-11-09 16:12:49 +01:00
Jan Ekström
976fcf57c1 ao_alsa: always initialize state if passed
Based on ao_play_data's assert, we are always expected to give
non-default values back from an AO's get_state.
2020-11-09 16:12:49 +01:00
sfan5
63ffa07b44 audio: take paused state into account in ao_start()
It makes no sense to instruct the AO to start the pull callbacks
when we know there's nothing to play (only affects pull AOs).
2020-09-20 18:52:54 +02:00
sfan5
c1db4630e6 audio: move start() calls outside of lock
Pull based AOs might want to call ao_read_data() inside start().
This fixes ao_opensles deadlocking.
2020-09-20 18:52:54 +02:00
wm4
cf19a0d3cc ao_alsa: make partial writes an error message
And I think "partial write" is easier to understand than "short write".
2020-09-03 22:40:20 +02:00
wm4
1643cb865f audio: fix stream-silence with push AOs (somewhat)
--audio-stream-silence is a shitty feature compensating for awful
consumer garbage, that mutes PCM at first to check whether it's
compressed audio, using formats advocated and owned by malicious patent
troll companies (who spend more money on their lawyers than paying any
technicians), wrapped in a wasteful way to make it constant bitrate
using a standard whose text is not freely available, and only rude users
want it. This feature has been carelessly broken, because it's
complicated and stupid. What would Jesus do? If not getting an aneurysm,
or pushing over tables with expensive A/V receivers on top of them, he'd
probably fix the feature. So let's take inspiration from Jesus Christ
himself, and do something as dumb as wasting some of our limited
lifetime on this incredibly stupid fucking shit.

This is tricky, because state changes like end-of-audio are supposed to
be driven by the AO driver, while playing silence precludes this. But it
seems code paths for "untimed" AOs can be reused.

But there are still problems. For example, underruns will just happen
normally (and stop audio streaming), because we don't have a separate
heuristic to check whether the buffer is "low enough" (as a consequence
of a network stall, but before the audio output itself underruns).
2020-09-03 22:39:23 +02:00
wm4
d3afe34c09 ao_lavc: slightly simplify filter use
Create a central function which pumps data through the filter. This also
might fix bogus use of the filter API on flushing. (The filter is just
used for convenience, but I guess the overall result is still simpler.)
2020-09-03 15:39:31 +02:00
wm4
5fc34cb4d6 ao_alsa: log more information on short writes 2020-09-02 22:22:45 +02:00
LAGonauta
0ac724f002 ao_openal: restore working condition with new push API 2020-08-31 20:24:14 +02:00
wm4
a805a152c1 ao: remove unused field 2020-08-31 20:23:44 +02:00
wm4
478d39c574 audio: fix inefficient behavior with ao_alsa, remove period_size field
It is now the AO's responsibility to handle period size alignment. The
ao->period_size alignment field is unused as of the recent audio
refactor commit. Remove it.

It turns out that ao_alsa shows extremely inefficient behavior as a
consequence of the removal of period size aligned writes in the
mentioned refactor commit. This is because it could get into a state
where it repeatedly wrote single samples (as small as 1 sample), and
starved the rest of the player as a consequence. Too bad. Explicitly
align the size in ao_alsa. Other AOs, which need this, should do the
same.

One reason why it broke so badly with ao_alsa was that it retried the
write() even if all reported space could be written. So stop doing that
too. Retry the write only if we somehow wrote less.

I'm not sure about ao_pulse.
2020-08-29 16:27:56 +02:00
wm4
b74c09efbf audio: refactor how data is passed to AO
This replaces the two buffers (ao_chain.ao_buffer in the core, and
buffer_state.buffers in the AO) with a single queue. Instead of having a
byte based buffer, the queue is simply a list of audio frames, as output
by the decoder. This should make dataflow simpler and reduce copying.

It also attempts to simplify fill_audio_out_buffers(), the function I
always hated most, because it's full of subtle and buggy logic.

Unfortunately, I got assaulted by corner cases, dumb features (attempt
at seamless looping, really?), and other crap, so it got pretty
complicated again. fill_audio_out_buffers() is still full of subtle and
buggy logic. Maybe it got worse. On the other hand, maybe there really
is some progress. Who knows.

Originally, the data flow parts was meant to be in f_output_chain, but
due to tricky interactions with the playloop code, it's now in the dummy
filter in audio.c.

At least this improves the way the audio PTS is passed to the encoder in
encoding mode. Now it attempts to pass frames directly, along with the
pts, which should minimize timestamp problems. But to be honest, encoder
mode is one big kludge that shouldn't exist in this way.

This commit should be considered pre-alpha code. There are lots of bugs
still hiding.
2020-08-29 13:12:32 +02:00
wm4
a7413aff22 audio: clarify set_pause() documentation 2020-08-27 11:55:20 +02:00
wm4
6b13d71cdc audio: remove unused ring.h includes
From what I can tell, this has been copy-pasted from times when
ao_coreaudio still used its own ringbuffer, instead of the common code.
2020-08-27 11:55:20 +02:00
sfan5
fb736b49f1 ao/pulse: create the stream corked
Previously get_state() would keep setting the cork status
while paused, but it only does for that after underflows now.
Correct this oversight by creating the stream corked for start()
to uncork it at a later time.

fixes #8026
2020-08-26 16:14:29 +02:00
ekisu
cdd8ba7224 ao/lavc: add channels and channel_layout to AVFrame
FFmpeg expects those fields to be set on the AVFrame when
encoding audio, not doing so will cause the avcodec_send_frame
call to return EINVAL (at least in recent builds).
2020-08-07 19:42:42 +02:00
sfan5
7a7a0a78b5 ao/pulse: fix reporting of playing state
When get_state() corks the stream after an underrun happens
priv->playing is incorrectly reset to true, which can cause the
player to miss the underrun entirely. Stop resetting priv->playing
during corking (but not uncorking) to fix this.
2020-07-12 23:44:41 +02:00
sfan5
f3b29a680c ao/pulse: flush stream on underrun
The underflow callback introduced in d27ad96 can be called
when the buffer is still full, causing playback to never
resume afterwards since get_state() reports free_samples == 0.
Fix this by fully resetting on underrun, which flushes
the stream and ensures free buffer space.

fixes #7874
2020-07-12 23:34:08 +02:00
Kevin Mitchell
5e323333cf
audio: don't lock ao_control for pull mode drivers
The pull mode APIs were previously required to have thread-safe
ao_controls. However, locks were added in b83bdd1 for parity with push
mode. This introduced deadlocks in ao_wasapi.

Instead, only lock ao_control for the push mode APIs.

fixes #7787

See also #7832, #7811. We'll wait for feedback to see if those should
also be closed.
2020-06-17 02:22:51 -07:00
wm4
d5de79d10f audio: require certain AOs to set device_buffer
AOs which use the "push" API must set this field now. Actually, this was
sort of always required, but happened to work anyway. The future
intention is to use device_buffer as the pre-buffer amount, which has to
be available right before audio playback is started. "Pull" AOs really
need this too conceptually, just that the API is underspecified.

From what I can see, only ao_null did not do this yet.
2020-06-09 16:49:05 +02:00
Nicolas F
0fb02f181f ao/pulse: properly set device_buffer
Previously, device_buffer defaulted to 0 on pulse. This meant that
commit baa7b5c would always wait with a timeout of 0, leading to
high CPU usage for PulseAudio users.

By setting device_buffer to the number of samples per channel that
PulseAudio sets as its target, this commit fixes this behaviour.
2020-06-07 22:16:49 +03:00
wm4
c67f36dd18 audio: fix deadlock on draining
The playback thread may obviously still fill the AO'S entire audio
buffer, which means it unset p->draining, which makes no sense and broke
ao_drain(). So just don't unset it here.

Not sure if this really fixes this, it was hard to reproduce. Regression
due to the recent changes. There are probably many more bugs like this.
Stupid asynchronous nightmare state machine. Give me a language that
supports formal verification (in presence of concurrency) or something.
2020-06-04 12:42:36 +02:00
wm4
baa7b5c8dd audio: adjust wait duration
I feel like this makes slightly more sense. At least it doesn't include
the potentially arbitrary constant latency that is generally included in
the delay value. Also, the buffer status doesn't matter - either we've
filled the entire buffer (then we can wait this long), or there's not
enough data anyway (then the core will wake up the thread if new data is
available).

But ultimately, we have to guess, unless the AO does notify us with
ao_wakeup_playthread().

Draining may now wait for no reason up to 1/4th of the total buffer
time. Shouldn't be a disimprovement in practice.
2020-06-03 15:22:18 +02:00
wm4
68ade4e5a5 audio: avoid possible deadlock regression for some AOs
It's conceivable that ao->driver->reset() will make the audio API wait
for ao_read_data() (i.e. its audio callback) to return. Since we
recently moved the reset() call inside the same lock that ao_read_data()
acquires, this could deadlock. Whether this really happens depends on
how exactly the AO behaves. For example, ao_wasapi does not have this
problem. "Push" AOs are not affected either.

Fix by moving it outside of the lock. Assume ao->driver->start() will
not have this problem.

Could affect ao_sdl, ao_coreaudio (and similar rotten fruit AOs). I'm
unsure whether anyone experienced the problem in practice.
2020-06-02 20:43:49 +02:00
wm4
08b198aab4 audio: further simplify internal audio API somewhat
Instead of the relatively subtle underflow handling, simply signal
whether the stream is in a playing state. Should make it more robust.

Should affect ao_alsa and ao_pulse only (and ao_openal, but it's
broken).

For ao_pulse, I'm just guessing. How the hell do you query whether a
stream is playing? Who knows. Seems to work, judging from very
superficial testing.
2020-06-02 20:43:49 +02:00
wm4
0d3474c6c0 audio: slightly better condition for still_playing
Just a detail. If wrong (not unlikely because I'm just guessing my own
messy state machine), this will make the player freeze due to waiting
for something that never happens. Enjoy.
2020-06-02 20:43:49 +02:00
wm4
c5158b057c audio: reduce extra wakeups caused by recent changes
The feeder thread basically woke up the core and itself too often, and
caused some CPU overhead. This was caused by the recent buffer.c
changes.

For one, do not let ao_read_data() wake up the core, and instead rely on
the feeder thread's own buffer management. This is a bit strange, since
the change intended to unify the buffer management, but being more
consequent about it is better deferred to later, when the buffer
management changes again anyway. And also, the "more" condition in the
feeder thread seems outdated, or at least what made it make sense has
been destroyed, so do something that may or may not be better. In any
case, I'm still not getting underruns with ao_alsa, but the wakeup
hammering is gone.
2020-06-01 15:48:45 +02:00
wm4
d27ad96542 audio: redo internal AO API
This affects "pull" AOs only: ao_alsa, ao_pulse, ao_openal, ao_pcm,
ao_lavc. There are changes to the other AOs too, but that's only about
renaming ao_driver.resume to ao_driver.start.

ao_openal is broken because I didn't manage to fix it, so it exits with
an error message. If you want it, why don't _you_ put effort into it? I
see no reason to waste my own precious lifetime over this (I realize the
irony).

ao_alsa loses the poll() mechanism, but it was mostly broken and didn't
really do what it was supposed to. There doesn't seem to be anything in
the ALSA API to watch the playback status without polling (unless you
want to use raw UNIX signals).

No idea if ao_pulse is correct, or whether it's subtly broken now. There
is no documentation, so I can't tell what is correct, without reverse
engineering the whole project. I recommend using ALSA.

This was supposed to be just a simple fix, but somehow it expanded scope
like a train wreck. Very high chance of regressions, but probably only
for the AOs listed above. The rest you can figure out from reading the
diff.
2020-06-01 01:08:16 +02:00
wm4
d448dd5bf2 audio: fix unpausing with some AOs
wasapi/coreaudio/sdl were affected, alsa/pusle were not.

The confusion here was that resume() has different meaning with pull and
push AOs.

Fixes: #7772
2020-05-31 14:43:13 +02:00
wm4
27e41c69aa ao_null: remove unreferenced function
Forgot in the previous commit to this file.
2020-05-27 21:29:43 +02:00
wm4
a4b7fcc183 audio: stop applying volume twice for some AOs
Regression since the recent refactor. How did nobody notice?

This happened because the push code now calls the function for the pull
code. Both the former and latter apply the volume, so oops.
2020-05-27 21:11:46 +02:00
wm4
9885952c2a audio: remove ao_driver.drain
The recent change to the common code removed all calls to ->drain. It's
currently emulated via a timed sleep and polling ao_eof_reached(). That
is actually fallback code for AOs which lacked draining. I could just
readd the drain call, but it was a bad idea anyway. My plan to handle
this better is to require the AO to signal a underrun, even if
AOPLAY_FINAL_CHUNK is not set. Also reinstate not possibly waiting for
ao_lavc.c. ao_pcm.c did not have anything to handle this; whatever.
2020-05-27 21:04:32 +02:00
wm4
b83bdd1d17 audio: merge pull/push ring buffer glue code
This is preparation to further cleanups (and eventually actual
improvements) of the audio output code.

AOs are split into two classes: pull and push. Pull AOs let an audio
callback of the native audio API read from a ring buffer. Push AOs
expose a function that works similar to write(), and for which we start
a "feeder" thread. It seems making this split was beneficial, because of
the different data flow, and emulating the one or other in the AOs
directly would have created code duplication (all the "pull" AOs had
their own ring buffer implementation before it was cleaned up).
Unfortunately, both types had completely separate implementations (in
pull.c and push.c). The idea was that little can be shared anyway. But
that's very annoying now, because I want to change the API between AO
and player.

This commit attempts to merge them. I've moved everything from push.c to
pull.c, the trivial entrypoints from ao.c to pull.c, and attempted to
reconcile the differences. It's a mess, but at least there's only one
ring buffer within the AO code now. Everything should work mostly the
same. Pull AOs now always copy the audio data under a lock; before this
commit, all ring buffer access was lock-free (except for the decoder
wakeup callback, which acquired a mutex). In theory, this is "bad", and
people obsessed with lock-free stuff will hate me, but in practice
probably won't matter. The planned change will probably remove this
copying-under-lock again, but who knows when this will happen.

One change for the push AOs now makes it drop audio, where before only a
warning was logged. This is only in case of AOs or drivers which exhibit
unexpected (and now unsupported) behavior.

This is a risky change. Although it's completely trivial conceptually,
there are too many special cases. In addition, I barely tested it, and
I've messed with it in a half-motivated state over a longer time, barely
making any progress, and finishing it under a rush when I already should
have been asleep. Most things seem to work, and I made superficial tests
with alsa, sdl, and encode mode. This should cover most things, but
there are a lot of tricky things that received no coverage. All this
text means you should be prepared to roll back to an older commit and
report your problem.
2020-05-25 01:54:37 +02:00
wm4
bca917f6d2 ao_oss: remove this audio output
Ancient Linux audio output. Apparently it survived until now, because
some BSDs (but not all) had use of this. But these should work with
ao_sdl or ao_openal too (that's why these AOs exist after all). ao_oss
itself has the problem that it's virtually unmaintainable from my point
of view due to all the subtle (or non-subtle) difference. Look at the
ifdef mess and the multiple code paths (that shouldn't exist) in the
removed source code.
2020-03-28 20:59:31 +01:00
wm4
4583bd8cc7 ao_rsound: remove this audio output
I wonder what this even is. I've never heard of anyone using it, and
can't find a corresponding library that actually builds with it. Good
enough to remove.
2020-03-28 20:59:00 +01:00
wm4
71d218eae4 ao_sndio: remove this audio output
It was always marked as "experimental", and had inherent problems that
were never fixed. It was disabled by default, and I don't think anyone
is using it.
2020-03-28 20:58:56 +01:00
wm4
6169fba796 encode: fix occasional init crash due to initialization order issues
Looks like the recent change to this actually made it crash whenever
audio happened to be initialized first, due to not setting the
mux_stream field before the on_ready callback. Mess a way around this.

Also remove a stray unused variable from ao_lavc.c.
2020-03-22 21:08:44 +01:00
wm4
63311762ed encode: add some shit that does some shit
?????????????

Makes no sense, can endless loop, but whatever.

Part of #7524.
2020-03-22 13:07:36 +01:00
wm4
de53155971 encode: restore audio muxer timebase use
Seems to crash hard if an error happens somewhere at init. Who cares.

Part of #7524.
2020-03-22 13:06:59 +01:00
Kevin Mitchell
3aad89829f ao_wasapi: try mix format except for chmap
In shared mode, we previously tried to feed the full native format to
IsFormatSupported in the hopes that the "closest match" returned was
actually that.

Turns out, IsFormatSupported will always return the mix format if we
don't use the mix format's sample rate. This will also clobber our
choice of channel map with the mix format channel map even if our
desired channel map is supported due to surround emulation.

The solution is to not bother trying to use anything other than the mix
format sample rate. While we're at it, we might as well use the mix
format PCM sample format (always float32) since this conversion will
happen anyway and may avoid unecessary dithering to intermediate
integer formats if we are already resampling or channel mixing.
2020-03-19 20:39:44 +02:00
Kevin Mitchell
609d0ef478 ao_wasapi: handle S_FALSE in mp_format_res_str
IsFormatSupported may return S_FALSE (considered SUCCESS) if the
requested format is not suppported, but is close to one that is.
2020-03-19 20:39:44 +02:00
wm4
26f4f18c06 options: change option macros and all option declarations
Change all OPT_* macros such that they don't define the entire m_option
initializer, and instead expand only to a part of it, which sets certain
fields. This requires changing almost every option declaration, because
they all use these macros. A declaration now always starts with

   {"name", ...

followed by designated initializers only (possibly wrapped in macros).
The OPT_* macros now initialize the .offset and .type fields only,
sometimes also .priv and others.

I think this change makes the option macros less tricky. The old code
had to stuff everything into macro arguments (and attempted to allow
setting arbitrary fields by letting the user pass designated
initializers in the vararg parts). Some of this was made messy due to
C99 and C11 not allowing 0-sized varargs with ',' removal. It's also
possible that this change is pointless, other than cosmetic preferences.

Not too happy about some things. For example, the OPT_CHOICE()
indentation I applied looks a bit ugly.

Much of this change was done with regex search&replace, but some places
required manual editing. In particular, code in "obscure" areas (which I
didn't include in compilation) might be broken now.

In wayland_common.c the author of some option declarations confused the
flags parameter with the default value (though the default value was
also properly set below). I fixed this with this change.
2020-03-18 19:52:01 +01:00
wm4
9d04e76f3f ao_pcm: fix double free on exit
This seems to be an older bug. It set priv->outputfilename to a new
talloc-allocated string, but the field is also managed as string option,
so talloc will free it first, then m_option_free() is called on the
dangling pointer. Possibly this is caused by the earlier ta destruction
order change.
2020-03-14 13:50:04 +01:00
wm4
8d965a1bfb options: change how option range min/max is handled
Before this commit, option declarations used M_OPT_MIN/M_OPT_MAX (and
some other identifiers based on these) to signal whether an option had
min/max values. Remove these flags, and make it use a range implicitly
on the condition if min<max is true.

This requires care in all cases when only M_OPT_MIN or M_OPT_MAX were
set (instead of both). Generally, the commit replaces all these
instances with using DBL_MAX/DBL_MIN for the "unset" part of the range.

This also happens to fix some cases where you could pass over-large
values to integer options, which were silently truncated, but now cause
an error.

This commit has some higher potential for regressions.
2020-03-13 17:34:46 +01:00
wm4
5d5a7e1953 ao_lavc: don't spam underrun warnings
Like ao_pcm, this is (conceptually) in perpetual underrun, as long as
dumping is fast enough.
2020-03-13 16:50:27 +01:00
wm4
eb381cbd4b options: split m_config.c/h
Move the "old" mostly command line parsing and option management related
code to m_config_frontend.c/h. Move the the code that enables other part
of the player to access options to m_config_core.c/h. "frontend" is out
of lack of creativity for a better name.

Unfortunately, the separation isn't quite clean yet. m_config_frontend.c
still references some m_config_core.c implementation details, and
m_config_new() is even left in m_config_core.c for now. There some odd
functions that should be removed as well (marked as "Bad functions").
Fixing these things requires more changes and will be done separately.

struct m_config is left with the current name to reduce diff noise.
Also, since there are a _lot_ source files that include m_config.h, add
a replacement m_config.h that "redirects" to m_config_core.h.
2020-03-13 16:50:27 +01:00
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
Rafael Rivera
c40554295a ao_wasapi_utils: remove invalid audio session icon path (fixes #7269) 2020-01-31 23:08:47 +11: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
Aman Gupta
f93faf26d8 audio: fix minor whitespace issue in out/internal.h 2019-11-19 12:10:26 -08:00
wm4
6d92e55502 Replace uses of FFMIN/MAX with MPMIN/MAX
And remove libavutil includes where possible.
2019-10-31 11:24:20 +01: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
cde94e83a9 audio/out: rip out old unused app/softvolume reporting
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.
2019-10-11 21:05:11 +02:00
wm4
d908fbd584 audio/out/pull, ao_sdl: implement new underrun reporting
See previous commits. ao_sdl is worthless, but it might be a good test
for pull-based AOs.

This stops using the old underrun reporting if the new one is enabled.
Also, since the AO's behavior can in theory not be according to
expectations, this needs to be enabled for every single pull AO
separately.

For some reason, in certain cases I get multiple underrun warnings while
cache-pausing is active. It fills the cache, restarts the AO,
immediately underruns again, and then fills the cache again. I'm not
sure why this happens; maybe ao_sdl tries to catch up when it shouldn't.
Who knows.
2019-10-11 20:02:23 +02:00
wm4
89c717559b audio/out/pull: fix underflow reporting
I think this was _always_ wrong. Due to the line above the first changed
line, buffered_bytes==bytes always. I can only hope I broke this in a
less under-tested edit when I originally wrote this.

Fixes: c5a82f729b
2019-10-11 20:02:23 +02:00
wm4
1723b88cdd ao_alsa: use AO underrun reporting
This enables the change introduced in the previous commit for ao_alsa.
2019-10-11 20:02:23 +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
52f3dee16a ao_alsa: handle underruns in get_space() too
This is essentially optional. But it will give the higher level code a
better guarantee that underruns were tested.
2019-10-11 19:19:59 +02:00
wm4
c6c93499cb ao_alsa: mess with underrun handling again
This commit tries to prepare for better underrun reporting. The goal is
to report underruns relatively immediately. Until now, this happened
only when play() was called. Change this, and abuse that get_delay() is
called "relatively often" - this reports the underrun immediately in
practice.

Background:

In commit 81e51a15f7 (and also e38b0b245e), we were quite confused
about ALSA underrun handling. The commit message showed uncertainty how
case 3 happened, but it's blindingly obvious and simple.

Actually reading the code shows that ALSA does not have a concept of a
"final chunk" (or we don't use it). It's obvious we never pass the
AOPLAY_FINAL_CHUNK flag along to the ALSA API in any way. The only thing
we do is simply writing a partial fragment. Of course this will cause an
underrun. Doing a partial write saves us the trouble to pad the last
frame with silence, or so.

The main reason why the underrun message was avoided was that play() was
never called with a non-0 sample count again (except if reset() was
called before that). That was OK, at least the goal of avoiding the
unwanted message was reached. (And the original "bogus" message at end
of playback was perfectly correct, as far as ALSA goes.)

If network stalls, play() will called again only once new data is
available. Obviously, this could take a long time, thus it's too late.
2019-10-11 16:52:45 +02:00
wm4
e38b0b245e ao_alsa: don't silence legitimate underrun if final chunk underruns
It turns out that case 2) mentioned in the previous commit happened
quite often when playback ended normally.

There is probably a legitimate underrun with normal buffer sizes (100
ms, 4 fragments, gapless audio in "weak" mode). This is a result of the
player waiting for video to end, and/or the time needed to kill the
video window. The former case means that it depends on your test case
whether it happens (a file where video ends slightly before audio is
less likely to trigger it).

This in turn is due to how gapless playback works. Achieving not having
a "gap" requires queuing the audio of the next file without playing a
partial chunk (as AOPLAY_FINAL_CHUNK would do). The partial chunk is
then played as part of the first chunk played from the next file. But if
it detects "later" that there is no next file, it still needs to get rid
of the last fragment with AOPLAY_FINAL_CHUNK. At this point it's too
late, and an underrun may have actually happened. The way the player
uninits and reinits the entire playback engine for the next file in a
"serial" manner means it cannot know in advance whether this works.

This is the reason why the idiot who added the underrun exception for
the last chunk in play() was wrong (I wrote that btw., before you accuse
me of being rude). Yes, it's a real underrun, and you could probably
hear it.
2019-10-06 20:46:22 +02:00
wm4
81e51a15f7 ao_alsa: remove sometimes bogus XRUN message
This XRUN (aka underrun) message was printed in the following
situations:

1) legitimate underrun during playback
2) legitimate underrun when playing final chunk
3) bogus underrun when playing final chunk

The old underrun case (in play()) happens in cases 1) and 2) as well,
but 3) did not happen. It appears 3) is indeed something that happens,
although it's not known for sure. It's still pretty annoying, so remove
the new XRUN message.

When testing, care should be taken to play with buffer sizes, video
versus no video, and gapless enabled/disabled. Also, suspending the
player with Ctrl+Z in the terminal (SIGSTOP) and then resuming is a good
way to trigger a "normal" underrun.
2019-10-06 20:46:22 +02:00
Philip Sequeira
21a5c416d5 options: add M_OPT_FILE to some more options that take files 2019-09-27 13:19:29 +02:00
Jan Ekström
69e4a5772a ao_pulse: add the newly added mappings for TrueHD/DTS-HD formats
Originally DTS-HD was mapped to PA_ENCODING_DTS_IEC61937 which I'm
actually not sure if it ever worked.
2019-09-27 00:23:36 +03:00
Leonardo Taccari
3d911d8ef0 ao_oss: Fallback to stereo when the device does not support >2 channels
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.
2019-09-21 15:38:46 +02:00
Térence Clastres
41f4e8d73a ao_pulse: add --pulse-allow-suspended
This flag makes mpv continue using the PulseAudio driver even if the
sink is suspended.
This can be useful if JACK is running with PulseAudio in bridge mode and
the sink-input assigned to mpv is the one JACK controls, thus being
suspended.
By forcing mpv to still use PulseAudio in this case, the user can now
adjust the sink to an unsuspended one.
2019-09-21 12:54:36 +02:00
sfan5
8f96169117 ao_opensles: fix delayed audio
This was forgotten in commit 5a8c48fde2
when the number of buffers was reduced to 1.
2019-09-02 00:38:05 +03:00
Aman Gupta
8b114e574a ao/audiounit: include AVAudioSession buffer in latency calc
Signed-off-by: Aman Gupta <aman@tmm1.net>
2019-04-05 10:29:44 +07:00
Aman Gupta
e35aca3cb4 ao/audiounit: improve a/v sync
This more closely mimics ao_coreaudio, on which this driver was
originally based.

Signed-off-by: Aman Gupta <aman@tmm1.net>
2019-04-05 10:29:44 +07:00
Anton Kindestam
8b83c89966 Merge commit '559a400ac36e75a8d73ba263fd7fa6736df1c2da' into wm4-commits--merge-edition
This bumps libmpv version to 1.103
2018-12-05 19:19:24 +01:00
Josh Lehman
515c4163ea ao_audiounit: rename pause function to reset
AudioUnit output driver uses the pull based api so it should have
a reset function instead of a pause function.
2018-09-30 16:01:21 -07:00
Jan Ekström
cea4ff3e5f ao_alsa: log the ALSA state if we get a non-XRUN error
The ALSA state generally can tell us more information in case we
get an unexpected error.
2018-09-29 20:02:46 +02:00
Jan Ekström
fdc952486a ao_alsa: handle XRUNs separately from other errors
According to ALSA doxy, EPIPE is a synonym to SND_PCM_STATE_XRUN,
and that is a state that we should attempt to automatically recover
from. In case recovery fails, log an error and return zero.

A warning message will still be output for each XRUN since those
are not something we should generally be receiving.
2018-09-29 20:02:46 +02:00
Jan Ekström
3218a58082 ao_alsa: early exit get_space if paused or ALSA is not ready
This has been way too long coming, and for me to notice that a
whole lot of ao_alsa functions do an early return if the AO is
paused.

For the STATE_SETUP case, I had this reproduced once, and never
since. Still, seems like we can start calling this function before
the ALSA device has been fully initialized so we might as well
early exit in that case.
2018-09-29 20:02:46 +02:00
Niklas Haas
fed0ea111b ao_jack: only auto-connect to audio ports
This prevents ao_jack from auto-connecting to MIDI ports (or other,
hypothetical future port types).
2018-09-26 22:44:48 +03:00
Tom Yan
9d6b15ab32 ao_pulse: fix tlength calculation
also remove the now unused non-sensical af_fmt_seconds_to_bytes.
2018-09-01 16:14:11 +02:00
Michael Hoang
91786fa99c Revert "ao_openal: enable building on OSX"
This reverts commit af6126adbe. Apple's
OpenAL support is ridiculously out of date, revert back to just using
OpenAL Soft on macOS (fixes #4645).
2018-08-26 15:49:22 +03:00
Tom Yan
6c2d6a3046 ao_opensles: set numBuffers to 8
Apparently some Android builds/forks require this for Bluetooth
audio to work as they unexpectedly accept fast flag for it.

Shouldn't cause any side-effect (e.g. buffer requirement increased
when on wired audio). It's a hardcoded default in the upstream
AAudio implementation anyway.

Ref.:
https://android.googlesource.com/platform/frameworks/av/+/android-8.0.0_r1/media/libaaudio/src/legacy/AudioStreamTrack.cpp#109
https://android.googlesource.com/platform/frameworks/wilhelm/+/android-8.0.0_r1/src/android/AudioPlayer_to_android.cpp#1680
https://android.googlesource.com/platform/frameworks/av/+/android-8.0.0_r1/media/libaudioclient/AudioTrack.cpp#488
2018-08-13 19:10:10 +02:00
Tom Yan
e1bd5288b7 ao_opensles: rework the heuristic of buffer/enqueue size setting
ao->device_buffer will only affect the enqueue size if the latter
is not specified. In other word, its intended purpose will solely
be setting/guarding the soft buffer size.

This guarantees that the soft buffer size will be consistent no
matter a specific enqueue size is set or not. (In the past it
would drop to the default of the generic audio-buffer option.)

opensles-frames-per-buffer has been renamed to opensles-frames-per
-enqueue, as it was never purposed to set the soft buffer size. It
will only make sure the size is never smaller than itself, just as
before.

opensles-buffer-size-in-ms is introduced to allow easy tuning of
the relative (i.e. in time) soft buffer size (and enqueue size,
unless the aforementioned option is set). As "device buffer" never
really made sense in this AO, this option OVERRIDES audio-buffer
whenever its value (including the default) is larger than 0.

Setting opensl-buffer-size-in-ms to 1 allows you to equate the soft
buffer size to the absolute enqueue size set with opensl-frames-per
-enqueue conveniently (unless it is less than 1ms).

When both are set to 0, audio-buffer will be the ultimate fallback.
If audio-buffer is also 0, the AO errors out.
2018-08-05 17:52:01 +02:00
Tom Yan
8baad91e7b ao_opensles: allow s32 and float output
OpenSLES (and its AudioTrack backend) in Android can take 32-bit
fixed and floating point input since Android L (API 21).
2018-08-05 17:51:45 +02:00
Jan Ekström
36cc33ff5a ao_alsa: simplify get_space() 2018-06-04 00:03:11 +03:00
Muhammad Faiz
945303a92e ao_alsa: replace snd_pcm_status() with snd_pcm_avail() in get_space()
Fixes a bug with alsa dmix on Fedora 29. After several minutes,
audio suddenly becomes bad and muted.

Actually, I don't know what causes this. Probably this is a bug in alsa.
In any case, as snd_pcm_status() returns not only 'avail', but also other
fields such as tstamp, htstamp, etc, this could be considered a good
simplification, as only avail is required for this function.
2018-06-04 00:00:57 +03: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
f18c4175ad encode: remove old timestamp handling
This effectively makes --ocopyts the default. The --ocopyts option
itself is also removed, because it's redundant.
2018-05-03 01:08:44 +03:00
wm4
6c8362ef54 encode: rewrite half of it
The main change is that we wait with opening the muxer ("writing
headers") until we have data from all streams. This fixes race
conditions at init due to broken assumptions in the old code.

This also changes a lot of other stuff. I found and fixed a few API
violations (often things for which better mechanisms were invented, and
the old ones are not valid anymore). I try to get away from the public
mutex and shared fields in encode_lavc_context. For now it's still
needed for some timestamp-related fields, but most are gone. It also
removes some bad code duplication between audio and video paths.
2018-04-29 02:21:32 +03:00
wm4
20a1f250c6 encode: cosmetics
Mostly whitespace changes; some semantic preserving transformations.
2018-04-20 12:37:34 +02:00
wm4
9ee9313465 ao_alsa: actually report underruns to user
Print them as a warning.

Note that there may be some cases where it underruns, without being a
bad condition. This could possibly happen e.g. if the last chunk is
written, and then it resumes playback some time after that. Eventually I
want to add more code to avoid such spurious warnings.
2018-04-15 23:11:33 +03:00
wm4
66810c1550 ao_pulse: reduce requested device buffer size
Same deal as with the previous commit for ALSA.

Untested.
2018-04-15 23:11:33 +03:00
wm4
17f58455b0 ao_alsa: reduce requested buffer size
There is a dedicated thread for feeding audio to the ALSA API from a
buffer with a larger size. There is little reason to have such a large
device buffer.
2018-04-15 23:11:33 +03:00
wm4
401bd57d44 ao_alsa: add options for controlling period/buffer size 2018-04-15 23:11:33 +03:00
Jan Ekström
9de51b6032 ao_openal: document the muted↔gain conversion
This struck me as odd for a moment, so adding a comment.
2018-04-15 01:18:53 +03:00
LAGonauta
614ad62f89 ao/openal: Add option to set buffering characteristics
One can now set the number of buffers and the buffer size.
This can reduce the CPU usage and the total latency stays mostly the same.
As there are sync mechanisms the A/V sync continue intact and working.

It also modifies 6.1 channel order, as per OpenAL spec
and add AOPLAY_FINAL_CHUNK support
2018-04-15 00:57:01 +03:00
LAGonauta
567df04012 ao/openal: Add better sample format and channel layout selection
Also re-added floating-point support.
2018-04-15 00:57:01 +03:00
LAGonauta
8f82dc92aa ao/openal: Add OpenAL Soft extension to get the correct latency
OpenAL Soft's AL_SOFT_source_latency extension allows one to correctly
get the device output latency, facilitating the syncronization with
video.
Also added a simpler generic fallback that does not take into account
latency of the device.
2018-04-15 00:57:01 +03:00
LAGonauta
dd357a7d53 ao/openal: Add support for direct channels output
Uses OpenAL Soft's AL_DIRECT_CHANNELS_SOFT extension and can be controlled through
a new CLI option, --openal-direct-channels.
This allows one to send the audio data direrctly to the desired channel without
effects applied.
2018-04-15 00:57:01 +03:00
LAGonauta
abaab930f0 ao/openal: Add hardware mute support
While the volume is set on the listener, mute is set on the sound source.
Seemed easier that way.
2018-04-15 00:57:01 +03:00
LAGonauta
c59ebbe399 ao/openal: Use only one source for audio output
Floating point audio not supported on this commit.
2018-04-15 00:57:01 +03:00
Tom Yan
b0951d71f8 ao_opensles: let cfg_frames_per_buffer accept buffer size up to 0.5s at 192kHz 2018-04-05 04:35:49 +03:00
Tom Yan
e3b3e28deb ao_opensles: remove useless cfg_sample_rate
We should always use the ao-neutral --audio-samplerate option.
2018-04-05 04:35:49 +03:00
Tom Yan
14b429de8d ao_opensles: bump device buffer size to 250ms
Although half (non-fast track on sink rate) or one-third (non-fast track not on sink rate) of the buffer size of the created AudioTrack instance as the SL Enqueue buffer size is basically enough for dropout-free playback, only using the full size can avoid stutter upon (re)start of playback.

Here are the various buffer sizes on different track/sink rate when on Bluetooth audio on Android O:

aptX @ 48kHz:
Sink rate: 48000 Hz
44100 Hz: 10632 frames (241.09 ms)
48000 Hz: 11544 frames (240.50 ms)
88200 Hz: 21216 frames (240.54 ms)
96000 Hz: 23088 frames (240.50 ms)
176400 Hz: 42384 frames (240.27 ms)
192000 Hz: 46128 frames (240.25 ms)

SBC/AAC/aptX @ 44.1kHz:
Sink rate: 44100 Hz
44100 Hz: 10776 frames (244.35 ms)
48000 Hz: 11748 frames (244.75 ms)
88200 Hz: 21552 frames (244.35 ms)
96000 Hz: 23448 frames (244.25 ms)
176400 Hz: 43056 frames (244.08 ms)
192000 Hz: 46848 frames (244.00 ms)

The above results were produced with the following code:

import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioTrack;

class AudioInfo {
    public static void main(String[] args) {
	int nosr = AudioTrack.getNativeOutputSampleRate(3);
	System.out.printf("Sink rate: %d Hz\n", nosr);

	int[] rates = {44100,48000,88200,96000,176400,192000};
	for (int rate: rates) {
	    AudioAttributes aa = new AudioAttributes.Builder().setFlags(256).build();
	    AudioFormat af = new AudioFormat.Builder().setSampleRate(rate).build();
	    AudioTrack at = new AudioTrack(aa, af, 4, 1, 0);
	    int sr = at.getSampleRate();
	    int bs = at.getBufferSizeInFrames();
	    float ms = bs * (float) 1000 / sr;
	    at.release();
	    System.out.printf("%d Hz: %d frames (%.2f ms)\n", sr, bs, ms);
	}
    }
}

Therefore bumping the device buffer size to 250ms.
2018-04-05 04:35:49 +03:00
Tom Yan
5a8c48fde2 ao_opensles: do one buffer only
Doing two buffers causes stutters upon (re)start of playback on Android O for all kinds of sinks.
2018-04-05 04:35:49 +03:00
Jan Ekström
59a04562b1 ao_opensles: re-flow interface/configuration retrieval
This manages to make the code more readable. Thanks to
MakeGho@IRCnet for the snippet on which this was based.
2018-03-24 03:43:57 +02:00
Aman Gupta
aaa076b631 ao_opensles: fix audio sync using device latency extension 2018-03-23 01:00:01 +02:00
wm4
2f20168b0b ao_sdl: fix default buffer size
If you set desired.samples to 0, SDL will return a default buffer size
on obtained.samples. This was broken, because ceil_power_of_two(0)
returns 1. Since 0 is usually not considered a power of two, this is
probably correct, but we still want to set desired.samples to 0 in this
case.
2018-03-08 17:12:32 -08: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
tomty89
013a8f75f3 ao_opensles: bump device buffer size to 200ms
While the soft buffer size is already by default 200ms, it is not enough to guarantee dropout-free playback on Bluetooth audio. Bumping the device buffer size to the same value seems to suffice.
2018-03-07 01:40:05 +02:00
tomty89
0a9ab1b076 ao_opensles: remove set_play_state()
Set play state to playing in init() instead. We no longer touch the play state afterwards.
2018-03-07 01:40:05 +02:00
tomty89
ba68e570de ao_opensles: clear buffer queue in reset()
Avoid resume() from causing SL_RESULT_BUFFER_INSUFFICIENT ("Failed to Enqueue: 7" when seek or resume from pause).
2018-03-07 01:40:05 +02: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