mirror of
https://github.com/mpv-player/mpv
synced 2025-03-11 08:37:59 +00:00
ao_wasapi: fix device listing
remove depricated and convoluted validation. refer instead to the --audio-device option.
This commit is contained in:
parent
8158dfc9e8
commit
ea00fe0eeb
@ -302,19 +302,19 @@ Available audio output drivers are:
|
||||
``wasapi``
|
||||
Audio output to the Windows Audio Session API.
|
||||
|
||||
``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.
|
||||
|
||||
Also supports searching active devices by 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.
|
||||
``device=<id>``
|
||||
Uses the requested endpoint instead of the system's default audio
|
||||
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 human readable name. If more
|
||||
than one device matches the name, refuses loading it.
|
||||
|
||||
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.
|
||||
|
@ -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},
|
||||
},
|
||||
};
|
||||
|
@ -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);
|
||||
char *name = NULL, *id = NULL;
|
||||
HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||
&IID_IMMDeviceEnumerator,
|
||||
(void **)&pEnumerator);
|
||||
EXIT_ON_ERROR(hr);
|
||||
|
||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(pEnumerator,
|
||||
eRender, eMultimedia,
|
||||
&pDevice);
|
||||
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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user