Commit d52d2efd authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

mmdevice: split out Store code

parent e5267d38
...@@ -487,6 +487,7 @@ AS_IF([test "${SYS}" = "mingw32" -a "${enable_winstore_app}" = "yes"], [ ...@@ -487,6 +487,7 @@ AS_IF([test "${SYS}" = "mingw32" -a "${enable_winstore_app}" = "yes"], [
VLC_ADD_LIBS([libvlccore], [-lole32 -lruntimeobject]) VLC_ADD_LIBS([libvlccore], [-lole32 -lruntimeobject])
]) ])
AC_DEFINE_UNQUOTED(VLC_WINSTORE_APP, ${vlc_winstore_app}, [Define to 1 if you want to build for Windows Store apps]) AC_DEFINE_UNQUOTED(VLC_WINSTORE_APP, ${vlc_winstore_app}, [Define to 1 if you want to build for Windows Store apps])
AM_CONDITIONAL([HAVE_WINSTORE], [test "$vlc_winstore_app" = "1"])
dnl dnl
......
...@@ -59,10 +59,17 @@ endif ...@@ -59,10 +59,17 @@ endif
libmmdevice_plugin_la_SOURCES = audio_output/mmdevice.c audio_output/mmdevice.h libmmdevice_plugin_la_SOURCES = audio_output/mmdevice.c audio_output/mmdevice.h
libmmdevice_plugin_la_LIBADD = -lole32 $(LIBM) libmmdevice_plugin_la_LIBADD = -lole32 $(LIBM)
libwinstore_plugin_la_SOURCES = audio_output/winstore.c audio_output/mmdevice.h
libwinstore_plugin_la_LIBADD = -lole32
libwasapi_plugin_la_SOURCES = audio_output/wasapi.c libwasapi_plugin_la_SOURCES = audio_output/wasapi.c
libwasapi_plugin_la_LIBADD = -lole32 -lksuser libwasapi_plugin_la_LIBADD = -lole32 -lksuser
if HAVE_WASAPI if HAVE_WASAPI
aout_LTLIBRARIES += libmmdevice_plugin.la libwasapi_plugin.la aout_LTLIBRARIES += libwasapi_plugin.la
if !HAVE_WINSTORE
aout_LTLIBRARIES += libmmdevice_plugin.la
else
aout_LTLIBRARIES += libwinstore_plugin.la
endif
endif endif
libdirectsound_plugin_la_SOURCES = audio_output/directsound.c \ libdirectsound_plugin_la_SOURCES = audio_output/directsound.c \
......
/***************************************************************************** /*****************************************************************************
* mmdevice.c : Windows Multimedia Device API audio output plugin for VLC * mmdevice.c : Windows Multimedia Device API audio output plugin for VLC
***************************************************************************** *****************************************************************************
* Copyright (C) 2012 Rémi Denis-Courmont * Copyright (C) 2012-2013 Rémi Denis-Courmont
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by * under the terms of the GNU Lesser General Public License as published by
...@@ -76,7 +76,6 @@ BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved) ...@@ -76,7 +76,6 @@ BOOL WINAPI DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
DEFINE_GUID (GUID_VLC_AUD_OUT, 0x4533f59d, 0x59ee, 0x00c6, DEFINE_GUID (GUID_VLC_AUD_OUT, 0x4533f59d, 0x59ee, 0x00c6,
0xad, 0xb2, 0xc6, 0x8b, 0x50, 0x1a, 0x66, 0x55); 0xad, 0xb2, 0xc6, 0x8b, 0x50, 0x1a, 0x66, 0x55);
#if !VLC_WINSTORE_APP
static int TryEnterMTA(vlc_object_t *obj) static int TryEnterMTA(vlc_object_t *obj)
{ {
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
...@@ -88,7 +87,6 @@ static int TryEnterMTA(vlc_object_t *obj) ...@@ -88,7 +87,6 @@ static int TryEnterMTA(vlc_object_t *obj)
return 0; return 0;
} }
#define TryEnterMTA(o) TryEnterMTA(VLC_OBJECT(o)) #define TryEnterMTA(o) TryEnterMTA(VLC_OBJECT(o))
#endif
static void EnterMTA(void) static void EnterMTA(void)
{ {
...@@ -102,15 +100,12 @@ static void LeaveMTA(void) ...@@ -102,15 +100,12 @@ static void LeaveMTA(void)
CoUninitialize(); CoUninitialize();
} }
#if !VLC_WINSTORE_APP
static wchar_t default_device[1] = L""; static wchar_t default_device[1] = L"";
#endif
struct aout_sys_t struct aout_sys_t
{ {
aout_stream_t *stream; /**< Underlying audio output stream */ aout_stream_t *stream; /**< Underlying audio output stream */
module_t *module; module_t *module;
#if !VLC_WINSTORE_APP
audio_output_t *aout; audio_output_t *aout;
IMMDeviceEnumerator *it; /**< Device enumerator, NULL when exiting */ IMMDeviceEnumerator *it; /**< Device enumerator, NULL when exiting */
IMMDevice *dev; /**< Selected output device, NULL if none */ IMMDevice *dev; /**< Selected output device, NULL if none */
...@@ -127,9 +122,6 @@ struct aout_sys_t ...@@ -127,9 +122,6 @@ struct aout_sys_t
CONDITION_VARIABLE work; CONDITION_VARIABLE work;
CONDITION_VARIABLE ready; CONDITION_VARIABLE ready;
vlc_thread_t thread; /**< Thread for audio session control */ vlc_thread_t thread; /**< Thread for audio session control */
#else
void *client;
#endif
}; };
/* NOTE: The Core Audio API documentation totally fails to specify the thread /* NOTE: The Core Audio API documentation totally fails to specify the thread
...@@ -195,22 +187,11 @@ static void Flush(audio_output_t *aout, bool wait) ...@@ -195,22 +187,11 @@ static void Flush(audio_output_t *aout, bool wait)
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
EnterMTA(); EnterMTA();
aout_stream_Flush(sys->stream, wait);
if (wait)
{ /* Loosy drain emulation */
mtime_t delay;
if (SUCCEEDED(aout_stream_TimeGet(sys->stream, &delay)))
Sleep((delay / (CLOCK_FREQ / 1000)) + 1);
}
else
aout_stream_Flush(sys->stream);
LeaveMTA(); LeaveMTA();
} }
#if !VLC_WINSTORE_APP
static int VolumeSet(audio_output_t *aout, float vol) static int VolumeSet(audio_output_t *aout, float vol)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
...@@ -894,17 +875,6 @@ static HRESULT ActivateDevice(void *opaque, REFIID iid, PROPVARIANT *actparms, ...@@ -894,17 +875,6 @@ static HRESULT ActivateDevice(void *opaque, REFIID iid, PROPVARIANT *actparms,
IMMDevice *dev = opaque; IMMDevice *dev = opaque;
return IMMDevice_Activate(dev, iid, CLSCTX_ALL, actparms, pv); return IMMDevice_Activate(dev, iid, CLSCTX_ALL, actparms, pv);
} }
#else /* VLC_WINSTORE_APP */
static HRESULT ActivateDevice(void *opaque, REFIID iid, PROPVARIANT *actparms,
void **restrict pv)
{
aout_sys_t *sys = opaque;
(void)iid; (void)actparms;
*pv = sys->client;
return S_OK;
}
#endif /* VLC_WINSTORE_APP */
static int aout_stream_Start(void *func, va_list ap) static int aout_stream_Start(void *func, va_list ap)
{ {
...@@ -930,20 +900,15 @@ static void aout_stream_Stop(void *func, va_list ap) ...@@ -930,20 +900,15 @@ static void aout_stream_Stop(void *func, va_list ap)
static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt) static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
{ {
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
#if !VLC_WINSTORE_APP
if (sys->dev == NULL) if (sys->dev == NULL)
return -1; return -1;
#endif
aout_stream_t *s = vlc_object_create(aout, sizeof (*s)); aout_stream_t *s = vlc_object_create(aout, sizeof (*s));
if (unlikely(s == NULL)) if (unlikely(s == NULL))
return -1; return -1;
#if !VLC_WINSTORE_APP
s->owner.device = sys->dev; s->owner.device = sys->dev;
#else
s->owner.device = sys->client;
#endif
s->owner.activate = ActivateDevice; s->owner.activate = ActivateDevice;
EnterMTA(); EnterMTA();
...@@ -953,11 +918,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt) ...@@ -953,11 +918,7 @@ static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
sys->module = vlc_module_load(s, "aout stream", NULL, false, sys->module = vlc_module_load(s, "aout stream", NULL, false,
aout_stream_Start, s, fmt, &hr); aout_stream_Start, s, fmt, &hr);
if (hr != AUDCLNT_E_DEVICE_INVALIDATED if (hr != AUDCLNT_E_DEVICE_INVALIDATED || DeviceSelect(aout, NULL))
#if !VLC_WINSTORE_APP
|| DeviceSelect(aout, NULL)
#endif
)
break; break;
} }
LeaveMTA(); LeaveMTA();
...@@ -997,7 +958,6 @@ static int Open(vlc_object_t *obj) ...@@ -997,7 +958,6 @@ static int Open(vlc_object_t *obj)
aout->sys = sys; aout->sys = sys;
sys->stream = NULL; sys->stream = NULL;
#if !VLC_WINSTORE_APP
sys->aout = aout; sys->aout = aout;
sys->it = NULL; sys->it = NULL;
sys->dev = NULL; sys->dev = NULL;
...@@ -1038,17 +998,13 @@ static int Open(vlc_object_t *obj) ...@@ -1038,17 +998,13 @@ static int Open(vlc_object_t *obj)
SleepConditionVariableCS(&sys->ready, &sys->lock, INFINITE); SleepConditionVariableCS(&sys->ready, &sys->lock, INFINITE);
LeaveCriticalSection(&sys->lock); LeaveCriticalSection(&sys->lock);
LeaveMTA(); /* Leave MTA after thread has entered MTA */ LeaveMTA(); /* Leave MTA after thread has entered MTA */
#else
sys->client = var_InheritAddress(aout, "mmdevice-audioclient");
assert(sys->client != NULL);
#endif
aout->start = Start; aout->start = Start;
aout->stop = Stop; aout->stop = Stop;
aout->time_get = TimeGet; aout->time_get = TimeGet;
aout->play = Play; aout->play = Play;
aout->pause = Pause; aout->pause = Pause;
aout->flush = Flush; aout->flush = Flush;
#if !VLC_WINSTORE_APP
aout->volume_set = VolumeSet; aout->volume_set = VolumeSet;
aout->mute_set = MuteSet; aout->mute_set = MuteSet;
aout->device_select = DeviceSelect; aout->device_select = DeviceSelect;
...@@ -1058,16 +1014,13 @@ error: ...@@ -1058,16 +1014,13 @@ error:
DeleteCriticalSection(&sys->lock); DeleteCriticalSection(&sys->lock);
free(sys); free(sys);
return VLC_EGENERIC; return VLC_EGENERIC;
#else
return VLC_SUCCESS;
#endif
} }
static void Close(vlc_object_t *obj) static void Close(vlc_object_t *obj)
{ {
audio_output_t *aout = (audio_output_t *)obj; audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys; aout_sys_t *sys = aout->sys;
#if !VLC_WINSTORE_APP
EnterCriticalSection(&sys->lock); EnterCriticalSection(&sys->lock);
sys->device = default_device; /* break out of MMSession() loop */ sys->device = default_device; /* break out of MMSession() loop */
sys->it = NULL; /* break out of MMThread() loop */ sys->it = NULL; /* break out of MMThread() loop */
...@@ -1076,9 +1029,6 @@ static void Close(vlc_object_t *obj) ...@@ -1076,9 +1029,6 @@ static void Close(vlc_object_t *obj)
vlc_join(sys->thread, NULL); vlc_join(sys->thread, NULL);
DeleteCriticalSection(&sys->lock); DeleteCriticalSection(&sys->lock);
#else
free(sys->client);
#endif
free(sys); free(sys);
} }
...@@ -1086,10 +1036,6 @@ vlc_module_begin() ...@@ -1086,10 +1036,6 @@ vlc_module_begin()
set_shortname("MMDevice") set_shortname("MMDevice")
set_description(N_("Windows Multimedia Device output")) set_description(N_("Windows Multimedia Device output"))
set_capability("audio output", 150) set_capability("audio output", 150)
#if VLC_WINSTORE_APP
/* Pointer to the activated AudioClient* */
add_integer("mmdevice-audioclient", 0x0, NULL, NULL, true);
#endif
set_category(CAT_AUDIO) set_category(CAT_AUDIO)
set_subcategory(SUBCAT_AUDIO_AOUT) set_subcategory(SUBCAT_AUDIO_AOUT)
add_shortcut("wasapi") add_shortcut("wasapi")
......
...@@ -72,8 +72,17 @@ static inline HRESULT aout_stream_Pause(aout_stream_t *s, bool paused) ...@@ -72,8 +72,17 @@ static inline HRESULT aout_stream_Pause(aout_stream_t *s, bool paused)
return (s->pause)(s, paused); return (s->pause)(s, paused);
} }
static inline HRESULT aout_stream_Flush(aout_stream_t *s) static inline HRESULT aout_stream_Flush(aout_stream_t *s, bool wait)
{ {
if (wait)
{ /* Loosy drain emulation */
mtime_t delay;
if (SUCCEEDED(aout_stream_TimeGet(s, &delay)))
Sleep((delay / (CLOCK_FREQ / 1000)) + 1);
return S_OK;
}
else
return (s->flush)(s); return (s->flush)(s);
} }
......
/*****************************************************************************
* mmdevice.c : Windows Multimedia Device API audio output plugin for VLC
*****************************************************************************
* Copyright (C) 2012 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#define INITGUID
#define COBJMACROS
#include <stdlib.h>
#include <assert.h>
#include <audiopolicy.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_aout.h>
#include <vlc_modules.h>
#include "audio_output/mmdevice.h"
DEFINE_GUID (GUID_VLC_AUD_OUT, 0x4533f59d, 0x59ee, 0x00c6,
0xad, 0xb2, 0xc6, 0x8b, 0x50, 0x1a, 0x66, 0x55);
static void EnterMTA(void)
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (unlikely(FAILED(hr)))
abort();
}
static void LeaveMTA(void)
{
CoUninitialize();
}
struct aout_sys_t
{
aout_stream_t *stream; /**< Underlying audio output stream */
module_t *module;
IAudioClient *client;
};
static int TimeGet(audio_output_t *aout, mtime_t *restrict delay)
{
aout_sys_t *sys = aout->sys;
HRESULT hr;
EnterMTA();
hr = aout_stream_TimeGet(sys->stream, delay);
LeaveMTA();
return SUCCEEDED(hr) ? 0 : -1;
}
static void Play(audio_output_t *aout, block_t *block)
{
aout_sys_t *sys = aout->sys;
EnterMTA();
aout_stream_Play(sys->stream, block);
LeaveMTA();
}
static void Pause(audio_output_t *aout, bool paused, mtime_t date)
{
aout_sys_t *sys = aout->sys;
EnterMTA();
aout_stream_Pause(sys->stream, paused);
LeaveMTA();
(void) date;
}
static void Flush(audio_output_t *aout, bool wait)
{
aout_sys_t *sys = aout->sys;
EnterMTA();
aout_stream_Flush(sys->stream, wait);
LeaveMTA();
}
static HRESULT ActivateDevice(void *opaque, REFIID iid, PROPVARIANT *actparms,
void **restrict pv)
{
aout_sys_t *sys = opaque;
(void)iid; (void)actparms;
*pv = sys->client;
return S_OK;
}
static int aout_stream_Start(void *func, va_list ap)
{
aout_stream_start_t start = func;
aout_stream_t *s = va_arg(ap, aout_stream_t *);
audio_sample_format_t *fmt = va_arg(ap, audio_sample_format_t *);
HRESULT *hr = va_arg(ap, HRESULT *);
*hr = start(s, fmt, &GUID_VLC_AUD_OUT);
return SUCCEEDED(*hr) ? VLC_SUCCESS : VLC_EGENERIC;
}
static void aout_stream_Stop(void *func, va_list ap)
{
aout_stream_stop_t stop = func;
aout_stream_t *s = va_arg(ap, aout_stream_t *);
stop(s);
}
static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt)
{
aout_sys_t *sys = aout->sys;
HRESULT hr;
aout_stream_t *s = vlc_object_create(aout, sizeof (*s));
if (unlikely(s == NULL))
return -1;
s->owner.device = sys->client;
s->owner.activate = ActivateDevice;
EnterMTA();
sys->module = vlc_module_load(s, "aout stream", NULL, false,
aout_stream_Start, s, fmt, &hr);
LeaveMTA();
if (sys->module == NULL)
{
vlc_object_release(s);
return -1;
}
assert (sys->stream == NULL);
sys->stream = s;
return 0;
}
static void Stop(audio_output_t *aout)
{
aout_sys_t *sys = aout->sys;
assert (sys->stream != NULL);
EnterMTA();
vlc_module_unload(sys->module, aout_stream_Stop, sys->stream);
LeaveMTA();
vlc_object_release(sys->stream);
sys->stream = NULL;
}
static int Open(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = malloc(sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
aout->sys = sys;
sys->stream = NULL;
sys->client = var_InheritAddress(aout, "mmdevice-audioclient");
assert(sys->client != NULL);
aout->start = Start;
aout->stop = Stop;
aout->time_get = TimeGet;
aout->play = Play;
aout->pause = Pause;
aout->flush = Flush;
return VLC_SUCCESS;
}
static void Close(vlc_object_t *obj)
{
audio_output_t *aout = (audio_output_t *)obj;
aout_sys_t *sys = aout->sys;
free(sys->client);
free(sys);
}
vlc_module_begin()
set_shortname("winstore")
set_description(N_("Windows Store audio output"))
set_capability("audio output", 150)
/* Pointer to the activated AudioClient* */
add_integer("winstore-audioclient", 0x0, NULL, NULL, true);
set_category(CAT_AUDIO)
set_subcategory(SUBCAT_AUDIO_AOUT)
add_shortcut("wasapi")
set_callbacks(Open, Close)
vlc_module_end()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment