+static av_cold int get_channel_label(int channel)
+{
+ uint64_t map = 1 << channel;
+ if (map <= AV_CH_LOW_FREQUENCY)
+ return channel + 1;
+ else if (map <= AV_CH_BACK_RIGHT)
+ return channel + 29;
+ else if (map <= AV_CH_BACK_CENTER)
+ return channel - 1;
+ else if (map <= AV_CH_SIDE_RIGHT)
+ return channel - 4;
+ else if (map <= AV_CH_TOP_BACK_RIGHT)
+ return channel + 1;
+ else if (map <= AV_CH_STEREO_RIGHT)
+ return -1;
+ else if (map <= AV_CH_WIDE_RIGHT)
+ return channel + 4;
+ else if (map <= AV_CH_SURROUND_DIRECT_RIGHT)
+ return channel - 23;
+ else if (map == AV_CH_LOW_FREQUENCY_2)
+ return kAudioChannelLabel_LFE2;
+ else
+ return -1;
+}
+
+static int remap_layout(AudioChannelLayout *layout, uint64_t in_layout, int count)
+{
+ int i;
+ int c = 0;
+ layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+ layout->mNumberChannelDescriptions = count;
+ for (i = 0; i < count; i++) {
+ int label;
+ while (!(in_layout & (1 << c)) && c < 64)
+ c++;
+ if (c == 64)
+ return AVERROR(EINVAL); // This should never happen
+ label = get_channel_label(c);
+ layout->mChannelDescriptions[i].mChannelLabel = label;
+ if (label < 0)
+ return AVERROR(EINVAL);
+ c++;
+ }
+ return 0;
+}
+
+static int get_aac_tag(uint64_t in_layout)
+{
+ switch (in_layout) {
+ case AV_CH_LAYOUT_MONO:
+ return kAudioChannelLayoutTag_Mono;
+ case AV_CH_LAYOUT_STEREO:
+ return kAudioChannelLayoutTag_Stereo;
+ case AV_CH_LAYOUT_QUAD:
+ return kAudioChannelLayoutTag_AAC_Quadraphonic;
+ case AV_CH_LAYOUT_OCTAGONAL:
+ return kAudioChannelLayoutTag_AAC_Octagonal;
+ case AV_CH_LAYOUT_SURROUND:
+ return kAudioChannelLayoutTag_AAC_3_0;
+ case AV_CH_LAYOUT_4POINT0:
+ return kAudioChannelLayoutTag_AAC_4_0;
+ case AV_CH_LAYOUT_5POINT0:
+ return kAudioChannelLayoutTag_AAC_5_0;
+ case AV_CH_LAYOUT_5POINT1:
+ return kAudioChannelLayoutTag_AAC_5_1;
+ case AV_CH_LAYOUT_6POINT0:
+ return kAudioChannelLayoutTag_AAC_6_0;
+ case AV_CH_LAYOUT_6POINT1:
+ return kAudioChannelLayoutTag_AAC_6_1;
+ case AV_CH_LAYOUT_7POINT0:
+ return kAudioChannelLayoutTag_AAC_7_0;
+ case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
+ return kAudioChannelLayoutTag_AAC_7_1;
+ case AV_CH_LAYOUT_7POINT1:
+ return kAudioChannelLayoutTag_MPEG_7_1_C;
+ default:
+ return 0;
+ }
+}
+