[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