1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-21 23:36:58 +00:00
mpv/audio/out
sunpenghao 6863eefc3d ao_wasapi: address premature buffer fills in exclusive mode
Currently, running AO control wakes up the WASAPI renderer thread in the
`WASAPI_THREAD_FEED` state, where `thread_feed` will be called. However,
it seems that in recent Windows versions (tested on Windows 10 build
19044.3930 and Windows 11 build 22631.3007) we can't know if it is safe
to feed more audio data in event-driven exclusive mode:
- `IAudioClient_GetCurrentPadding` always returns `bufferFrameCount`,
  even if *NO* data has ever been written. This means we don't know how
  much free space we have that is available for writing. This is not the
  case in shared mode, where the return value correctly reflects the
  size of data waiting to be processed. As a sidenote, MS did not
  document the precise definition of the return value for an
  event-driven, exclusive stream [1].
- `IAudioRenderClient_GetBuffer` never fails. We can call it for 10
  times in a roll, each time requesting an entire buffer (the unit at
  which data is exchanged in exclusive mode using event-driven
  buffering; there are 2 such buffers) and get a successful return code
  everytime. In shared mode, we get `AUDCLNT_E_BUFFER_TOO_LARGE` if we
  request a buffer larger than that currently available.

As a result, `thread_feed` will always write `bufferFrameCount` frames
of audio in exclusive mode. There will therefore be glitches each time
`thread_control` is called due to the subsequent `thread_feed`
overwriting frames yet to be processed. Also, an irreversible error is
accumulated to `sample_count` as long as there is no AO reset, leading
to eventual, unbounded A/V desync.

As a fix to the issue, add a dedicated state for dispatch queue
processing so that `thread_feed` is only called when signaled by the OS.
The buffer checks in `thread_feed` that use `GetCurrentPadding` in
exclusive mode are kept in case there are older versions where the two
APIs behave differently.

Closes #12615.

[1] https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-getcurrentpadding
2024-02-24 05:26:56 +00:00
..
ao_alsa.c options: remove explicit initialization of integers to 0 2023-02-21 17:15:17 +00:00
ao_audiotrack.c ao_audiotrack: switch to ao_read_data_nonblocking() 2023-11-08 20:26:23 +01:00
ao_audiounit.m ao: convert all timing code to nanoseconds 2023-10-16 15:38:59 +00:00
ao_coreaudio_chmap.c ao_coreaudio_chmap: suppress vla warning 2023-11-24 10:05:09 +01:00
ao_coreaudio_chmap.h osdep: remove atomic.h 2023-10-20 21:31:09 +02:00
ao_coreaudio_exclusive.c various: make mentions of macOS consistent 2024-02-21 20:46:53 +01:00
ao_coreaudio_properties.c various: fix typos 2022-04-25 09:07:18 -04:00
ao_coreaudio_properties.h ao_coreaudio: change license to LGPL 2017-05-08 13:57:40 +02:00
ao_coreaudio_utils.c various: replace some OOM handling 2023-11-24 10:04:55 +01:00
ao_coreaudio_utils.h osdep: remove atomic.h 2023-10-20 21:31:09 +02:00
ao_coreaudio.c ao_coreaudio: switch to ao_read_data_nonblocking() 2023-11-08 20:26:23 +01:00
ao_jack.c various: sort some standard headers 2023-10-20 21:31:09 +02:00
ao_lavc.c ALL: use new mp_thread abstraction 2023-11-05 17:36:17 +00:00
ao_null.c ao_null: fix reset() implementation 2024-01-12 20:36:04 +01:00
ao_openal.c options: transition options from OPT_FLAG to OPT_BOOL 2023-02-21 17:15:17 +00:00
ao_opensles.c ALL: use new mp_thread abstraction 2023-11-05 17:36:17 +00:00
ao_oss.c ao_oss: add "spdif" passthrough support for high bitrate codecs (e.g. Dolby Atmos, DTS-HD, etc.) over HDMI 2023-08-20 20:02:40 +02:00
ao_pcm.c options: transition options from OPT_FLAG to OPT_BOOL 2023-02-21 17:15:17 +00:00
ao_pipewire.c ao_pipewire: add support for SPDIF formats 2024-02-15 16:43:25 +00:00
ao_pulse.c ALL: use new mp_thread abstraction 2023-11-05 17:36:17 +00:00
ao_sdl.c ao: convert all timing code to nanoseconds 2023-10-16 15:38:59 +00:00
ao_sndio.c ao_sndio: add missing config.h include 2024-02-07 14:44:52 +00:00
ao_wasapi_changenotify.c ao_wasapi_changenotify: use %ls instead of %S for wchar_t 2017-04-20 07:38:03 +02:00
ao_wasapi_utils.c various: use correct PATH_MAX for win32 2023-12-27 22:55:56 +01:00
ao_wasapi.c ao_wasapi: address premature buffer fills in exclusive mode 2024-02-24 05:26:56 +00:00
ao_wasapi.h ao_wasapi: address premature buffer fills in exclusive mode 2024-02-24 05:26:56 +00:00
ao.c ao: remove trailing NULL element from driver array 2023-01-16 19:25:54 +00:00
ao.h audio: drain ao before setting pause 2023-08-11 22:28:50 +00:00
buffer.c audio: rename ao_read_data_unlocked 2024-02-05 09:25:48 -08:00
internal.h audio: introduce ao_read_data_nonblocking() 2023-11-08 20:26:23 +01:00