[vlc-devel] [PATCH 5/5] wasapi: add an option to handle exclusive mode
Thomas Guillem
thomas at gllm.fr
Fri Oct 25 09:17:21 CEST 2019
On Thu, Oct 24, 2019, at 20:55, Rémi Denis-Courmont wrote:
> Le torstaina 24. lokakuuta 2019, 15.37.13 EEST Thomas Guillem a écrit :
> > cf. WASAPI_EXCLUSIVE_LONGTEXT
> > ---
> > modules/audio_output/wasapi.c | 174 +++++++++++++++++++++++++++++++++-
> > 1 file changed, 170 insertions(+), 4 deletions(-)
> >
> > diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
> > index daa946f8afc..91defb250fb 100644
> > --- a/modules/audio_output/wasapi.c
> > +++ b/modules/audio_output/wasapi.c
> > @@ -588,6 +588,154 @@ static void Stop(aout_stream_t *s)
> > free(sys);
> > }
> >
> > +/*
> > + * This function will try to find the closest PCM format that is accepted
> > by + * the sound card. Exclusive here means a direct access to the sound
> > card. The + * format arguments and the return code of this function behave
> > exactly like + * IAudioClient_IsFormatSupported().
> > + */
> > +static HRESULT GetExclusivePCMFormat(IAudioClient *c, const WAVEFORMATEX
> > *pwf, + WAVEFORMATEX **ppwf_closest) +{
> > + HRESULT hr;
> > + const AUDCLNT_SHAREMODE exclusive = AUDCLNT_SHAREMODE_EXCLUSIVE;
> > +
> > + *ppwf_closest = NULL;
> > +
> > + /* First try the input format */
> > + hr = IAudioClient_IsFormatSupported(c, exclusive, pwf, NULL);
> > +
> > + if (hr != AUDCLNT_E_UNSUPPORTED_FORMAT)
> > + {
> > + assert(hr != S_FALSE); /* S_FALSE reserved for shared mode */
> > + return hr;
> > + }
> > +
> > + /* This format come from vlc_ToWave() */
> > + assert(pwf->wFormatTag == WAVE_FORMAT_EXTENSIBLE);
> > + const WAVEFORMATEXTENSIBLE *pwfe = (void *) pwf;
> > + assert(IsEqualIID(&pwfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)
> > + || IsEqualIID(&pwfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM));
> > +
> > + /* Allocate the output closest format */
> > + WAVEFORMATEXTENSIBLE *pwfe_closest =
> > + CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
> > + if (!pwfe_closest)
> > + return E_FAIL;
> > + WAVEFORMATEX *pwf_closest = &pwfe_closest->Format;
> > +
> > + /* Setup the fallback arrays. There are 3 properties to check: the
> > format, + * the samplerate and the channels. There are maximum of 4
> > formats to + * check, 3 samplerates, and 2 channels configuration. So,
> > that is a + * maximum of 4x3x2=24 checks */
> > +
> > + /* The format fallback order is dependent of the input format. We don't
> > + * want to use a high quality format when it's not needed but we
> > prefer to + * use a high quality format instead of a lower one */
> > + static const uint16_t bits_pcm8_fallback[] = { 8, 16, 24, 32 };
> > + static const uint16_t bits_pcm16_fallback[] = { 16, 24, 32, 8 };
> > + static const uint16_t bits_pcm24_fallback[] = { 24, 32, 16, 8 };
> > + static const uint16_t bits_pcm32_fallback[] = { 32, 24, 16, 8 };
> > +
> > + static const size_t bits_fallback_size =
> > ARRAY_SIZE(bits_pcm8_fallback); +
> > + const uint16_t *bits_fallback;
> > + switch (pwf->wBitsPerSample)
> > + {
> > + case 64: /* fall through */
> > + case 32: bits_fallback = bits_pcm32_fallback; break;
> > + case 24: bits_fallback = bits_pcm24_fallback; break;
> > + case 16: bits_fallback = bits_pcm16_fallback; break;
> > + case 8: bits_fallback = bits_pcm8_fallback; break;
> > + default: vlc_assert_unreachable();
> > + }
> > +
> > + /* Check the input samplerate, then 48kHz and 44.1khz */
> > + const uint32_t samplerate_fallback[] = {
> > + pwf->nSamplesPerSec,
> > + pwf->nSamplesPerSec == 48000 ? 0 : 48000,
> > + pwf->nSamplesPerSec == 44100 ? 0 : 44100,
> > + };
> > + const size_t samplerate_fallback_size =
> > ARRAY_SIZE(samplerate_fallback); +
> > + /* Check the input number of channels, then stereo */
> > + const uint16_t channels_fallback[] = {
> > + pwf->nChannels,
> > + pwf->nChannels == 2 ? 0 : 2,
> > + };
> > + const size_t channels_fallback_size = ARRAY_SIZE(channels_fallback);
>
> Really the only point in exclusive mode is bit exact. If you need to convert,
> there is really no point, especially if the sample rate and/or the channel
> mappings differ. This is waaaaay needlessly complicated.
An other point of exclusive is to reduce the audio latency.
>
> --
> レミ・デニ-クールモン
> http://www.remlab.net/
>
>
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list