aboutsummaryrefslogtreecommitdiffhomepage
path: root/audio/out/ao_wasapi.c
Commit message (Collapse)AuthorAge
* audio/out/pull: remove race conditionsGravatar wm42014-05-29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There were subtle and minor race conditions in the pull.c code, and AOs using it (jack, portaudio, sdl, wasapi). Attempt to remove these. There was at least a race condition in the ao_reset() implementation: mp_ring_reset() was called concurrently to the audio callback. While the ringbuffer uses atomics to allow concurrent access, the reset function wasn't concurrency-safe (and can't easily be made to). Fix this by stopping the audio callback before doing a reset. After that, we can do anything without needing synchronization. The callback is resumed when resuming playback at a later point. Don't call driver->pause, and make driver->resume and driver->reset start/stop the audio callback. In the initial state, the audio callback must be disabled. JackAudio of course is different. Maybe there is no way to suspend the audio callback without "disconnecting" it (what jack_deactivate() would do), so I'm not trying my luck, and implemented a really bad hack doing active waiting until we get the audio callback into a state where it won't interfere. Once the callback goes from AO_STATE_WAIT to NONE, we can be sure that the callback doesn't access the ringbuffer or anything else anymore. Since both sched_yield() and pthread_yield() apparently are not always available, use mp_sleep_us(1) to avoid burning CPU during active waiting. The ao_jack.c change also removes a race condition: apparently we didn't initialize _all_ ao fields before starting the audio callback. In ao_wasapi.c, I'm not sure whether reset really waits for the audio callback to return. Kovensky says it's not guaranteed, so disable the reset callback - for now the behavior of ao_wasapi.c is like with ao_jack.c, and active waiting is used to deal with the audio callback.
* atomics: switch to C11 stdatomic.hGravatar wm42014-05-21
| | | | | | | | | | | | | | | | | | | | | | | | | 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: Use the character set conversion functions from io.hGravatar Diogo Franco (Kovensky)2014-03-11
| | | | | ...rather than rolling out our own. The only possible advantage is that the "custom" ones didn't use talloc.
* ao_wasapi: Implement AOCONTROL_UPDATE_STREAM_TITLEGravatar Diogo Franco (Kovensky)2014-03-11
|
* ao_wasapi: Implement per-application mixingGravatar Diogo Franco (Kovensky)2014-03-11
| | | | | | | | | | | | | 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 threadGravatar Diogo Franco (Kovensky)2014-03-11
| | | | | | | | | | | | | | | 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 filesGravatar Diogo Franco (Kovensky)2014-03-11
| | | | | | 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.
* ao_wasapi: Initial conversion to the new pull modelGravatar Diogo Franco (Kovensky)2014-03-11
| | | | | | | | | Gets rid of the internal ring buffer and get_buffer. Corrects an implementation error in thread_reset. There is still a possible race condition on reset, and a few refactors left to do. If feasible, the thread that handles everything WASAPI-related will be made to only handle feed events.
* ao_wasapi: Use double math for QueryPerformanceCounter correctionGravatar Diogo Franco (Kovensky)2014-03-09
| | | | | | The uint64_t math would cause overflow at long enough system uptimes (...such as 3 days), and any precision error given by the double math will be under one milisecond.
* audio/out: make draining a separate operationGravatar wm42014-03-09
| | | | | | | | | | | | Until now, this was always conflated with uninit. This was ugly, and also many AOs emulated this manually (or just ignored it). Make draining an explicit operation, so AOs which support it can provide it, and for all others generic code will emulate it. For ao_wasapi, we keep it simple and basically disable the internal draining implementation (maybe it should be restored later). Tested on Linux only.
* audio/out: make ao struct opaqueGravatar wm42014-03-09
| | | | | | We want to move the AO to its own thread. There's no technical reason for making the ao struct opaque to do this. But it helps us sleep at night, because we can control access to shared state better.
* ao_wasapi: Slightly improve timer accuracyGravatar Diogo Franco (Kovensky)2014-03-06
| | | | | | | | | | | Use QueryPerformanceCounter to improve the accuracy of IAudioClock::GetPosition. While this is mainly for "realtime correctness" (usually the delay is a single sample or less), there are cases where IAudioClock::GetPosition takes a long time to return from its call (though the documentation doesn't define what a "long time" is), so correcting its value might be important in case the documented possible delay happens.
* ao_wasapi: Add device latency to get_delayGravatar Diogo Franco (Kovensky)2014-03-06
| | | | | | | | | | | The lack of device latency made get_delay report latencies shorter than they should; on systems with fast enough drivers, the delay is not perceptible, but high enough invisible delays would cause desyncs. I'm not yet completely sure whether this is 100% accurate, there are some issues involved when repeatedly pausing+unpausing (the delay might jump around by several dozen miliseconds), but seeking seems to be working correctly now.
* w32: use safe DLL search paths everywhereGravatar James Ross-Gowan2014-01-27
| | | | | | | | | | | | Windows applications that use LoadLibrary are vulnerable to DLL preloading attacks if a malicious DLL with the same name as a system DLL is placed in the current directory. mpv had some code to avoid this in ao_wasapi.c. This commit just moves it to main.c, since there's no reason it can't be used process-wide. This change can affect how plugins are loaded in AviSynth, but it shouldn't be a problem since MPC-HC also does this and it's a very popular AviSynth client.
* m_option: add mp_log callback to OPT_STRING_VALIDATE optionsGravatar wm42013-12-21
| | | | | And also convert a bunch of other code, especially ao_wasapi and ao_portaudio.
* ao_wasapi: mp_msg conversionsGravatar wm42013-12-21
| | | | | | | Remove the nonsensical print_lock too. Things that are called from the option validator are not converted yet, because the option parser doesn't provide a log context yet.
* ao_wasapi: fix includesGravatar wm42013-12-18
| | | | Broken due to recent header renaming. Untested.
* Split mpvcore/ into common/, misc/, bstr/Gravatar wm42013-12-17
|
* Move options/config related files from mpvcore/ to options/Gravatar wm42013-12-17
| | | | | | | | | Since m_option.h and options.h are extremely often included, a lot of files have to be changed. Moving path.c/h to options/ is a bit questionable, but since this is mainly about access to config files (which are also handled in options/), it's probably ok.
* ao_wasapi: Fix mistaken behavior on uninitGravatar Diogo Franco (Kovensky)2013-12-08
| | | | | The parameter, when true, tells whether uninit should block for flushing the buffers, not whether it should quit immediately without flushing.
* ao_wasapi: handle AOPLAY_FINAL_CHUNKGravatar Diogo Franco (Kovensky)2013-12-08
| | | | | Used for writing down all samples to the audio driver, even if it's not a full chunk; needed at EOF on weird files.
* ao_wasapi: Reduce the buffer size to a sane valueGravatar Diogo Franco (Kovensky)2013-12-08
| | | | | | | The previous RING_BUFFER_COUNT value, 64, would have ao_wasapi buffer 64 frames of audio in the ring buffer; a delay of 1280ms, which is clearly overkill for everything. A value of 8 buffers 8 frames for a total of 160ms.
* ao_wasapi: fix audio buffering delay calculationGravatar Diogo Franco (Kovensky)2013-12-08
| | | | | | | | When get_space was converted to returning samples instead of bytes, a unit type mismatch in get_delay's calculation returned bogus values. Fix by converting get_space's value back to bytes. Fixes playback with ao_wasapi when reaching EOF, or seeking past it.
* audio/out: prepare for non-interleaved audioGravatar wm42013-11-12
| | | | | | | | | | | | | | | | | | | This comes with two internal AO API changes: 1. ao_driver.play now can take non-interleaved audio. For this purpose, the data pointer is changed to void **data, where data[0] corresponds to the pointer in the old API. Also, the len argument as well as the return value are now in samples, not bytes. "Sample" in this context means the unit of the smallest possible audio frame, i.e. sample_size * channels. 2. ao_driver.get_space now returns samples instead of bytes. (Similar to the play function.) Change all AOs to use the new API. The AO API as exposed to the rest of the player still uses the old API. It's emulated in ao.c. This is purely to split the commits changing all AOs and the commits adding actual support for outputting N-I audio.
* audio/out: reject non-interleaved formatsGravatar wm42013-11-12
| | | | | | | | | | No AO can handle these, so it would be a problem if they get added later, and non-interleaved formats get accepted erroneously. Let them gracefully fall back to other formats. Most AOs actually would fall back, but to an unrelated formats. This is covered by this commit too, and if possible they should pick the interleaved variant if a non-interleaved format is requested.
* audio: replace af_fmt2str_short -> af_fmt_to_strGravatar wm42013-11-07
| | | | Also, remove all af_fmt2str usages.
* audio/out: remove useless info struct and redundant fieldsGravatar wm42013-10-23
|
* core: move contents to mpvcore (2/2)Gravatar Stefano Pigozzi2013-08-06
| | | | Followup commit. Fixes all the files references.
* Merge pull request #154 from rossy2401/wasapi-pauseGravatar Diogo Franco2013-08-05
|\ | | | | WASAPI stops working after pause
* | Fix some warningsGravatar Jonathan Yong2013-07-30
| |
| * ao_wasapi: don't check the audio feed while pausedGravatar James Ross-Gowan2013-07-27
|/
* audio/out: remove options argument from init()Gravatar wm42013-07-22
| | | | Same as with VOs in the previous commit.
* ao_wasapi: Fix S/PDIF passthrough initGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | | | | MSDN tells me to multiply the samplerates by 4 (for setting up the S/PDIF signal frequency), but doesn't mention that I'm only supposed to do it on the new, NT6.1+ IEC 61937 structs. Works on my Realtek Digital Output, but as I can't connect any hardware to it I can't hear the result. Also, always ask for little-endian AC3. I'm not sure if this is supposed to be LE or NE, but Windows is LE on all platforms, so we go with LE.
* ao_wasapi: Log the passthrough format in MSGL_VGravatar Diogo Franco (Kovensky)2013-07-22
|
* ao_wasapi: Also do passthrough for AF_FORMAT_MPEG2Gravatar Diogo Franco (Kovensky)2013-07-22
| | | | That's the sample format ad_spdif uses when the source is MP3.
* ao_wasapi: Support S/PDIF passthroughGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | Entirely untested as this troper has no S/PDIF hardware. Refuses trying any other format if we can't use passthrough, or we would end up sending white noise at the user.
* ao_wasapi: Fix double free on uninitGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | Caused by incorrect conversion to the m_option API: since we don't allocate the state ourselves, we also don't free it ourselves.
* ao_wasapi: Support loading devices by nameGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | | | Do an strstr match against the device description and, if we have only a single match, take it. This works as long as the devices in the system don't change, but it's not supposed to be reliable; if one wants reliability, one uses the device ID string. Formatting.
* ao_wasapi: Don't search for devices as part of validationGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | | | | | This could turn valid parameters into syntax errors by the mere presence or abscence of a device (e.g. USB audio devices), so don't do that. We do validate that, if the parameter is an integer, it is not negative. We also respond to the "help" parameter, which does the same as the "list" suboption but exits after listing. Demote the validation logging to MSGL_DBG2.
* ao_wasapi: Change function macros to require semicolon after invocationGravatar Diogo Franco (Kovensky)2013-07-22
| | | | Add semicolons where they were missing.
* ao_wasapi: Use OPT_STRING_VALIDATE for device suboptionGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | | | | | | | | | | | Validates by trying to pick the device using the device enumerator and aborting with out of range on failure. Refactors find_and_load_device to not use the wasapi_state; it might be called during validation. Adds missing CoInitialize/CoUninitialize calls. Remove unused variables (the SAFE_RELEASE macros keep them referenced so compiler warnings don't help finding them...). Remove the IMMDeviceEnumerator from the wasapi_state, it's only needed during initialization and initialization is now well factored enough to get rid of it. Try and connect to unplugged devices as well when using the device ID string.
* ao_wasapi: Fully convert to m_option APIGravatar Diogo Franco (Kovensky)2013-07-22
|
* ao_wasapi: Don't leak the default device's ID when listing devicesGravatar Diogo Franco (Kovensky)2013-07-22
| | | | Also remove unused variable.
* ao_wasapi: Annotate the default device when listing devicesGravatar Diogo Franco (Kovensky)2013-07-22
|
* ao_wasapi: Refactor device listing/loadingGravatar Diogo Franco (Kovensky)2013-07-22
| | | | | | | | | | | | Omit "{0.0.0.00000000}." on devices that start with that substring, re-add when searching for devices by ID. Log the device ID of the default device. Log the friendly name of the used device. Consistently refer to endpoints/devices as devices, as this is more consistent with mpv terminology.
* ao_wasapi0: Rename to ao_wasapiGravatar Diogo Franco (Kovensky)2013-07-22
Nobody knows what the 0 was for. There's no "WASAPI version 0". Just take it out.