summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/ao.rst24
-rw-r--r--audio/out/ao_wasapi.c11
-rwxr-xr-xaudio/out/ao_wasapi_utils.c102
-rwxr-xr-xaudio/out/ao_wasapi_utils.h8
4 files changed, 41 insertions, 104 deletions
diff --git a/DOCS/man/ao.rst b/DOCS/man/ao.rst
index 60ba6348b1..5ca960c4ea 100644
--- a/DOCS/man/ao.rst
+++ b/DOCS/man/ao.rst
@@ -302,19 +302,19 @@ Available audio output drivers are:
``wasapi``
Audio output to the Windows Audio Session API.
+ ``exclusive``
+ Requests exclusive, direct hardware access. By definition prevents
+ sound playback of any other program until mpv exits.
``device=<id>``
Uses the requested endpoint instead of the system's default audio
- endpoint. Both the number and the ID String are valid; the ID String
- is guaranteed to not change unless the driver is uninstalled.
+ endpoint. Both an ordinal number (0,1,2,...) and the GUID
+ String are valid; the GUID string is guaranteed to not change
+ unless the driver is uninstalled.
- Also supports searching active devices by name. If more than one
- device matches the name, refuses loading it.
+ Also supports searching active devices by human readable name. If more
+ than one device matches the name, refuses loading it.
- To get a list of the valid devices, give ``help`` as the id. The
- list is the same as the ``list`` suboption, but stops the player
- initialization.
- ``exclusive``
- Requests exclusive, direct hardware access. By definition prevents
- sound playback of any other program until mpv exits.
- ``list``
- Lists all audio endpoints (output devices) present in the system.
+ This option is mostly deprecated in favour of the more general
+ ``--audio-device`` option. That said, ``--audio-device=help`` will give
+ a list of valid device GUIDs (prefixed with ``wasapi/``), as well as
+ their human readable names, which should work here.
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 8a8d910469..5821409f91 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -253,11 +253,6 @@ static int init(struct ao *ao)
if(!wasapi_fill_VistaBlob(state))
MP_WARN(ao, "Error loading thread priority functions\n");
- if (state->opt_list) {
- if(!wasapi_enumerate_devices(state->log, NULL, NULL))
- MP_WARN(ao, "Error enumerating devices\n");
- }
-
if (state->opt_exclusive) {
state->share_mode = AUDCLNT_SHAREMODE_EXCLUSIVE;
} else {
@@ -412,8 +407,7 @@ static int hotplug_init(struct ao *ao)
static void list_devs(struct ao *ao, struct ao_device_list *list)
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
- if(!wasapi_enumerate_devices(mp_null_log, ao, list))
- MP_WARN(ao, "Error enumerating devices\n");
+ wasapi_enumerate_devices(ao, list);
CoUninitialize();
}
@@ -433,8 +427,7 @@ const struct ao_driver audio_out_wasapi = {
.priv_size = sizeof(wasapi_state),
.options = (const struct m_option[]) {
OPT_FLAG("exclusive", opt_exclusive, 0),
- OPT_FLAG("list", opt_list, 0),
- OPT_STRING_VALIDATE("device", opt_device, 0, wasapi_validate_device),
+ OPT_STRING("device", opt_device, 0),
{NULL},
},
};
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 6ecc6c82a2..eb4350f96d 100755
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -20,6 +20,7 @@
#include <math.h>
#include <libavutil/common.h>
#include <windows.h>
+#include <errors.h>
#include <ksguid.h>
#include <ksmedia.h>
#include <audioclient.h>
@@ -96,12 +97,14 @@ const char *wasapi_explain_err(const HRESULT hr)
#define E(x) case x : return # x ;
switch (hr) {
E(S_OK)
+ E(S_FALSE)
E(E_FAIL)
E(E_OUTOFMEMORY)
E(E_POINTER)
E(E_HANDLE)
E(E_NOTIMPL)
E(E_INVALIDARG)
+ E(E_PROP_ID_UNSUPPORTED)
E(REGDB_E_IIDNOTREG)
E(CO_E_NOTINITIALIZED)
E(AUDCLNT_E_NOT_INITIALIZED)
@@ -826,96 +829,62 @@ end:
return found;
}
-// Warning: ao and list are NULL in the "--ao=wasapi:device=help" path!
-static HRESULT enumerate_with_state(struct mp_log *log, struct ao *ao,
- struct ao_device_list *list,
- char *header, int status, int with_id)
+HRESULT wasapi_enumerate_devices(struct ao *ao,
+ struct ao_device_list *list)
{
- HRESULT hr;
IMMDeviceEnumerator *pEnumerator = NULL;
IMMDeviceCollection *pDevices = NULL;
IMMDevice *pDevice = NULL;
- char *defid = NULL;
-
- hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
- &IID_IMMDeviceEnumerator, (void **)&pEnumerator);
- EXIT_ON_ERROR(hr);
-
- hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(pEnumerator,
- eRender, eMultimedia,
- &pDevice);
+ char *name = NULL, *id = NULL;
+ HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
+ &IID_IMMDeviceEnumerator,
+ (void **)&pEnumerator);
EXIT_ON_ERROR(hr);
- defid = get_device_id(pDevice);
-
- SAFE_RELEASE(pDevice, IMMDevice_Release(pDevice));
-
hr = IMMDeviceEnumerator_EnumAudioEndpoints(pEnumerator, eRender,
- status, &pDevices);
+ DEVICE_STATE_ACTIVE, &pDevices);
EXIT_ON_ERROR(hr);
int count;
- IMMDeviceCollection_GetCount(pDevices, &count);
+ hr = IMMDeviceCollection_GetCount(pDevices, &count);
+ EXIT_ON_ERROR(hr);
if (count > 0)
- mp_info(log, "%s\n", header);
+ MP_VERBOSE(ao, "Output devices:\n");
for (int i = 0; i < count; i++) {
hr = IMMDeviceCollection_Item(pDevices, i, &pDevice);
EXIT_ON_ERROR(hr);
- char *name = get_device_name(pDevice);
- char *id = get_device_id(pDevice);
-
- char *mark = "";
- if (strcmp(id, defid) == 0)
- mark = " (default)";
-
- if (with_id) {
- mp_info(log, "Device #%d: %s, ID: %s%s\n", i, name, id, mark);
- } else {
- mp_info(log, "%s, ID: %s%s\n", name, id, mark);
+ name = get_device_name(pDevice);
+ id = get_device_id(pDevice);
+ if (!id) {
+ hr = E_FAIL;
+ EXIT_ON_ERROR(hr);
}
+ char *safe_name = name ? name : "";
+ ao_device_list_add(list, ao, &(struct ao_device_desc){id, safe_name});
- if (ao) {
- char *desc = talloc_asprintf(NULL, "%s, ID: %s%s", name, id, mark);
- struct ao_device_desc e = {id, desc};
- ao_device_list_add(list, ao, &e);
- }
+ MP_VERBOSE(ao, "#%d, GUID: \'%s\', name: \'%s\'\n", i, id, safe_name);
talloc_free(name);
talloc_free(id);
SAFE_RELEASE(pDevice, IMMDevice_Release(pDevice));
}
- talloc_free(defid);
SAFE_RELEASE(pDevices, IMMDeviceCollection_Release(pDevices));
SAFE_RELEASE(pEnumerator, IMMDeviceEnumerator_Release(pEnumerator));
return S_OK;
exit_label:
- talloc_free(defid);
+ MP_ERR(ao, "Error enumerating devices: %s (0x%"PRIx32")\n",
+ wasapi_explain_err(hr), (uint32_t) hr);
+ talloc_free(name);
+ talloc_free(id);
SAFE_RELEASE(pDevice, IMMDevice_Release(pDevice));
SAFE_RELEASE(pDevices, IMMDeviceCollection_Release(pDevices));
SAFE_RELEASE(pEnumerator, IMMDeviceEnumerator_Release(pEnumerator));
return hr;
}
-bool wasapi_enumerate_devices(struct mp_log *log, struct ao *ao,
- struct ao_device_list *list)
-{
- HRESULT hr;
- hr = enumerate_with_state(log, ao, list, "Active devices:",
- DEVICE_STATE_ACTIVE, 1);
- EXIT_ON_ERROR(hr);
- hr = enumerate_with_state(log, ao, list, "Unplugged devices:",
- DEVICE_STATE_UNPLUGGED, 0);
- EXIT_ON_ERROR(hr);
- return true;
-exit_label:
- mp_err(log, "Error enumerating devices: %s (0x%"PRIx32")\n",
- wasapi_explain_err(hr), (uint32_t) hr);
- return false;
-}
-
static HRESULT load_default_device(struct ao *ao, IMMDeviceEnumerator* pEnumerator,
IMMDevice **ppDevice)
{
@@ -1043,27 +1012,6 @@ exit_label:
return hr;
}
-int wasapi_validate_device(struct mp_log *log, const m_option_t *opt,
- struct bstr name, struct bstr param)
-{
- if (bstr_equals0(param, "help")) {
- wasapi_enumerate_devices(log, NULL, NULL);
- return M_OPT_EXIT;
- }
-
- mp_dbg(log, "Validating device=%s\n", param.start);
-
- char *end;
- int devno = (int) strtol(param.start, &end, 10);
-
- int ret = 1;
- if ((end == (void *)param.start || *end) && devno < 0)
- ret = M_OPT_OUT_OF_RANGE;
-
- mp_dbg(log, "device=%s %svalid\n", param.start, ret == 1 ? "" : "not ");
- return ret;
-}
-
HRESULT wasapi_setup_proxies(struct wasapi_state *state) {
HRESULT hr;
diff --git a/audio/out/ao_wasapi_utils.h b/audio/out/ao_wasapi_utils.h
index 7327d2f350..9806bba4a9 100755
--- a/audio/out/ao_wasapi_utils.h
+++ b/audio/out/ao_wasapi_utils.h
@@ -36,12 +36,8 @@ bool wasapi_fill_VistaBlob(wasapi_state *state);
const char *wasapi_explain_err(const HRESULT hr);
-bool wasapi_enumerate_devices(struct mp_log *log, struct ao *ao,
- struct ao_device_list *list);
-
-int wasapi_validate_device(struct mp_log *log, const m_option_t *opt,
- struct bstr name, struct bstr param);
-
+HRESULT wasapi_enumerate_devices(struct ao *ao,
+ struct ao_device_list *list);
void wasapi_dispatch(void);
HRESULT wasapi_thread_init(struct ao *ao);