Commit 9c803bc0 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

wasapi: factorize/check COM initialization

parent 39ee3d11
...@@ -46,6 +46,24 @@ vlc_module_begin() ...@@ -46,6 +46,24 @@ vlc_module_begin()
set_callbacks(Open, Close) set_callbacks(Open, Close)
vlc_module_end() vlc_module_end()
static int TryEnter(void)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
return -!!FAILED(hr);
}
static void Enter(void)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (unlikely(FAILED(hr)))
abort();
}
static void Leave(void)
{
CoUninitialize();
}
struct aout_sys_t struct aout_sys_t
{ {
IAudioClient *client; IAudioClient *client;
...@@ -65,7 +83,7 @@ static void Play(audio_output_t *aout, block_t *block) ...@@ -65,7 +83,7 @@ static void Play(audio_output_t *aout, block_t *block)
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
HRESULT hr; HRESULT hr;
CoInitializeEx(NULL, COINIT_MULTITHREADED); Enter();
if (likely(sys->clock != NULL)) if (likely(sys->clock != NULL))
{ {
UINT64 pos, qpcpos; UINT64 pos, qpcpos;
...@@ -121,7 +139,7 @@ static void Play(audio_output_t *aout, block_t *block) ...@@ -121,7 +139,7 @@ static void Play(audio_output_t *aout, block_t *block)
+ block->i_nb_samples * CLOCK_FREQ / aout->format.i_rate); + block->i_nb_samples * CLOCK_FREQ / aout->format.i_rate);
} }
CoUninitialize(); Leave();
block_Release(block); block_Release(block);
} }
...@@ -130,7 +148,7 @@ static void Pause(audio_output_t *aout, bool paused, mtime_t date) ...@@ -130,7 +148,7 @@ static void Pause(audio_output_t *aout, bool paused, mtime_t date)
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
HRESULT hr; HRESULT hr;
CoInitializeEx(NULL, COINIT_MULTITHREADED); Enter();
if (paused) if (paused)
hr = IAudioClient_Stop(sys->client); hr = IAudioClient_Stop(sys->client);
else else
...@@ -138,7 +156,7 @@ static void Pause(audio_output_t *aout, bool paused, mtime_t date) ...@@ -138,7 +156,7 @@ static void Pause(audio_output_t *aout, bool paused, mtime_t date)
if (FAILED(hr)) if (FAILED(hr))
msg_Warn(aout, "cannot %s stream (error 0x%lx)", msg_Warn(aout, "cannot %s stream (error 0x%lx)",
paused ? "stop" : "start", hr); paused ? "stop" : "start", hr);
CoUninitialize(); Leave();
(void) date; (void) date;
} }
...@@ -150,12 +168,12 @@ static void Flush(audio_output_t *aout, bool wait) ...@@ -150,12 +168,12 @@ static void Flush(audio_output_t *aout, bool wait)
if (wait) if (wait)
return; /* Not drain implemented */ return; /* Not drain implemented */
CoInitializeEx(NULL, COINIT_MULTITHREADED); Enter();
IAudioClient_Stop(sys->client); IAudioClient_Stop(sys->client);
hr = IAudioClient_Reset(sys->client); hr = IAudioClient_Reset(sys->client);
if (FAILED(hr)) if (FAILED(hr))
msg_Warn(aout, "cannot reset stream (error 0x%lx)", hr); msg_Warn(aout, "cannot reset stream (error 0x%lx)", hr);
CoUninitialize(); Leave();
} }
static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute) static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute)
...@@ -166,8 +184,8 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute) ...@@ -166,8 +184,8 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute)
if (vol > 1.) if (vol > 1.)
vol = 1.; vol = 1.;
Enter();
/* NOTE: better change volume while muted (if mute is toggled) */ /* NOTE: better change volume while muted (if mute is toggled) */
CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (mute) if (mute)
{ {
hr = ISimpleAudioVolume_SetMute(sys->volume.simple, true, NULL); hr = ISimpleAudioVolume_SetMute(sys->volume.simple, true, NULL);
...@@ -185,7 +203,7 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute) ...@@ -185,7 +203,7 @@ static int SimpleVolumeSet(audio_output_t *aout, float vol, bool mute)
if (FAILED(hr)) if (FAILED(hr))
msg_Warn(aout, "cannot unmute session (error 0x%lx)", hr); msg_Warn(aout, "cannot unmute session (error 0x%lx)", hr);
} }
CoUninitialize(); Leave();
return 0; return 0;
} }
...@@ -268,9 +286,7 @@ static void MTAThread(void *data) ...@@ -268,9 +286,7 @@ static void MTAThread(void *data)
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
HRESULT hr; HRESULT hr;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); Enter();
if (unlikely(FAILED(hr)))
abort();
hr = IAudioClient_GetService(sys->client, &IID_IAudioRenderClient, hr = IAudioClient_GetService(sys->client, &IID_IAudioRenderClient,
(void **)&sys->render); (void **)&sys->render);
...@@ -299,7 +315,7 @@ static void MTAThread(void *data) ...@@ -299,7 +315,7 @@ static void MTAThread(void *data)
IAudioClock_Release(sys->clock); IAudioClock_Release(sys->clock);
IAudioRenderClient_Release(sys->render); IAudioRenderClient_Release(sys->render);
fail: fail:
CoUninitialize(); Leave();
ReleaseSemaphore(sys->ready, 1, NULL); ReleaseSemaphore(sys->ready, 1, NULL);
} }
...@@ -323,8 +339,7 @@ static int Open(vlc_object_t *obj) ...@@ -323,8 +339,7 @@ static int Open(vlc_object_t *obj)
sys->done = NULL; sys->done = NULL;
aout->sys = sys; aout->sys = sys;
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (TryEnter())
if (FAILED(hr))
{ {
free(sys); free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -430,7 +445,7 @@ static int Open(vlc_object_t *obj) ...@@ -430,7 +445,7 @@ static int Open(vlc_object_t *obj)
aout->pf_flush = Flush; aout->pf_flush = Flush;
/*if (AOUT_FMT_LINEAR(&format) && !exclusive)*/ /*if (AOUT_FMT_LINEAR(&format) && !exclusive)*/
aout_VolumeHardInit(aout, SimpleVolumeSet, false); aout_VolumeHardInit(aout, SimpleVolumeSet, false);
CoUninitialize(); Leave();
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
if (sys->done != NULL) if (sys->done != NULL)
...@@ -439,7 +454,7 @@ error: ...@@ -439,7 +454,7 @@ error:
CloseHandle(sys->done); CloseHandle(sys->done);
if (sys->client != NULL) if (sys->client != NULL)
IAudioClient_Release(sys->client); IAudioClient_Release(sys->client);
CoUninitialize(); Leave();
free(sys); free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -449,12 +464,12 @@ static void Close (vlc_object_t *obj) ...@@ -449,12 +464,12 @@ static void Close (vlc_object_t *obj)
audio_output_t *aout = (audio_output_t *)obj; audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
CoInitializeEx(NULL, COINIT_MULTITHREADED); Enter();
ReleaseSemaphore(sys->done, 1, NULL); /* tell MTA thread to finish */ ReleaseSemaphore(sys->done, 1, NULL); /* tell MTA thread to finish */
WaitForSingleObject(sys->ready, INFINITE); /* wait for that ^ */ WaitForSingleObject(sys->ready, INFINITE); /* wait for that ^ */
IAudioClient_Stop(sys->client); /* should not be needed */ IAudioClient_Stop(sys->client); /* should not be needed */
IAudioClient_Release(sys->client); IAudioClient_Release(sys->client);
CoUninitialize(); Leave();
CloseHandle(sys->done); CloseHandle(sys->done);
CloseHandle(sys->ready); CloseHandle(sys->ready);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment