summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-07-08 22:58:01 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2013-07-22 21:53:18 +0200
commitc2de6fdf345b72a0f69f9b4b9618599a7287c2c8 (patch)
tree71a51819855eab90a1d5c2965893da0d7f26ab5a
parent9652245ef0432143433da57e0563f0a69471965b (diff)
downloadmpv-c2de6fdf345b72a0f69f9b4b9618599a7287c2c8.tar.bz2
mpv-c2de6fdf345b72a0f69f9b4b9618599a7287c2c8.tar.xz
ao_coreaudio: set channel layout based on hardware query
this is a wip
-rw-r--r--audio/out/ao_coreaudio.c108
1 files changed, 106 insertions, 2 deletions
diff --git a/audio/out/ao_coreaudio.c b/audio/out/ao_coreaudio.c
index 65e51bce7d..6c1cdb9150 100644
--- a/audio/out/ao_coreaudio.c
+++ b/audio/out/ao_coreaudio.c
@@ -313,11 +313,115 @@ 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);
+ 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;
+
+ 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
+
struct mp_chmap_sel chmap_sel = {0};
- mp_chmap_sel_add_waveext(&chmap_sel);
+
+ for (int i=0; i < n_bitmaps; i++) {
+ struct mp_chmap chmap = {0};
+ mp_chmap_from_lavc(&chmap, bitmaps[i]);
+ mp_chmap_sel_add_map(&chmap_sel, &chmap);
+ }
+
+ if (n_bitmaps < 1)
+ // Could not get from the hardware any usable bitmap, default to
+ // waveext...
+ mp_chmap_sel_add_waveext(&chmap_sel);
+
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
AudioStreamBasicDescription asbd;