diff options
-rw-r--r-- | audio/out/ao_coreaudio.c | 17 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.c | 121 | ||||
-rw-r--r-- | audio/out/ao_coreaudio_utils.h | 5 |
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 */ |