1 /*****************************************************************************
2 * mmdevice.c : Windows Multimedia Device API audio output plugin for VLC
3 *****************************************************************************
4 * Copyright (C) 2012 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
30 #include <audiopolicy.h>
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
35 #include <vlc_modules.h>
36 #include "audio_output/mmdevice.h"
38 DEFINE_GUID (GUID_VLC_AUD_OUT, 0x4533f59d, 0x59ee, 0x00c6,
39 0xad, 0xb2, 0xc6, 0x8b, 0x50, 0x1a, 0x66, 0x55);
41 static void EnterMTA(void)
43 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
44 if (unlikely(FAILED(hr)))
48 static void LeaveMTA(void)
55 aout_stream_t *stream; /**< Underlying audio output stream */
60 static int TimeGet(audio_output_t *aout, mtime_t *restrict delay)
62 aout_sys_t *sys = aout->sys;
66 hr = aout_stream_TimeGet(sys->stream, delay);
69 return SUCCEEDED(hr) ? 0 : -1;
72 static void Play(audio_output_t *aout, block_t *block)
74 aout_sys_t *sys = aout->sys;
77 aout_stream_Play(sys->stream, block);
81 static void Pause(audio_output_t *aout, bool paused, mtime_t date)
83 aout_sys_t *sys = aout->sys;
86 aout_stream_Pause(sys->stream, paused);
92 static void Flush(audio_output_t *aout, bool wait)
94 aout_sys_t *sys = aout->sys;
97 aout_stream_Flush(sys->stream, wait);
101 static HRESULT ActivateDevice(void *opaque, REFIID iid, PROPVARIANT *actparms,
104 (void) iid; (void) actparms;
105 IAudioClient* client = (IAudioClient*)opaque;
106 IAudioClient_AddRef(client);
112 static int aout_stream_Start(void *func, va_list ap)
114 aout_stream_start_t start = func;
115 aout_stream_t *s = va_arg(ap, aout_stream_t *);
116 audio_sample_format_t *fmt = va_arg(ap, audio_sample_format_t *);
117 HRESULT *hr = va_arg(ap, HRESULT *);
119 *hr = start(s, fmt, &GUID_VLC_AUD_OUT);
120 return SUCCEEDED(*hr) ? VLC_SUCCESS : VLC_EGENERIC;
123 static void aout_stream_Stop(void *func, va_list ap)
125 aout_stream_stop_t stop = func;
126 aout_stream_t *s = va_arg(ap, aout_stream_t *);
131 static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
133 aout_sys_t *sys = aout->sys;
136 aout_stream_t *s = vlc_object_create(aout, sizeof (*s));
137 if (unlikely(s == NULL))
140 s->owner.device = sys->client;
141 s->owner.activate = ActivateDevice;
144 sys->module = vlc_module_load(s, "aout stream", NULL, false,
145 aout_stream_Start, s, fmt, &hr);
148 if (sys->module == NULL)
150 vlc_object_release(s);
154 assert (sys->stream == NULL);
159 static void Stop(audio_output_t *aout)
161 aout_sys_t *sys = aout->sys;
163 assert (sys->stream != NULL);
166 vlc_module_unload(sys->module, aout_stream_Stop, sys->stream);
169 vlc_object_release(sys->stream);
173 static int Open(vlc_object_t *obj)
175 audio_output_t *aout = (audio_output_t *)obj;
177 IAudioClient* client = var_InheritInteger(aout, "winstore-audioclient");
181 aout_sys_t *sys = malloc(sizeof (*sys));
182 if (unlikely(sys == NULL))
187 sys->client = client;
190 aout->time_get = TimeGet;
197 static void Close(vlc_object_t *obj)
199 audio_output_t *aout = (audio_output_t *)obj;
200 aout_sys_t *sys = aout->sys;
206 set_shortname("winstore")
207 set_description(N_("Windows Store audio output"))
208 set_capability("audio output", 150)
209 /* Pointer to the activated AudioClient* */
210 add_integer("winstore-audioclient", 0x0, NULL, NULL, true);
211 set_category(CAT_AUDIO)
212 set_subcategory(SUBCAT_AUDIO_AOUT)
213 add_shortcut("wasapi")
214 set_callbacks(Open, Close)