static bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, struct mp_chmap *chmap) { void *talloc_ctx = talloc_new(NULL); MP_VERBOSE(ao, "input channel layout:\n"); ca_log_layout(ao, MSGL_V, layout); AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout); if (!l) goto coreaudio_error; if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) { MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n", (unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS); return false; } chmap->num = l->mNumberChannelDescriptions; for (int n = 0; n < l->mNumberChannelDescriptions; n++) { AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel; int speaker = ca_label_to_mp_speaker_id(label); if (speaker < 0) { MP_VERBOSE(ao, "channel label=%u unusable to build channel " "bitmap, skipping layout\n", (unsigned) label); goto coreaudio_error; } chmap->speaker[n] = speaker; } // Remap weird 7.1(rear) layouts correctly. replace_submap(chmap, CHMAP(6, FL, FR, BL, BR, SDL, SDR), CHMAP(6, FL, FR, SL, SR, BL, BR)); talloc_free(talloc_ctx); MP_VERBOSE(ao, "mp chmap: %s\n", mp_chmap_to_str(chmap)); return mp_chmap_is_valid(chmap) && !mp_chmap_is_unknown(chmap); coreaudio_error: MP_VERBOSE(ao, "converted input channel layout (failed):\n"); ca_log_layout(ao, MSGL_V, layout); talloc_free(talloc_ctx); return false; }
static bool ca_layout_to_mp_chmap(struct ao *ao, AudioChannelLayout *layout, struct mp_chmap *chmap) { void *talloc_ctx = talloc_new(NULL); MP_DBG(ao, "input channel layout:\n"); ca_log_layout(ao, MSGL_DEBUG, layout); AudioChannelLayout *l = ca_layout_to_custom_layout(ao, talloc_ctx, layout); if (!l) goto coreaudio_error; MP_VERBOSE(ao, "converted input channel layout:\n"); ca_log_layout(ao, MSGL_V, l); if (l->mNumberChannelDescriptions > MP_NUM_CHANNELS) { MP_VERBOSE(ao, "layout has too many descriptions (%u, max: %d)\n", (unsigned) l->mNumberChannelDescriptions, MP_NUM_CHANNELS); return false; } for (int n = 0; n < l->mNumberChannelDescriptions; n++) { AudioChannelLabel label = l->mChannelDescriptions[n].mChannelLabel; int speaker = ca_label_to_mp_speaker_id(label); if (speaker < 0) { MP_VERBOSE(ao, "channel label=%u unusable to build channel " "bitmap, skipping layout\n", (unsigned) label); goto coreaudio_error; } else { chmap->speaker[n] = speaker; chmap->num = n + 1; } } talloc_free(talloc_ctx); return chmap->num > 0; coreaudio_error: MP_VERBOSE(ao, "converted input channel layout (failed):\n"); ca_log_layout(ao, MSGL_V, layout); talloc_free(talloc_ctx); return false; }
static AudioChannelLayout *ca_layout_to_custom_layout(struct ao *ao, void *talloc_ctx, AudioChannelLayout *l) { AudioChannelLayoutTag tag = l->mChannelLayoutTag; AudioChannelLayout *r; OSStatus err; if (tag == kAudioChannelLayoutTag_UseChannelDescriptions) return l; if (tag == kAudioChannelLayoutTag_UseChannelBitmap) { uint32_t psize; err = AudioFormatGetPropertyInfo( kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(uint32_t), &l->mChannelBitmap, &psize); CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (info)"); r = talloc_size(NULL, psize); err = AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForBitmap, sizeof(uint32_t), &l->mChannelBitmap, &psize, r); CHECK_CA_ERROR("failed to convert channel bitmap to descriptions (get)"); } else { uint32_t psize; err = AudioFormatGetPropertyInfo( kAudioFormatProperty_ChannelLayoutForTag, sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize); r = talloc_size(NULL, psize); CHECK_CA_ERROR("failed to convert channel tag to descriptions (info)"); err = AudioFormatGetProperty( kAudioFormatProperty_ChannelLayoutForTag, sizeof(AudioChannelLayoutTag), &l->mChannelLayoutTag, &psize, r); CHECK_CA_ERROR("failed to convert channel tag to descriptions (get)"); } MP_VERBOSE(ao, "converted input channel layout:\n"); ca_log_layout(ao, MSGL_V, l); return r; coreaudio_error: return NULL; }