[vlc-devel] [PATCH 5/5] wasapi: add an option to handle exclusive mode

Rémi Denis-Courmont remi at remlab.net
Thu Oct 24 20:55:20 CEST 2019


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.

-- 
レミ・デニ-クールモン
http://www.remlab.net/





More information about the vlc-devel mailing list