From dcf38e01905c40c9fd6dd603320395e808472a04 Mon Sep 17 00:00:00 2001 From: "Diogo Franco (Kovensky)" Date: Sun, 21 Jul 2013 13:11:44 -0300 Subject: ao_wasapi: Support S/PDIF passthrough 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. --- audio/out/ao_wasapi.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'audio') diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c index 03a7c767a1..38d1637fb4 100644 --- a/audio/out/ao_wasapi.c +++ b/audio/out/ao_wasapi.c @@ -392,10 +392,55 @@ exit_label: return ret; } +static int try_passthrough(struct wasapi_state *state, + struct ao *const ao) +{ + WAVEFORMATEXTENSIBLE wformat = { + .Format = { + .wFormatTag = WAVE_FORMAT_EXTENSIBLE, + .nChannels = ao->channels.num, + .nSamplesPerSec = ao->samplerate * 4, + .nAvgBytesPerSec = (ao->samplerate * 4) * (ao->channels.num * 2), + .nBlockAlign = ao->channels.num * 2, + .wBitsPerSample = 16, + .cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX), + }, + .Samples.wValidBitsPerSample = 16, + .dwChannelMask = mp_chmap_to_waveext(&ao->channels), + .SubFormat = local_KSDATAFORMAT_SUBTYPE_PCM, + }; + wformat.SubFormat.Data1 = WAVE_FORMAT_DOLBY_AC3_SPDIF; // see INIT_WAVEFORMATEX_GUID macro + + union WAVEFMT u; + u.extensible = &wformat; + + HRESULT hr = IAudioClient_IsFormatSupported(state->pAudioClient, + state->share_mode, + u.ex, NULL); + if (!FAILED(hr)) { + state->format = wformat; + return 1; + } + return 0; +} + static int find_formats(struct ao *const ao) { struct wasapi_state *state = (struct wasapi_state *)ao->priv; + if (AF_FORMAT_IS_IEC61937(ao->format)) { + if (try_passthrough(state, ao)) + return 0; + + EnterCriticalSection(&state->print_lock); + mp_msg(MSGT_AO, MSGL_ERR, "ao-wasapi: couldn't use passthrough!"); + if (!state->opt_exclusive) + mp_msg(MSGT_AO, MSGL_ERR, " (try exclusive mode)"); + mp_msg(MSGT_AO, MSGL_ERR, "\n"); + LeaveCriticalSection(&state->print_lock); + return -1; + } + /* See if the format works as-is */ int bits = af_fmt2bits(ao->format); /* don't try 8bits -- there are various 8bit modes other than PCM (*-law et al); -- cgit v1.2.3