X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faudio_output%2Fwasapi.c;h=6d715f59e903b111d4483d0a5509910fcdb2e788;hb=f503b668bc9b683dd36b2342b81ca8bff98ef790;hp=d8e9f2633f1d057cf6109adc7f31c55069352c1f;hpb=771335afa2a349662533c93048ce21b627d4057e;p=vlc diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c index d8e9f2633f..6d715f59e9 100644 --- a/modules/audio_output/wasapi.c +++ b/modules/audio_output/wasapi.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -65,42 +64,29 @@ static UINT64 GetQPC(void) return (d.quot * 10000000) + ((d.rem * 10000000) / freq.QuadPart); } -static void Enter(void) -{ - HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (unlikely(FAILED(hr))) - abort(); -} - -static void Leave(void) -{ - CoUninitialize(); -} - -typedef struct aout_api_sys +typedef struct aout_stream_sys { IAudioClient *client; uint8_t chans_table[AOUT_CHAN_MAX]; uint8_t chans_to_reorder; - uint8_t bits; /**< Bits per sample */ + vlc_fourcc_t format; /**< Sample format */ unsigned rate; /**< Sample rate */ unsigned bytes_per_frame; UINT32 written; /**< Frames written to the buffer */ UINT32 frames; /**< Total buffer size (frames) */ -} aout_api_sys_t; +} aout_stream_sys_t; /*** VLC audio output callbacks ***/ -static HRESULT TimeGet(aout_api_t *api, mtime_t *restrict delay) +static HRESULT TimeGet(aout_stream_t *s, mtime_t *restrict delay) { - aout_api_sys_t *sys = api->sys; + aout_stream_sys_t *sys = s->sys; void *pv; UINT64 pos, qpcpos; HRESULT hr; - Enter(); hr = IAudioClient_GetService(sys->client, &IID_IAudioClock, &pv); if (SUCCEEDED(hr)) { @@ -108,12 +94,11 @@ static HRESULT TimeGet(aout_api_t *api, mtime_t *restrict delay) hr = IAudioClock_GetPosition(clock, &pos, &qpcpos); if (FAILED(hr)) - msg_Err(api, "cannot get position (error 0x%lx)", hr); + msg_Err(s, "cannot get position (error 0x%lx)", hr); IAudioClock_Release(clock); } else - msg_Err(api, "cannot get clock (error 0x%lx)", hr); - Leave(); + msg_Err(s, "cannot get clock (error 0x%lx)", hr); if (SUCCEEDED(hr)) { @@ -126,27 +111,26 @@ static HRESULT TimeGet(aout_api_t *api, mtime_t *restrict delay) else { *delay = sys->written * CLOCK_FREQ / sys->rate; - msg_Dbg(api, "extrapolating position: still propagating buffers"); + msg_Dbg(s, "extrapolating position: still propagating buffers"); } } return hr; } -static HRESULT Play(aout_api_t *api, block_t *block) +static HRESULT Play(aout_stream_t *s, block_t *block) { - aout_api_sys_t *sys = api->sys; + aout_stream_sys_t *sys = s->sys; void *pv; HRESULT hr; if (sys->chans_to_reorder) aout_ChannelReorder(block->p_buffer, block->i_buffer, - sys->chans_to_reorder, sys->chans_table, sys->bits); + sys->chans_to_reorder, sys->chans_table, sys->format); - Enter(); hr = IAudioClient_GetService(sys->client, &IID_IAudioRenderClient, &pv); if (FAILED(hr)) { - msg_Err(api, "cannot get render client (error 0x%lx)", hr); + msg_Err(s, "cannot get render client (error 0x%lx)", hr); goto out; } @@ -157,7 +141,7 @@ static HRESULT Play(aout_api_t *api, block_t *block) hr = IAudioClient_GetCurrentPadding(sys->client, &frames); if (FAILED(hr)) { - msg_Err(api, "cannot get current padding (error 0x%lx)", hr); + msg_Err(s, "cannot get current padding (error 0x%lx)", hr); break; } @@ -170,7 +154,7 @@ static HRESULT Play(aout_api_t *api, block_t *block) hr = IAudioRenderClient_GetBuffer(render, frames, &dst); if (FAILED(hr)) { - msg_Err(api, "cannot get buffer (error 0x%lx)", hr); + msg_Err(s, "cannot get buffer (error 0x%lx)", hr); break; } @@ -180,7 +164,7 @@ static HRESULT Play(aout_api_t *api, block_t *block) hr = IAudioRenderClient_ReleaseBuffer(render, frames, 0); if (FAILED(hr)) { - msg_Err(api, "cannot release buffer (error 0x%lx)", hr); + msg_Err(s, "cannot release buffer (error 0x%lx)", hr); break; } IAudioClient_Start(sys->client); @@ -198,41 +182,36 @@ static HRESULT Play(aout_api_t *api, block_t *block) } IAudioRenderClient_Release(render); out: - Leave(); block_Release(block); return hr; } -static HRESULT Pause(aout_api_t *api, bool paused) +static HRESULT Pause(aout_stream_t *s, bool paused) { - aout_api_sys_t *sys = api->sys; + aout_stream_sys_t *sys = s->sys; HRESULT hr; - Enter(); if (paused) hr = IAudioClient_Stop(sys->client); else hr = IAudioClient_Start(sys->client); if (FAILED(hr)) - msg_Warn(api, "cannot %s stream (error 0x%lx)", + msg_Warn(s, "cannot %s stream (error 0x%lx)", paused ? "stop" : "start", hr); - Leave(); return hr; } -static HRESULT Flush(aout_api_t *api) +static HRESULT Flush(aout_stream_t *s) { - aout_api_sys_t *sys = api->sys; + aout_stream_sys_t *sys = s->sys; HRESULT hr; - Enter(); IAudioClient_Stop(sys->client); - hr = IAudioClient_Reset(sys->client); - Leave(); + hr = IAudioClient_Reset(sys->client); if (FAILED(hr)) - msg_Warn(api, "cannot reset stream (error 0x%lx)", hr); + msg_Warn(s, "cannot reset stream (error 0x%lx)", hr); else sys->written = 0; return hr; @@ -264,7 +243,6 @@ static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf, wf->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; break; - case VLC_CODEC_S8: case VLC_CODEC_U8: audio->i_format = VLC_CODEC_S16N; case VLC_CODEC_S16N: @@ -331,22 +309,19 @@ static unsigned vlc_CheckWaveOrder (const WAVEFORMATEX *restrict wf, return aout_CheckChannelReorder(chans_in, chans_out, mask, table); } -static HRESULT Start(aout_api_t *api, audio_sample_format_t *restrict fmt, - IMMDevice *dev, const GUID *sid) +static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict fmt, + const GUID *sid) { - aout_api_sys_t *sys = malloc(sizeof (*sys)); + aout_stream_sys_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) return E_OUTOFMEMORY; sys->client = NULL; - HRESULT hr; - - Enter(); void *pv; - hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_ALL, NULL, &pv); + HRESULT hr = aout_stream_Activate(s, &IID_IAudioClient, NULL, &pv); if (FAILED(hr)) { - msg_Err(api, "cannot activate client (error 0x%lx)", hr); + msg_Err(s, "cannot activate client (error 0x%lx)", hr); goto error; } sys->client = pv; @@ -360,7 +335,7 @@ static HRESULT Start(aout_api_t *api, audio_sample_format_t *restrict fmt, &wf.Format, &pwf); if (FAILED(hr)) { - msg_Err(api, "cannot negotiate audio format (error 0x%lx)", hr); + msg_Err(s, "cannot negotiate audio format (error 0x%lx)", hr); goto error; } @@ -370,18 +345,18 @@ static HRESULT Start(aout_api_t *api, audio_sample_format_t *restrict fmt, if (vlc_FromWave(pwf, fmt)) { CoTaskMemFree(pwf); - msg_Err(api, "unsupported audio format"); + msg_Err(s, "unsupported audio format"); hr = E_INVALIDARG; goto error; } - msg_Dbg(api, "modified format"); + msg_Dbg(s, "modified format"); } else assert(pwf == NULL); sys->chans_to_reorder = vlc_CheckWaveOrder((hr == S_OK) ? &wf.Format : pwf, sys->chans_table); - sys->bits = fmt->i_bitspersample; + sys->format = fmt->i_format; hr = IAudioClient_Initialize(sys->client, AUDCLNT_SHAREMODE_SHARED, 0, AOUT_MAX_PREPARE_TIME * 10, 0, @@ -389,64 +364,48 @@ static HRESULT Start(aout_api_t *api, audio_sample_format_t *restrict fmt, CoTaskMemFree(pwf); if (FAILED(hr)) { - msg_Err(api, "cannot initialize audio client (error 0x%lx)", hr); + msg_Err(s, "cannot initialize audio client (error 0x%lx)", hr); goto error; } hr = IAudioClient_GetBufferSize(sys->client, &sys->frames); if (FAILED(hr)) { - msg_Err(api, "cannot get buffer size (error 0x%lx)", hr); + msg_Err(s, "cannot get buffer size (error 0x%lx)", hr); goto error; } - Leave(); - sys->rate = fmt->i_rate; sys->bytes_per_frame = fmt->i_bytes_per_frame; sys->written = 0; - api->sys = sys; - api->time_get = TimeGet; - api->play = Play; - api->pause = Pause; - api->flush = Flush; - return VLC_SUCCESS; + s->sys = sys; + s->time_get = TimeGet; + s->play = Play; + s->pause = Pause; + s->flush = Flush; + return S_OK; error: if (sys->client != NULL) IAudioClient_Release(sys->client); - Leave(); + free(sys); return hr; } -static void Stop(aout_api_t *api) +static void Stop(aout_stream_t *s) { - aout_api_sys_t *sys = api->sys; + aout_stream_sys_t *sys = s->sys; - Enter(); IAudioClient_Stop(sys->client); /* should not be needed */ IAudioClient_Release(sys->client); - Leave(); } -#undef aout_api_Start -aout_api_t *aout_api_Start(vlc_object_t *parent, audio_sample_format_t *fmt, - IMMDevice *dev, const GUID *sid) +HRESULT aout_stream_Start(aout_stream_t *s, + audio_sample_format_t *restrict fmt, const GUID *sid) { - aout_api_t *api = vlc_object_create(parent, sizeof (*api)); - if (unlikely(api == NULL)) - return NULL; - - HRESULT hr = Start(api, fmt, dev, sid); - if (FAILED(hr)) - { - vlc_object_release(api); - api = NULL; - } - return NULL; + return Start(s, fmt, sid); } -void aout_api_Stop(aout_api_t *api) +void aout_stream_Stop(aout_stream_t *s) { - Stop(api); - vlc_object_release(api); + Stop(s); }