From c11c744998a28d582ec9d6139f2bf6c927000e3a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 10 Jul 2013 19:24:28 +0200 Subject: ao_coreaudio: refactor chmap detection b2f9e0610 introduced this functionality with code that was quite 'monolithic'. Split the functionality over several functions and ose the new macros to get array properties. --- audio/out/ao_coreaudio_utils.c | 81 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'audio/out/ao_coreaudio_utils.c') 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; + } +} -- cgit v1.2.3