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 aout_sys_t *sys = opaque;
106 (void)iid; (void)actparms;
111 static int aout_stream_Start(void *func, va_list ap)
113 aout_stream_start_t start = func;
114 aout_stream_t *s = va_arg(ap, aout_stream_t *);
115 audio_sample_format_t *fmt = va_arg(ap, audio_sample_format_t *);
116 HRESULT *hr = va_arg(ap, HRESULT *);
118 *hr = start(s, fmt, &GUID_VLC_AUD_OUT);
119 return SUCCEEDED(*hr) ? VLC_SUCCESS : VLC_EGENERIC;
122 static void aout_stream_Stop(void *func, va_list ap)
124 aout_stream_stop_t stop = func;
125 aout_stream_t *s = va_arg(ap, aout_stream_t *);
130 static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
132 aout_sys_t *sys = aout->sys;
135 aout_stream_t *s = vlc_object_create(aout, sizeof (*s));
136 if (unlikely(s == NULL))
139 s->owner.device = sys->client;
140 s->owner.activate = ActivateDevice;
143 sys->module = vlc_module_load(s, "aout stream", NULL, false,
144 aout_stream_Start, s, fmt, &hr);
147 if (sys->module == NULL)
149 vlc_object_release(s);
153 assert (sys->stream == NULL);
158 static void Stop(audio_output_t *aout)
160 aout_sys_t *sys = aout->sys;
162 assert (sys->stream != NULL);
165 vlc_module_unload(sys->module, aout_stream_Stop, sys->stream);
168 vlc_object_release(sys->stream);
172 static int Open(vlc_object_t *obj)
174 audio_output_t *aout = (audio_output_t *)obj;
176 aout_sys_t *sys = malloc(sizeof (*sys));
177 if (unlikely(sys == NULL))
182 sys->client = var_InheritAddress(aout, "mmdevice-audioclient");
183 assert(sys->client != NULL);
186 aout->time_get = TimeGet;
193 static void Close(vlc_object_t *obj)
195 audio_output_t *aout = (audio_output_t *)obj;
196 aout_sys_t *sys = aout->sys;
203 set_shortname("winstore")
204 set_description(N_("Windows Store audio output"))
205 set_capability("audio output", 150)
206 /* Pointer to the activated AudioClient* */
207 add_integer("winstore-audioclient", 0x0, NULL, NULL, true);
208 set_category(CAT_AUDIO)
209 set_subcategory(SUBCAT_AUDIO_AOUT)
210 add_shortcut("wasapi")
211 set_callbacks(Open, Close)