summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi.h
Commit message (Collapse)AuthorAgeFilesLines
* ao_wasapi: fix player core lockup when avoiding premature buffer fillsnanahi8 days1-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 6863eefc3d1d683a08f56aeaca0b4706672f2447 handled this situation by using an atomic variable to express the state for which the wakeup is caused by AO control, and the dispatch queue is only processed at this state. However, this can cause permanent lockup of the player core when the following happens: - AO control sets the thread state to WASAPI_THREAD_DISPATCH, and sets the wakeup handle. - WASAPI thread reads the WASAPI_THREAD_DISPATCH state and processes the dispatch queue. - Another AO control happens. A dispatch item is enqueued, and the state stays at WASAPI_THREAD_DISPATCH. - WASAPI thread resets the thread state to WASAPI_THREAD_FEED since the state has not changed. - WaitForSingleObject() returns in the WASAPI thread, sees this state, and does not process the dispatch queue. - The player core locks permanently because it is waiting for the dispatch to be processed. This has been experimentally verified on a system under high contention: The easiest way to trigger this lockup is to continuously hold down "i", which rapidly issues AO get volume/mute controls. To properly handle this, use separate handles for system and user wakeup requests. Only feed audio when woke up by system and only process the dispatch queue when woke up by user. Fixes: 6863eefc3d1d683a08f56aeaca0b4706672f2447
* Revert "ao_wasapi: address premature buffer fills in exclusive mode"nanahi8 days1-1/+0
| | | | This reverts commit 6863eefc3d1d683a08f56aeaca0b4706672f2447.
* ao_wasapi: add `--wasapi-exclusive-buffer` optionsunpenghao2024-04-191-0/+1
| | | | | | | | | | | This allows users to set buffer duration in exclusive mode. We have been using the default device period as the buffer size and it is robust enough in most cases. However, on some devices there are horrible glitches after a stream reset. Unfortunately, the issue is not consistently reproducible, but using a smaller buffer size (e.g., the minimum device period) seems to resolve the problem. Fixes #13715.
* ao_wasapi: support set_pauseMisaki Kasumi2024-04-031-1/+3
|
* ao_wasapi: address premature buffer fills in exclusive modesunpenghao2024-02-241-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* various: sort some standard headersNRK2023-10-201-1/+2
| | | | | | | | | | | | since i was going to fix the include order of stdatomic, might as well sort the surrouding includes in accordance with the project's coding style. some headers can sometime require specific include order. standard library headers usually don't. but mpv might "hack into" the standard headers (e.g pthreads) so that complicates things a bit more. hopefully nothing breaks. if it does, the style guide is to blame.
* osdep: remove atomic.hNRK2023-10-201-1/+1
| | | | | | | replace it with <stdatomic.h> and replace the mp_atomic_* typedefs with explicit _Atomic qualified types. also add missing config.h includes on some files.
* ao_wasapi: reorganize wasapi.hKevin Mitchell2017-08-071-12/+4
| | | | | Remove dead declarations. Move macro only used in wasapi_utils.c closer to use. Rearrange declaration order.
* ao_wasapi: return bool instead of HRESULT from thread_initKevin Mitchell2017-08-071-2/+2
| | | | | | | | Any bad HRESULTs should have been printed already and lots of failure modes don't have an HRESULT leading to awkward hr = E_FAIL business. This also checks the exit status of GetBufferSize in the align hack. A final fatal message is added if either of the retry hacks fail.
* ao_wasapi: drop use of AF_FORMAT_S24wm42017-07-071-0/+1
| | | | | | | | | | | Do conversion directly, using the infrastructure that was added before. This also rewrites part of format negotation, I guess. I couldn't test the format that was used for S24 - my hardware does not report support for it. So I commented it, as it could be buggy. Testing this with the wasapi_formats[] entry for 24/24 uncommented would be appreciated.
* win32: add COM-specific SAFE_RELEASE to windows_utils.hJames Ross-Gowan2017-01-301-1/+1
| | | | | | | | | | | | | | | See: https://msdn.microsoft.com/en-us/library/windows/desktop/dd743946.aspx Microsoft example code often uses a SAFE_RELEASE macro like the one in the above link. This makes it easier to avoid errors when releasing COM interfaces. It also reduces noise in COM-heavy code. ao_wasapi.h also had a macro called SAFE_RELEASE, though unlike the version above, its SAFE_RELEASE macro accepted a second parameter which allowed it to destroy arbitrary objects other than just COM interfaces. This renames ao_wasapi's SAFE_RELEASE to SAFE_DESTROY, which should more accurately reflect what it does and prevent confusion with the Microsoft version.
* ao_wasapi: log return code when probing audio formatswm42016-11-301-0/+4
| | | | | | | | | We log a large number of formats, but we rarely log the result of the probing. Change this. The logic in try_format_exclusive() changes slightly, but should be equivalent. EXIT_ON_ERROR() checks for FAILED(), which should be exclusive to SUCCEEDED().
* options: remove deprecated sub-option handling for --vo and --aowm42016-11-251-2/+0
| | | | | | | | Long planned. Leads to some sanity. There still are some rather gross things. Especially g_groups is ugly, and a hack that can hopefully be removed. (There is a plan for it, but whether it's implemented depends on how much energy is left.)
* osdep: rename atomics.h to atomic.hwm42016-09-071-1/+1
| | | | | The standard header is stdatomic.h, so the extra "s" freaks me out every time I look at it.
* ao_wasapi: replace laggy COM messaging with mp_dispatch_queueKevin Mitchell2016-02-261-14/+2
| | | | | | | | | | A COM message loop is apparently totally inappropriate for a low latency thread. It leads to audio glitches because the thread doesn't wake up fast enough when it should. It also causes mysterious correlations between the vo and ao thread (i.e., toggling fullscreen delays audio feed events). Instead use an mp_dispatch_queue to set/get volume/mute/session display name from the audio thread. This has the added benefit of obviating the need to marshal the associated interfaces from the audio thread.
* ao_wasapi: add "wasapi" prefix to non-static find_deviceID functionKevin Mitchell2016-01-281-1/+1
|
* ao_wasapi: correct check for specified device on default changeKevin Mitchell2016-01-281-0/+1
| | | | | | Correctly avoid a reload if the current device was specified by the user through --audio-device. Previously, we only recognized if the user had specified --ao=wasapi:device=.
* Relicense some non-MPlayer source files to LGPL 2.1 or laterwm42016-01-191-7/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This covers source files which were added in mplayer2 and mpv times only, and where all code is covered by LGPL relicensing agreements. There are probably more files to which this applies, but I'm being conservative here. A file named ao_sdl.c exists in MPlayer too, but the mpv one is a complete rewrite, and was added some time after the original ao_sdl.c was removed. The same applies to vo_sdl.c, for which the SDL2 API is radically different in addition (MPlayer supports SDL 1.2 only). common.c contains only code written by me. But common.h is a strange case: although it originally was named mp_common.h and exists in MPlayer too, by now it contains only definitions written by uau and me. The exceptions are the CONTROL_ defines - thus not changing the license of common.h yet. codec_tags.c contained once large tables generated from MPlayer's codecs.conf, but all of these tables were removed. From demux_playlist.c I'm removing a code fragment from someone who was not asked; this probably could be done later (see commit 15dccc37). misc.c is a bit complicated to reason about (it was split off mplayer.c and thus contains random functions out of this file), but actually all functions have been added post-MPlayer. Except get_relative_time(), which was written by uau, but looks similar to 3 different versions of something similar in each of the Unix/win32/OSX timer source files. I'm not sure what that means in regards to copyright, so I've just moved it into another still-GPL source file for now. screenshot.c once had some minor parts of MPlayer's vf_screenshot.c, but they're all gone.
* ao_wasapi: move out some utility functionswm42016-01-111-5/+1
| | | | | | Note that hresult_to_str() (coming from wasapi_explain_err()) is mostly wasapi-specific, but since HRESULT error codes are unique, it can be extended for any other use.
* ao_wasapi: remove unnecessary header fileKevin Mitchell2016-01-051-2/+25
| | | | | All the wasapi files were including both ao_wasapi.h and ao_wasapi_utils.h. Just merge them into a single file.
* ao_wasapi: remove +x flag from fileswm42016-01-041-0/+0
|
* ao_wasapi: make persistent enumerator local to change_notifyKevin Mitchell2016-01-041-1/+1
| | | | This is no longer required by anything else
* ao_wasapi: rewrite device listing and selectionKevin Mitchell2016-01-041-0/+2
| | | | | | | | | | | | | Unify and clean up listing and selection. Use common enumerator code for both operations to avoid duplication or inconsistencies. Maintain, but significatnly simplify manual device selection by id, name or number. This actually fixes loading by name which didn't really work before since the "name" displayed by --audio-device=help differed from that used to match the selection, which used the device "description" instead. Save the selected deviceID in the private structure for later loading. This will permit moving the device selection into the main thread in a future commit.
* ao_wasapi: wrap long lines and use only c99 comment styleKevin Mitchell2015-12-211-2/+2
| | | | | also remove a log message in AOCONTROL_UPDATE_STREAM_TITLE since none of the other controls have one.
* ao_wasapi: reorganize private structureKevin Mitchell2015-12-211-37/+36
|
* ao_wasapi: remove useless buffer_block_sizeKevin Mitchell2015-12-211-1/+0
| | | | this was only ever used for a verbose message
* ao_wasapi: remove volume "restore" on exitKevin Mitchell2015-12-201-3/+0
| | | | | | It was complicated and not even very intuitive to the user. If you are controlling the master volume, you just have to be prepared to deal with the consequences.
* ao_wasapi: get rid of Vistablob hackKevin Mitchell2015-11-241-11/+0
| | | | | This was required to work around XP linking issues and is no longer required.
* ao/wasapi: use atomic state variable instead of different eventsKevin Mitchell2015-04-041-6/+11
| | | | | | | | | Unfortunately, because we have proxy objects (pAudioVolumeProxy, pEndpointVolumeProxy, pSessionControlProxy) it looks like we still have to use MsgWaitForMultipleObjects and watch for and dispatch pending messages: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680112%28v=vs.85%29.aspx
* ao/wasapi: reorder priv membersKevin Mitchell2015-04-041-12/+14
|
* ao/wasapi: add ao hotplugKevin Mitchell2015-03-311-1/+3
| | | | | | | Create a second copy of the change_notify structure for the hotplug ao. change_notify->is_hotplug distinguishes the hotplug version from the regular one monitoring the currently playing ao. Also make the change notification less verbose now that there might be two of them around.
* ao/wasapi: move resume to audio threadKevin Mitchell2015-02-231-4/+1
| | | | | | | | | | | | | | This echanges the two events hForceFeed/hFeedDone for hResume. This like the last commit makes things more deterministic. Importantly, the forcefeed is only done if there is not already a full buffer yet to be played by the device. This should fix some of the problems with exclusive mode. This commit also removes the necessity to have a proxy to the AudioClient object in the main thread. fixes #1529
* ao_wasapi: move reset into audio threadKevin Mitchell2015-02-231-0/+1
| | | | | | | | | This makes things a bit more deterministic. It ensures that the audio thread isn't doing anything between IAudioClient_Stop(), IAudioClient_Reset() and setting the sample_count to 0. Buffer overfilling on resume is still a problem in exclusive mode (see next commit).
* win32: request UTF-16 API variants, Vista+ APIs, and COM C macroswm42015-01-071-3/+0
| | | | | Put the Vista+ (_WIN32_WINNT) and the COM C (COBJMACROS) defines into the build system, instead of defining them over and over in the code.
* ao/wasapi: handle VistaBlob failure more gracefullyKevin Mitchell2014-11-281-1/+4
|
* ao/wasapi: increase buffer size to 50 msKevin Mitchell2014-11-181-4/+0
| | | | | Before it was the default device period, which was too small causing glitches on on entering/exiting fullscreen.
* ao/wasapi: request reset on appropriate eventsKevin Mitchell2014-11-171-3/+13
| | | | | | | | on changes to PKEY_AudioEngine_DeviceFormat, device status, and default device. call ao_reload directly in the change_notify "methods". this requires keeping a device enumerator around for the duration of execution, rather than just for initially querying devices
* ao/wasapi: new wasapi device monitoring interfaceJonathan Yong2014-11-171-0/+8
| | | | | | | | | | | Implement skeleton IMMNotificationClient to watch for changes in the sound device. This will make recovery possible from changes shared mode sample rate, bit depth, "enhancements"/effects and even graceful device removal. http://msdn.microsoft.com/en-us/library/windows/desktop/dd371417%28v=vs.85%29.aspx Signed-off-by: Kevin Mitchell <kevmitch@gmail.com>
* ao/wasapi: improve error messages and add more debug statementsKevin Mitchell2014-11-171-1/+1
| | | | | | also enforce more consistency in the exit codes and error handling thanks to Jonathan Yong <10walls@gmail.com>
* Move compat/ and bstr/ directory contents somewhere elsewm42014-08-291-1/+1
| | | | | | | | | bstr.c doesn't really deserve its own directory, and compat had just a few files, most of which may as well be in osdep. There isn't really any justification for these extra directories, so get rid of them. The compat/libav.h was empty - just delete it. We changed our approach to API compatibility, and will likely not need it anymore.
* atomics: switch to C11 stdatomic.hwm42014-05-211-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | In my opinion, we shouldn't use atomics at all, but ok. This switches the mpv code to use C11 stdatomic.h, and for compilers that don't support stdatomic.h yet, we emulate the subset used by mpv using the builtins commonly provided by gcc and clang. This supersedes an earlier similar attempt by Kovensky. That attempt unfortunately relied on a big copypasted freebsd header (which also depended on much more highly compiler-specific functionality, defined reserved symbols, etc.), so it had to be NIH'ed. Some issues: - C11 says default initialization of atomics "produces a valid state", but it's not sure whether the stored value is really 0. But we rely on this. - I'm pretty sure our use of the __atomic... builtins is/was incorrect. We don't use atomic load/store intrinsics, and access stuff directly. - Our wrapper actually does stricter typechecking than the stdatomic.h implementation by gcc 4.9. We make the atomic types incompatible with normal types by wrapping them into structs. (The FreeBSD wrapper does the same.) - I couldn't test on MinGW.
* ao_wasapi: Implement AOCONTROL_UPDATE_STREAM_TITLEDiogo Franco (Kovensky)2014-03-111-0/+4
|
* ao_wasapi: Implement per-application mixingDiogo Franco (Kovensky)2014-03-111-0/+5
| | | | | | | | | | | | | The volume controls in mpv now affect the session's volume (the application's volume in the mixer). Since we do not request a non-persistent session, the volume and mute status persist across mpv invocations and system reboots. In exclusive mode, WASAPI doesn't have access to a mixer so the endpoint (sound card)'s master volume is modified instead. Since by definition mpv is the only thing outputting audio in exclusive mode, this causes no conflict, and ao_wasapi restores the last user-set volume when it's uninitialized.
* ao_wasapi: Move non-critical code outside of the event threadDiogo Franco (Kovensky)2014-03-111-15/+14
| | | | | | | | | | | | | | | Due to the COM Single-Threaded Apartment model, the thread owning the objects will still do all the actual method calls (in the form of message dispatches), but at least this will be COM's problem rather than having to set up several handles and adding extra code to the event thread. Since the event thread still needs to own the WASAPI handles to avoid waiting on another thread to dispatch the messages, the init and uninit code still has to run in the thread. This also removes a broken drain implementation and removes unused headers from each of the files split from the original ao_wasapi.c.
* ao_wasapi: Split into 2 filesDiogo Franco (Kovensky)2014-03-111-0/+95
ao_wasapi.c was almost entirely init code mixed with option code and occasionally actual audio handling code. Split most things to ao_wasapi_utils.c and keep the audio handling code in ao_wasapi.c.