summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/out/ao_coreaudio.c5
-rw-r--r--audio/out/ao_coreaudio_properties.c7
-rw-r--r--audio/out/ao_coreaudio_utils.c50
-rw-r--r--audio/out/ao_coreaudio_utils.h3
4 files changed, 46 insertions, 19 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 590549bd1a..0eab220421 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -156,7 +156,10 @@ static int init(struct ao *ao)
OSStatus err = ca_select_device(ao, ao->device, &p->device);
CHECK_CA_ERROR("failed to select device");
- ao->detected_device = talloc_asprintf(ao, "%d", p->device);
+ char *uid;
+ err = CA_GET_STR(p->device, kAudioDevicePropertyDeviceUID, &uid);
+ CHECK_CA_ERROR("failed to get device UID");
+ ao->detected_device = talloc_steal(ao, uid);
if (!init_chmap(ao))
goto coreaudio_error;
diff --git a/audio/out/ao_coreaudio_properties.c b/audio/out/ao_coreaudio_properties.c
index 181d338cbd..cf2b4d14a1 100644
--- a/audio/out/ao_coreaudio_properties.c
+++ b/audio/out/ao_coreaudio_properties.c
@@ -83,12 +83,7 @@ OSStatus ca_get_str(AudioObjectID id, ca_scope scope, ca_sel selector,
ca_get(id, scope, selector, sizeof(CFStringRef), (void **)&string);
CHECK_CA_ERROR_SILENT_L(coreaudio_error);
- CFIndex size =
- CFStringGetMaximumSizeForEncoding(
- CFStringGetLength(string), CA_CFSTR_ENCODING) + 1;
-
- *data = talloc_zero_size(NULL, size);
- CFStringGetCString(string, *data, size, CA_CFSTR_ENCODING);
+ *data = cfstr_get_cstr(string);
CFRelease(string);
coreaudio_error:
return err;
diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c
index fe8354939a..50c866d86c 100644
--- a/audio/out/ao_coreaudio_utils.c
+++ b/audio/out/ao_coreaudio_utils.c
@@ -28,6 +28,21 @@
#include "osdep/endian.h"
#include "audio/format.h"
+CFStringRef cfstr_from_cstr(char *str)
+{
+ return CFStringCreateWithCString(NULL, str, CA_CFSTR_ENCODING);
+}
+
+char *cfstr_get_cstr(CFStringRef cfstr)
+{
+ CFIndex size =
+ CFStringGetMaximumSizeForEncoding(
+ CFStringGetLength(cfstr), CA_CFSTR_ENCODING) + 1;
+ char *buffer = talloc_zero_size(NULL, size);
+ CFStringGetCString(cfstr, buffer, size, CA_CFSTR_ENCODING);
+ return buffer;
+}
+
static bool ca_is_output_device(struct ao *ao, AudioDeviceID dev)
{
size_t n_buffers;
@@ -49,9 +64,9 @@ void ca_get_device_list(struct ao *ao, struct ao_device_list *list)
for (int i = 0; i < n_devs; i++) {
if (!ca_is_output_device(ao, devs[i]))
continue;
- char name[32];
+ char *name;
char *desc;
- sprintf(name, "%d", devs[i]);
+ err = CA_GET_STR(devs[i], kAudioDevicePropertyDeviceUID, &name);
err = CA_GET_STR(devs[i], kAudioObjectPropertyName, &desc);
if (err != noErr)
desc = "Unknown";
@@ -65,21 +80,32 @@ coreaudio_error:
OSStatus ca_select_device(struct ao *ao, char* name, AudioDeviceID *device)
{
OSStatus err = noErr;
- errno = 0;
- int selection = name && name[0] ? strtol(name, (char **)NULL, 10) : -1;
- if (errno == EINVAL || errno == ERANGE) {
- selection = -1;
- MP_WARN(ao, "device identifier '%s' is invalid\n", name);
- }
- *device = 0;
- if (selection < 0) {
+ *device = kAudioObjectUnknown;
+
+ if (name) {
+ CFStringRef uid = cfstr_from_cstr(name);
+ AudioValueTranslation v = (AudioValueTranslation) {
+ .mInputData = &uid,
+ .mInputDataSize = sizeof(CFStringRef),
+ .mOutputData = device,
+ .mOutputDataSize = sizeof(*device),
+ };
+ uint32_t size = sizeof(AudioValueTranslation);
+ AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
+ .mSelector = kAudioHardwarePropertyDeviceForUID,
+ .mScope = kAudioObjectPropertyScopeGlobal,
+ .mElement = kAudioObjectPropertyElementMaster,
+ };
+ err = AudioObjectGetPropertyData(
+ kAudioObjectSystemObject, &p_addr, 0, 0, &size, &v);
+ CFRelease(uid);
+ CHECK_CA_ERROR("unable to query for device UID");
+ } else {
// device not set by user, get the default one
err = CA_GET(kAudioObjectSystemObject,
kAudioHardwarePropertyDefaultOutputDevice,
device);
CHECK_CA_ERROR("could not get default audio device");
- } else {
- *device = selection;
}
if (mp_msg_test(ao->log, MSGL_V)) {
diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h
index 0ef84c3afa..17c60b93be 100644
--- a/audio/out/ao_coreaudio_utils.h
+++ b/audio/out/ao_coreaudio_utils.h
@@ -28,6 +28,9 @@
#define CA_CFSTR_ENCODING kCFStringEncodingASCII
+CFStringRef cfstr_from_cstr(char *str);
+char *cfstr_get_cstr(CFStringRef cfstr);
+
char *fourcc_repr(void *talloc_ctx, uint32_t code);
bool check_ca_st(struct ao *ao, int level, OSStatus code, const char *message);