summaryrefslogtreecommitdiffstats
path: root/audio/out
diff options
context:
space:
mode:
Diffstat (limited to 'audio/out')
-rw-r--r--audio/out/ao_coreaudio.c99
-rw-r--r--audio/out/ao_coreaudio_utils.c81
-rw-r--r--audio/out/ao_coreaudio_utils.h7
3 files changed, 96 insertions, 91 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 48fc3a4779..ee0a042d2a 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -306,96 +306,18 @@ static int init(struct ao *ao, char *params)
}
if (!supports_digital) {
- uint32_t size;
- AudioObjectPropertyAddress p_addr = (AudioObjectPropertyAddress) {
- .mSelector = kAudioDevicePropertyPreferredChannelLayout,
- .mScope = kAudioDevicePropertyScopeOutput,
- .mElement = kAudioObjectPropertyElementMaster,
- };
-
- err = AudioObjectGetPropertyDataSize(selected_device, &p_addr, 0, NULL,
- &size);
- CHECK_CA_ERROR("could not get audio device prefered layouts size");
- size_t n_layouts = size / sizeof(AudioChannelLayout);
-
- AudioChannelLayout *layouts = (AudioChannelLayout *) malloc(size);
- err = AudioObjectGetPropertyData(selected_device, &p_addr, 0, NULL,
- &size, layouts);
+ AudioChannelLayout *layouts;
+ size_t n_layouts;
+ err = CA_GET_ARY_O(selected_device,
+ kAudioDevicePropertyPreferredChannelLayout,
+ &layouts, &n_layouts);
CHECK_CA_ERROR("could not get audio device prefered layouts");
- uint32_t bitmaps[n_layouts];
- size_t n_bitmaps = 0;
-
- for (int i=0; i < n_layouts; i++) {
- ca_msg(MSGL_WARN, "channel layout %d:\n", i);
-
- switch (layouts[i].mChannelLayoutTag) {
- case kAudioChannelLayoutTag_UseChannelBitmap:
- // This is the best case. CoreAudio's representation of the
- // layout is the same of what mpv uses internally.
- ca_msg(MSGL_WARN, "channel layout !\n");
- bitmaps[n_bitmaps++] = layouts[i].mChannelBitmap;
- case kAudioChannelLayoutTag_UseChannelDescriptions: {
- // If the channel layout uses channel descriptions, from my
- // exepriments there are there three possibile cases:
- // * The description has a label kAudioChannelLabel_Unknown:
- // Can't do anything about this (looks like non surround
- // layouts are like this).
- // * The description uses positional information: this in
- // theory could be used but one would have to map spatial
- // positions to labels which is not really feasible.
- // * The description has a well known label which can be mapped
- // to the waveextensible definition: this is the kind of
- // descriptions we process here.
- ca_msg(MSGL_WARN, "descriptions!\n");
- size_t ch_num = layouts[i].mNumberChannelDescriptions;
-
- uint32_t bitmap = 0;
- bool all_channels_valid = true;
-
- for (int j=0; j < ch_num && all_channels_valid; j++) {
- AudioChannelLabel label =
- layouts[i].mChannelDescriptions[j].mChannelLabel;
-
- if (label == kAudioChannelLabel_UseCoordinates ||
- label == kAudioChannelLabel_Unknown ||
- label > kAudioChannelLabel_TopBackRight) {
- ca_msg(MSGL_WARN,
- "channel label=%d unusable to build channel "
- "bitmap, skipping layout\n", label);
- all_channels_valid = false;
- } else {
- bitmap |= 1ULL << (label - 1);
- }
- }
-
- if (all_channels_valid)
- bitmaps[n_bitmaps++] = bitmap;
+ uint32_t *bitmaps;
+ size_t n_bitmaps;
- break;
- }
- default: {
- ca_msg(MSGL_WARN, "some tag!\n");
- // This layout is defined exclusively by it's tag. Use the Audio
- // Format Services API to try and convert it to a bitmap that
- // mpv can use.
- uint32_t bitmap;
- uint32_t bitmap_size = sizeof(uint32_t);
- AudioChannelLayoutTag tag = layouts[i].mChannelLayoutTag;
- err = AudioFormatGetProperty(
- kAudioFormatProperty_BitmapForLayoutTag,
- sizeof(AudioChannelLayoutTag), &tag,
- &bitmap_size, &bitmap);
- if (err != noErr) {
- ca_msg(MSGL_WARN,
- "channel layout tag=%d unusable to build channel "
- "bitmap, skipping layout\n", tag);
- } else {
- bitmaps[n_bitmaps++] = bitmap;
- }
- }
- }
- } // closes for
+ ca_bitmaps_from_layouts(layouts, n_layouts, &bitmaps, &n_bitmaps);
+ free(layouts);
struct mp_chmap_sel chmap_sel = {0};
@@ -405,6 +327,8 @@ static int init(struct ao *ao, char *params)
mp_chmap_sel_add_map(&chmap_sel, &chmap);
}
+ talloc_free(bitmaps);
+
if (ao->channels.num < 3 || n_bitmaps < 1)
// If the input is not surround or we could not get any usable
// bitmap from the hardware, default to waveext...
@@ -413,7 +337,6 @@ static int init(struct ao *ao, char *params)
if (!ao_chmap_sel_adjust(ao, &chmap_sel, &ao->channels))
goto coreaudio_error;
- free(layouts);
} // closes if (!supports_digital)
// Build ASBD for the input format
diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c
index 221aeb4ddb..195d285b3e 100644
--- a/audio/out/ao_coreaudio_utils.c
+++ b/audio/out/ao_coreaudio_utils.c
@@ -340,3 +340,84 @@ bool ca_change_format(AudioStreamID stream,
return format_set;
}
+
+void ca_bitmaps_from_layouts(AudioChannelLayout *layouts, size_t n_layouts,
+ uint32_t **bitmaps, size_t *n_bitmaps)
+{
+ *n_bitmaps = 0;
+ *bitmaps = talloc_array_size(NULL, sizeof(uint32_t), n_layouts);
+
+ for (int i=0; i < n_layouts; i++) {
+ uint32_t bitmap = 0;
+
+ switch (layouts[i].mChannelLayoutTag) {
+ case kAudioChannelLayoutTag_UseChannelBitmap:
+ (*bitmaps)[(*n_bitmaps)++] = layouts[i].mChannelBitmap;
+ break;
+
+ case kAudioChannelLayoutTag_UseChannelDescriptions:
+ if (ca_bitmap_from_ch_desc(&layouts[i], &bitmap))
+ (*bitmaps)[(*n_bitmaps)++] = bitmap;
+ break;
+
+ default:
+ if (ca_bitmap_from_ch_tag(&layouts[i], &bitmap))
+ (*bitmaps)[(*n_bitmaps)++] = bitmap;
+ }
+ }
+}
+
+bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap)
+{
+ // If the channel layout uses channel descriptions, from my
+ // exepriments there are there three possibile cases:
+ // * The description has a label kAudioChannelLabel_Unknown:
+ // Can't do anything about this (looks like non surround
+ // layouts are like this).
+ // * The description uses positional information: this in
+ // theory could be used but one would have to map spatial
+ // positions to labels which is not really feasible.
+ // * The description has a well known label which can be mapped
+ // to the waveextensible definition: this is the kind of
+ // descriptions we process here.
+ size_t ch_num = layout->mNumberChannelDescriptions;
+ bool all_channels_valid = true;
+
+ for (int j=0; j < ch_num && all_channels_valid; j++) {
+ AudioChannelLabel label = layout->mChannelDescriptions[j].mChannelLabel;
+ if (label == kAudioChannelLabel_UseCoordinates ||
+ label == kAudioChannelLabel_Unknown ||
+ label > kAudioChannelLabel_TopBackRight) {
+ ca_msg(MSGL_WARN,
+ "channel label=%d unusable to build channel "
+ "bitmap, skipping layout\n", label);
+ all_channels_valid = false;
+ } else {
+ *bitmap |= 1ULL << (label - 1);
+ }
+ }
+
+ return all_channels_valid;
+}
+
+bool ca_bitmap_from_ch_tag(AudioChannelLayout *layout, uint32_t *bitmap)
+{
+ // This layout is defined exclusively by it's tag. Use the Audio
+ // Format Services API to try and convert it to a bitmap that
+ // mpv can use.
+ uint32_t bitmap_size = sizeof(uint32_t);
+
+ AudioChannelLayoutTag tag = layout->mChannelLayoutTag;
+ OSStatus err = AudioFormatGetProperty(
+ kAudioFormatProperty_BitmapForLayoutTag,
+ sizeof(AudioChannelLayoutTag), &tag,
+ &bitmap_size, bitmap);
+ if (err != noErr) {
+ ca_msg(MSGL_WARN,
+ "channel layout tag=%d unusable to build channel "
+ "bitmap, skipping layout\n", tag);
+ return false;
+ } else {
+ return true;
+ }
+}
diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h
index b7f261088b..78e524fbd8 100644
--- a/audio/out/ao_coreaudio_utils.h
+++ b/audio/out/ao_coreaudio_utils.h
@@ -70,8 +70,9 @@ OSStatus ca_disable_device_listener(AudioDeviceID device, void *flag);
bool ca_change_format(AudioStreamID stream,
AudioStreamBasicDescription change_format);
-bool ca_bitmap_from_ch_descriptions(AudioChannelLayout layout,
- uint32_t *bitmap);
-bool ca_bitmap_from_ch_tag(AudioChannelLayout layout, uint32_t *bitmap);
+bool ca_bitmap_from_ch_desc(AudioChannelLayout *layout, uint32_t *bitmap);
+bool ca_bitmap_from_ch_tag(AudioChannelLayout *layout, uint32_t *bitmap);
+void ca_bitmaps_from_layouts(AudioChannelLayout *layouts, size_t n_layouts,
+ uint32_t **bitmaps, size_t *n_bitmaps);
#endif /* MPV_COREAUDIO_UTILS_H */