summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/out/ao_coreaudio.c17
-rw-r--r--audio/out/ao_coreaudio_utils.c121
-rw-r--r--audio/out/ao_coreaudio_utils.h5
3 files changed, 54 insertions, 89 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index e8b0179d20..9407d5f562 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -303,23 +303,16 @@ static int init(struct ao *ao)
&layouts, &n_layouts);
CHECK_CA_ERROR("could not get audio device prefered layouts");
- uint32_t *bitmaps;
- size_t n_bitmaps;
-
- ca_bitmaps_from_layouts(ao, layouts, n_layouts, &bitmaps, &n_bitmaps);
- talloc_free(layouts);
-
struct mp_chmap_sel chmap_sel = {0};
-
- for (int i=0; i < n_bitmaps; i++) {
+ for (int i = 0; i < n_layouts; i++) {
struct mp_chmap chmap = {0};
- mp_chmap_from_lavc(&chmap, bitmaps[i]);
- mp_chmap_sel_add_map(&chmap_sel, &chmap);
+ if (ca_layout_to_mp_chmap(ao, &layouts[i], &chmap))
+ mp_chmap_sel_add_map(&chmap_sel, &chmap);
}
- talloc_free(bitmaps);
+ talloc_free(layouts);
- if (ao->channels.num < 3 || n_bitmaps < 1)
+ if (ao->channels.num < 3)
// If the input is not surround or we could not get any usable
// bitmap from the hardware, default to waveext...
mp_chmap_sel_add_waveext(&chmap_sel);
diff --git a/audio/out/ao_coreaudio_utils.c b/audio/out/ao_coreaudio_utils.c
index 8c3b0dca1d..71b97ff8fa 100644
--- a/audio/out/ao_coreaudio_utils.c
+++ b/audio/out/ao_coreaudio_utils.c
@@ -377,60 +377,6 @@ static int ca_label_to_mp_speaker_id(AudioChannelLabel label)
return -1;
}
-static bool ca_bitmap_from_ch_desc(struct ao *ao, 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;
- const int mp_speaker_id = ca_label_to_mp_speaker_id(label);
- if (mp_speaker_id < 0) {
- MP_VERBOSE(ao, "channel label=%d unusable to build channel "
- "bitmap, skipping layout\n", label);
- all_channels_valid = false;
- } else {
- *bitmap |= 1ULL << mp_speaker_id;
- }
- }
-
- return all_channels_valid;
-}
-
-static bool ca_bitmap_from_ch_tag(struct ao *ao, 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) {
- MP_VERBOSE(ao, "channel layout tag=%d unusable to build channel "
- "bitmap, skipping layout\n", tag);
- return false;
- } else {
- return true;
- }
-}
-
static void ca_log_layout(struct ao *ao, AudioChannelLayout *layout)
{
if (!mp_msg_test(ao->log, MSGL_V))
@@ -457,30 +403,57 @@ static void ca_log_layout(struct ao *ao, AudioChannelLayout *layout)
}
}
-void ca_bitmaps_from_layouts(struct ao *ao,
- AudioChannelLayout *layouts, size_t n_layouts,
- uint32_t **bitmaps, size_t *n_bitmaps)
+bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
+ struct mp_chmap *chmap)
{
- *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;
- ca_log_layout(ao, &layouts[i]);
+ AudioChannelLayoutTag tag = layout->mChannelLayoutTag;
+ uint32_t layout_size = sizeof(layout);
+ OSStatus err;
+
+ if (tag == kAudioChannelLayoutTag_UseChannelBitmap) {
+ err = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForBitmap,
+ sizeof(uint32_t),
+ &layout->mChannelBitmap,
+ &layout_size,
+ layout);
+ CHECK_CA_ERROR("failed to convert channel bitmap to descriptions");
+ } else if (tag != kAudioChannelLayoutTag_UseChannelDescriptions) {
+ err = AudioFormatGetProperty(kAudioFormatProperty_ChannelLayoutForTag,
+ sizeof(AudioChannelLayoutTag),
+ &layout->mChannelLayoutTag,
+ &layout_size,
+ layout);
+ CHECK_CA_ERROR("failed to convert channel tag to descriptions");
+ }
- switch (layouts[i].mChannelLayoutTag) {
- case kAudioChannelLayoutTag_UseChannelBitmap:
- (*bitmaps)[(*n_bitmaps)++] = layouts[i].mChannelBitmap;
- break;
+ ca_log_layout(ao, layout);
- case kAudioChannelLayoutTag_UseChannelDescriptions:
- if (ca_bitmap_from_ch_desc(ao, &layouts[i], &bitmap))
- (*bitmaps)[(*n_bitmaps)++] = bitmap;
- break;
+ // If the channel layout uses channel descriptions, from my
+ // experiments 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.
- default:
- if (ca_bitmap_from_ch_tag(ao, &layouts[i], &bitmap))
- (*bitmaps)[(*n_bitmaps)++] = bitmap;
+ for (int n = 0; n < layout->mNumberChannelDescriptions; n++) {
+ AudioChannelLabel label = layout->mChannelDescriptions[n].mChannelLabel;
+ uint8_t speaker = ca_label_to_mp_speaker_id(label);
+ if (speaker < 0) {
+ MP_VERBOSE(ao, "channel label=%d unusable to build channel "
+ "bitmap, skipping layout\n", label);
+ } else {
+ chmap->speaker[n] = speaker;
+ chmap->num = n + 1;
}
}
+
+ return chmap->num > 0;
+coreaudio_error:
+ ca_log_layout(ao, layout);
+ return false;
}
diff --git a/audio/out/ao_coreaudio_utils.h b/audio/out/ao_coreaudio_utils.h
index 0aca2f7c62..9218ccf00d 100644
--- a/audio/out/ao_coreaudio_utils.h
+++ b/audio/out/ao_coreaudio_utils.h
@@ -77,8 +77,7 @@ OSStatus ca_disable_device_listener(AudioDeviceID device, void *flag);
bool ca_change_format(struct ao *ao, AudioStreamID stream,
AudioStreamBasicDescription change_format);
-void ca_bitmaps_from_layouts(struct ao *ao,
- AudioChannelLayout *layouts, size_t n_layouts,
- uint32_t **bitmaps, size_t *n_bitmaps);
+bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout,
+ struct mp_chmap *chmap);
#endif /* MPV_COREAUDIO_UTILS_H */