summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi_utils.c
diff options
context:
space:
mode:
authorKevin Mitchell <kevmitch@gmail.com>2016-02-26 06:58:09 -0800
committerKevin Mitchell <kevmitch@gmail.com>2016-02-26 15:43:51 -0800
commit84a3c21beb2f3360e4fda13179846406b4a24f7c (patch)
tree8c5e705a7d2adce3d521c88a51b6c104caee87c6 /audio/out/ao_wasapi_utils.c
parent31539884c829a0d2aec63d85647110282234a27a (diff)
downloadmpv-84a3c21beb2f3360e4fda13179846406b4a24f7c.tar.bz2
mpv-84a3c21beb2f3360e4fda13179846406b4a24f7c.tar.xz
ao_wasapi: replace laggy COM messaging with mp_dispatch_queue
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.
Diffstat (limited to 'audio/out/ao_wasapi_utils.c')
-rw-r--r--audio/out/ao_wasapi_utils.c93
1 files changed, 0 insertions, 93 deletions
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 7816517bb8..ce084731e4 100644
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -936,93 +936,6 @@ exit_label:
return deviceID;
}
-static void *unmarshal(struct wasapi_state *state, REFIID type, IStream **from)
-{
- if (!*from)
- return NULL;
- void *to_proxy = NULL;
- HRESULT hr = CoGetInterfaceAndReleaseStream(*from, type, &to_proxy);
- *from = NULL; // the stream is released even on failure
- EXIT_ON_ERROR(hr);
- return to_proxy;
-exit_label:
- MP_WARN(state, "Error reading COM proxy: %s\n", mp_HRESULT_to_str(hr));
- return to_proxy;
-}
-
-void wasapi_receive_proxies(struct wasapi_state *state) {
- state->pAudioVolumeProxy = unmarshal(state, &IID_ISimpleAudioVolume,
- &state->sAudioVolume);
- state->pEndpointVolumeProxy = unmarshal(state, &IID_IAudioEndpointVolume,
- &state->sEndpointVolume);
- state->pSessionControlProxy = unmarshal(state, &IID_IAudioSessionControl,
- &state->sSessionControl);
-}
-
-void wasapi_release_proxies(wasapi_state *state) {
- SAFE_RELEASE(state->pAudioVolumeProxy,
- ISimpleAudioVolume_Release(state->pAudioVolumeProxy));
- SAFE_RELEASE(state->pEndpointVolumeProxy,
- IAudioEndpointVolume_Release(state->pEndpointVolumeProxy));
- SAFE_RELEASE(state->pSessionControlProxy,
- IAudioSessionControl_Release(state->pSessionControlProxy));
-}
-
-// Must call CoReleaseMarshalData to decrement marshalled object's reference
-// count.
-#define SAFE_RELEASE_INTERFACE_STREAM(stream) do { \
- if ((stream) != NULL) { \
- CoReleaseMarshalData((stream)); \
- IStream_Release((stream)); \
- (stream) = NULL; \
- } \
- } while(0)
-
-static IStream *marshal(struct wasapi_state *state,
- REFIID type, void *from_obj)
-{
- if (!from_obj)
- return NULL;
- IStream *to;
- HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, &to);
- EXIT_ON_ERROR(hr);
- hr = CoMarshalInterThreadInterfaceInStream(type, (IUnknown *)from_obj, &to);
- EXIT_ON_ERROR(hr);
- return to;
-exit_label:
- SAFE_RELEASE_INTERFACE_STREAM(to);
- MP_WARN(state, "Error creating COM proxy stream: %s\n",
- mp_HRESULT_to_str(hr));
- return to;
-}
-
-static void create_proxy_streams(struct wasapi_state *state) {
- state->sAudioVolume = marshal(state, &IID_ISimpleAudioVolume,
- state->pAudioVolume);
- state->sEndpointVolume = marshal(state, &IID_IAudioEndpointVolume,
- state->pEndpointVolume);
- state->sSessionControl = marshal(state, &IID_IAudioSessionControl,
- state->pSessionControl);
-}
-
-static void destroy_proxy_streams(struct wasapi_state *state) {
- // This is only to handle error conditions.
- // During normal operation, these will already have been released by
- // unmarshaling.
- SAFE_RELEASE_INTERFACE_STREAM(state->sAudioVolume);
- SAFE_RELEASE_INTERFACE_STREAM(state->sEndpointVolume);
- SAFE_RELEASE_INTERFACE_STREAM(state->sSessionControl);
-}
-
-void wasapi_dispatch(struct ao *ao)
-{
- MP_DBG(ao, "Dispatch\n");
- // dispatch any possible pending messages
- MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- DispatchMessage(&msg);
-}
-
HRESULT wasapi_thread_init(struct ao *ao)
{
struct wasapi_state *state = ao->priv;
@@ -1057,9 +970,6 @@ retry: ;
}
EXIT_ON_ERROR(hr);
- MP_DBG(ao, "Creating proxies\n");
- create_proxy_streams(state);
-
MP_DBG(ao, "Init wasapi thread done\n");
return S_OK;
exit_label:
@@ -1071,13 +981,10 @@ void wasapi_thread_uninit(struct ao *ao)
{
struct wasapi_state *state = ao->priv;
MP_DBG(ao, "Thread shutdown\n");
- wasapi_dispatch(ao);
if (state->pAudioClient)
IAudioClient_Stop(state->pAudioClient);
- destroy_proxy_streams(state);
-
SAFE_RELEASE(state->pRenderClient, IAudioRenderClient_Release(state->pRenderClient));
SAFE_RELEASE(state->pAudioClock, IAudioClock_Release(state->pAudioClock));
SAFE_RELEASE(state->pAudioVolume, ISimpleAudioVolume_Release(state->pAudioVolume));