[vlc-devel] [PATCH] wasapi: implement pass-through

Thomas Guillem thomas at gllm.fr
Mon May 2 16:14:28 CEST 2016


I made a last minute change, and didn't saw that it failed because of
the fall-back to directound...

Here is the good version:

#include <vlc_plugin.h>
#include "audio_output/mmdevice.h"

+DEFINE_GUID( _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF,
WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71 );
+static const GUID __KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF =
{WAVE_FORMAT_DOLBY_AC3_SPDIF, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa,
0x00, 0x38, 0x9b, 0x71}};
+

On Mon, May 2, 2016, at 15:51, Thomas Guillem wrote:
> Inspired by the directsound module
> ---
>  modules/audio_output/wasapi.c | 50
>  ++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 42 insertions(+), 8 deletions(-)
> 
> diff --git a/modules/audio_output/wasapi.c
> b/modules/audio_output/wasapi.c
> index 2a588e2..fed602a 100644
> --- a/modules/audio_output/wasapi.c
> +++ b/modules/audio_output/wasapi.c
> @@ -69,6 +69,7 @@ typedef struct aout_stream_sys
>      vlc_fourcc_t format; /**< Sample format */
>      unsigned rate; /**< Sample rate */
>      unsigned bytes_per_frame;
> +    unsigned frame_length;
>      UINT64 written; /**< Frames written to the buffer */
>      UINT32 frames; /**< Total buffer size (frames) */
>  } aout_stream_sys_t;
> @@ -155,7 +156,7 @@ static HRESULT Play(aout_stream_t *s, block_t *block)
>              break;
>          }
>  
> -        const size_t copy = frames * sys->bytes_per_frame;
> +        const size_t copy = frames * sys->bytes_per_frame /
> sys->frame_length;
>  
>          memcpy(dst, block->p_buffer, copy);
>          hr = IAudioRenderClient_ReleaseBuffer(render, frames, 0);
> @@ -231,6 +232,30 @@ static const uint32_t chans_in[] = {
>      SPEAKER_FRONT_CENTER, SPEAKER_LOW_FREQUENCY, 0
>  };
>  
> +static void vlc_SpdifToWave(WAVEFORMATEXTENSIBLE *restrict wf,
> +                            audio_sample_format_t *restrict audio)
> +{
> +    audio->i_format = VLC_CODEC_SPDIFL;
> +    aout_FormatPrepare (audio);
> +    audio->i_bytes_per_frame = AOUT_SPDIF_SIZE;
> +    audio->i_frame_length = A52_FRAME_NB;
> +
> +    /* Similar to KSDATAFORMAT_SUBTYPE_IEC61937_DOLBY_DIGITAL; */
> +    wf->SubFormat = KSDATAFORMAT_SUBTYPE_AC3_AUDIO;

+    wf->SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;

> +
> +    wf->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
> +    wf->Format.nChannels = 2; /* To prevent channel re-ordering */
> +    wf->Format.nSamplesPerSec = audio->i_rate;
> +    wf->Format.wBitsPerSample = 16;
> +    wf->Format.nBlockAlign = 4; /* wf->Format.wBitsPerSample / 8 *
> wf->Format.nChannels  */
> +    wf->Format.nAvgBytesPerSec = wf->Format.nSamplesPerSec *
> wf->Format.nBlockAlign;
> +    wf->Format.cbSize = sizeof (*wf) - sizeof (wf->Format);
> +
> +    wf->Samples.wValidBitsPerSample = wf->Format.wBitsPerSample;
> +
> +    wf->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
> +}
> +
>  static void vlc_ToWave(WAVEFORMATEXTENSIBLE *restrict wf,
>                         audio_sample_format_t *restrict audio)
>  {
> @@ -345,10 +370,6 @@ static unsigned vlc_CheckWaveOrder (const
> WAVEFORMATEX *restrict wf,
>  static HRESULT Start(aout_stream_t *s, audio_sample_format_t *restrict
>  fmt,
>                       const GUID *sid)
>  {
> -    if (!s->b_force && var_InheritBool(s, "spdif") &&
> AOUT_FMT_SPDIF(fmt))
> -        /* Fallback to other plugin until pass-through is implemented */
> -        return E_NOTIMPL;
> -
>      static INIT_ONCE freq_once = INIT_ONCE_STATIC_INIT;
>  
>      if (!InitOnceExecuteOnce(&freq_once, InitFreq, &freq, NULL))
> @@ -371,9 +392,20 @@ static HRESULT Start(aout_stream_t *s,
> audio_sample_format_t *restrict fmt,
>      /* Configure audio stream */
>      WAVEFORMATEXTENSIBLE wf;
>      WAVEFORMATEX *pwf;
> +    AUDCLNT_SHAREMODE shared_mode;
> +
> +    if (AOUT_FMT_SPDIF(fmt) && var_InheritBool(s, "spdif"))
> +    {
> +        vlc_SpdifToWave(&wf, fmt);
> +        shared_mode = AUDCLNT_SHAREMODE_EXCLUSIVE;
> +    }
> +    else
> +    {
> +        vlc_ToWave(&wf, fmt);
> +        shared_mode = AUDCLNT_SHAREMODE_SHARED;
> +    }
>  
> -    vlc_ToWave(&wf, fmt);
> -    hr = IAudioClient_IsFormatSupported(sys->client,
> AUDCLNT_SHAREMODE_SHARED,
> +    hr = IAudioClient_IsFormatSupported(sys->client, shared_mode,
>                                          &wf.Format, &pwf);
>      if (FAILED(hr))
>      {
> @@ -391,6 +423,7 @@ static HRESULT Start(aout_stream_t *s,
> audio_sample_format_t *restrict fmt,
>              hr = E_INVALIDARG;
>              goto error;
>          }
> +        shared_mode = AUDCLNT_SHAREMODE_SHARED;
>          msg_Dbg(s, "modified format");
>      }
>      else
> @@ -400,7 +433,7 @@ static HRESULT Start(aout_stream_t *s,
> audio_sample_format_t *restrict fmt,
>                                                 sys->chans_table);
>      sys->format = fmt->i_format;
>  
> -    hr = IAudioClient_Initialize(sys->client, AUDCLNT_SHAREMODE_SHARED,
> 0,
> +    hr = IAudioClient_Initialize(sys->client, shared_mode, 0,
>                                   AOUT_MAX_PREPARE_TIME * 10, 0,
>                                   (hr == S_OK) ? &wf.Format : pwf, sid);
>      CoTaskMemFree(pwf);
> @@ -429,6 +462,7 @@ static HRESULT Start(aout_stream_t *s,
> audio_sample_format_t *restrict fmt,
>  
>      sys->rate = fmt->i_rate;
>      sys->bytes_per_frame = fmt->i_bytes_per_frame;
> +    sys->frame_length = fmt->i_frame_length;
>      sys->written = 0;
>      s->sys = sys;
>      s->time_get = TimeGet;
> -- 
> 2.8.0.rc3
> 
> _______________________________________________
> 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