Patch updated ; passes all FATE tests. Comments from Alex Converse review incorporated (much thanks to him).
From 168411206bc07d6a74097c52b3b88063591787ae Mon Sep 17 00:00:00 2001 From: pkviet <pkv.str...@gmail.com> Date: Wed, 24 Oct 2018 06:31:52 +0200 Subject: [PATCH 3/3] avcodec/aacdec: Translate pce to avutil channel_layout This commit makes additions to the capabilties of native aac decoder to translate pce to ffmpeg channel layouts. For all pce generated by the native aac encoder a table is used. For more general pce (up to 22 channels) a custom layout is built when chan_config == 0. Signed-off-by: pkviet <pkv.str...@gmail.com> --- libavcodec/aacdec_template.c | 229 ++++++++++++++++++++++++++++++++++++++++++- libavcodec/aacdectab.h | 126 ++++++++++++++++++++++++ 2 files changed, 351 insertions(+), 4 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index dce6035d67..c1748d3673 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -155,6 +155,34 @@ static av_cold int che_configure(AACContext *ac, return 0; } +static uint8_t *pce_reorder_map(uint64_t layout, int channels) +{ + if (layout == AV_CH_LAYOUT_7POINT1_WIDE || layout == AV_CH_LAYOUT_7POINT1 || + layout == AV_CH_LAYOUT_7POINT1_WIDE_BACK) + return aac_chan_maps[7]; + if (layout == AV_CH_LAYOUT_6POINT1 || layout == AV_CH_LAYOUT_6POINT1_BACK || + layout == AV_CH_LAYOUT_6POINT1_FRONT) + return aac_chan_maps[6]; + if (layout == AV_CH_LAYOUT_5POINT1 || layout == AV_CH_LAYOUT_5POINT1_BACK) + return aac_chan_maps[5]; + if (layout == AV_CH_LAYOUT_4POINT1 || layout == AV_CH_LAYOUT_5POINT0_BACK) + return aac_chan_maps[4]; + if (layout == AV_CH_LAYOUT_3POINT1 || layout == AV_CH_LAYOUT_4POINT0) + return aac_chan_maps[3]; + return normal_chan_maps[channels - 1]; +} + +static int has_CCE(AVCodecContext *avctx) +{ + AACContext *ac = avctx->priv_data; + int i; + for (i = 0; i < MAX_ELEM_ID * 4; i++) { + if (ac->oc[1].layout_map[i][0] == TYPE_CCE) + return 1; + } + return 0; +} + static int frame_configure_elements(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; @@ -180,10 +208,17 @@ static int frame_configure_elements(AVCodecContext *avctx) if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) return ret; + /* reorder channels in case pce table was used with LFE channel */ + uint8_t reorder[8] = {0, 1, 2, 3, 4, 5, 6, 7}; + if (ac->oc[1].m4ac.chan_config == 0 && avctx->channels < 9 + && avctx->channels > 4 && !has_CCE(avctx)) + memcpy(reorder, pce_reorder_map(ac->oc[1].channel_layout, avctx->channels), + avctx->channels * sizeof(uint8_t)); /* map output channel pointers to AVFrame data */ for (ch = 0; ch < avctx->channels; ch++) { + int ch_remapped = avctx->channels < 9 ? reorder[ch] : ch; if (ac->output_element[ch]) - ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch]; + ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch_remapped]; } return 0; @@ -257,13 +292,193 @@ static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos, return num_pos_channels; } -static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) +static int count_channels_per_type(uint8_t (*layout_map)[3], int tags, int pos, enum RawDataBlockType type) +{ + int num_pos_channels = 0; + int i; + for (i = 0; i < tags; i++) { + if (layout_map[i][2] != pos) + continue; + if (layout_map[i][0] == type) { + if (type == TYPE_CPE) + num_pos_channels += 2; + if (type == TYPE_SCE || type == TYPE_LFE || type == TYPE_CCE) // used to detect CCE + num_pos_channels += 1; + } + } + + return num_pos_channels; +} + +static uint64_t convert_layout_map_to_av_layout(uint8_t layout_map[MAX_ELEM_ID * 4][3]) +{ + int i, config; + config = 0; + // look up pce table for channel layout correspondence used by native encoder and decoder + for (i = 1; i < PCE_LAYOUT_NBR; i++) { + if (memcmp(layout_map, pce_channel_layout_map[i], sizeof(uint8_t) * 3 * PCE_MAX_TAG) == 0) { + config = i; + break; + } + } + return pce_channel_layout_list[config]; +} + +static uint64_t sniff_channel_order(AACContext *ac, uint8_t (*layout_map)[3], int tags) { int i, n, total_non_cc_elements; struct elem_to_channel e2c_vec[4 * MAX_ELEM_ID] = { { 0 } }; int num_front_channels, num_side_channels, num_back_channels; + int num_front_channels_SCE, num_front_channels_CPE, num_LFE_channels; + int num_side_channels_CPE, num_back_channels_SCE, num_back_channels_CPE; + int has_CCE_channels; + int channels; uint64_t layout; + num_front_channels_SCE = count_channels_per_type(layout_map, tags, AAC_CHANNEL_FRONT, TYPE_SCE); + num_back_channels_SCE = count_channels_per_type(layout_map, tags, AAC_CHANNEL_BACK, TYPE_SCE); + num_front_channels_CPE = count_channels_per_type(layout_map, tags, AAC_CHANNEL_FRONT, TYPE_CPE); + num_side_channels_CPE = count_channels_per_type(layout_map, tags, AAC_CHANNEL_SIDE, TYPE_CPE); + num_back_channels_CPE = count_channels_per_type(layout_map, tags, AAC_CHANNEL_BACK, TYPE_CPE); + num_LFE_channels = count_channels_per_type(layout_map, tags, AAC_CHANNEL_LFE, TYPE_LFE); + has_CCE_channels = count_channels_per_type(layout_map, tags, AAC_CHANNEL_CC, TYPE_CCE); + channels = num_front_channels_SCE + num_back_channels_SCE + num_LFE_channels + num_front_channels_CPE + + num_side_channels_CPE + num_back_channels_CPE; + if (ac->oc[1].m4ac.chan_config == 0 && !has_CCE_channels) { + layout = 0; + // first use table to find layout + if (PCE_MAX_TAG >= tags) + layout = convert_layout_map_to_av_layout(layout_map); + if (layout > 0) { + char buf[64]; + av_get_channel_layout_string(buf, sizeof(buf), -1, layout); + av_log(ac->avctx, AV_LOG_WARNING, "Using PCE table: channel layout " + "decoded as %s (%#llx)\n", buf, layout); + return layout; + } + /* Build a custom layout directly from pce (CC elements are not taken into account). + * Channel_layout.h lists up to 24 indivudal channel masks of which we use + * 22, discounting AV_CH_STEREO_LEFT and AV_CH_STEREO_RIGHT + */ + if (channels > 22) + goto fallback; + switch (num_LFE_channels) { + case 1: + layout |= AV_CH_LOW_FREQUENCY; + break; + case 2: + layout |= AV_CH_LOW_FREQUENCY | AV_CH_LOW_FREQUENCY_2; + break; + case 0: + break; + default: + goto fallback; + } + switch (num_front_channels_SCE) { + case 1: + layout |= AV_CH_FRONT_CENTER; + break; + case 2: + layout |= AV_CH_FRONT_CENTER | AV_CH_TOP_FRONT_CENTER; + break; + case 0: + break; + default: + goto fallback; + } + switch (num_front_channels_CPE) { + case 2: + layout |= AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT; + break; + case 4: + layout |= AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER; + break; + case 6: + layout |= AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | + AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT; + break; + case 0: + break; + default: + goto fallback; + } + switch (num_back_channels_SCE) { + case 1: + layout |= AV_CH_BACK_CENTER; + break; + case 2: + layout |= AV_CH_BACK_CENTER | AV_CH_TOP_BACK_CENTER; + break; + case 0: + break; + default: + goto fallback; + } + switch (num_back_channels_CPE) { + case 2: + layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT; + break; + case 4: + layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT; + break; + case 0: + break; + default: + goto fallback; + } + switch (num_side_channels_CPE) { + case 2: + layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT; + break; + case 4: + layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT; + break; + case 6: + layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT | + AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT; + case 0: + break; + default: + goto fallback; + } + // fix for layout 3.0 (reorders layout_map from [SCE, CPE] to [CPE, SCE]) + // because the table has the correspondence 'Front: [CPE, SCE]' to '3.0' + if (layout == AV_CH_LAYOUT_SURROUND) { + layout_map[0][0] = TYPE_CPE; + layout_map[0][1] = 0; + layout_map[0][2] = AAC_CHANNEL_FRONT; + layout_map[1][0] = TYPE_SCE; + layout_map[1][1] = 0; + layout_map[1][2] = AAC_CHANNEL_FRONT; + } + /* 'fix' for layout 0xcf (this is to be consistent with previous code, + * and fate-test, see 'fallback' below); this changes the channel ordering. + */ + if (layout == (AV_CH_LAYOUT_3POINT1 | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)) { + layout_map[0][0] = TYPE_CPE; + layout_map[0][1] = 1; + layout_map[0][2] = AAC_CHANNEL_FRONT; + layout_map[1][0] = TYPE_SCE; + layout_map[1][1] = 0; + layout_map[1][2] = AAC_CHANNEL_FRONT; + layout_map[2][0] = TYPE_LFE; + layout_map[2][1] = 0; + layout_map[2][2] = AAC_CHANNEL_LFE; + layout_map[3][0] = TYPE_CPE; + layout_map[3][1] = 0; + layout_map[3][2] = AAC_CHANNEL_FRONT; + } + if (layout) { + char buf[64]; + av_get_channel_layout_string(buf, sizeof(buf), -1, layout); + av_log(ac->avctx, AV_LOG_WARNING, "Decoding PCE: " + "using custom channel layout %s (%#llx)\n", buf, layout); + return layout; + } + } + +fallback: if (FF_ARRAY_ELEMS(e2c_vec) < tags) return 0; @@ -463,7 +678,7 @@ static int output_configure(AACContext *ac, // Try to sniff a reasonable channel order, otherwise output the // channels in the order the PCE declared them. if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) - layout = sniff_channel_order(layout_map, tags); + layout = sniff_channel_order(ac, layout_map, tags); for (i = 0; i < tags; i++) { int type = layout_map[i][0]; int id = layout_map[i][1]; @@ -738,7 +953,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc; int sampling_index; int comment_len; - int tags; + int i, j, tags; skip_bits(gb, 2); // object_type @@ -781,6 +996,12 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc); tags += num_cc; + /* zeroes layout_map beyond tags*/ + for (i = tags; i < MAX_ELEM_ID * 4; i++) { + for (j = 0; j < 3; j++) + layout_map[i][j] = 0; + } + relative_align_get_bits(gb, byte_align_ref); /* comment field, first byte is length */ diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index baf51a74bf..17df04469c 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -35,6 +35,7 @@ #include <stdint.h> +#define AAC_MAX_CHANNELS 8 static const int8_t tags_per_config[16] = { 0, 1, 1, 2, 3, 3, 4, 5, 0, 0, 0, 4, 5, 0, 5, 0 }; static const uint8_t aac_channel_layout_map[16][5][3] = { @@ -71,4 +72,129 @@ static const uint64_t aac_channel_layout[16] = { /* AV_CH_LAYOUT_7POINT1_TOP, */ }; +#define PCE_LAYOUT_NBR 35 +#define PCE_MAX_TAG 10 + +/* number of tags for the pce_channel_layout_map table */ +static const int8_t tags_pce_config[PCE_LAYOUT_NBR] = {0, 10, 9, 8, 7, 8, 7, 6, 6, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1}; + +static const uint8_t pce_channel_layout_map[PCE_LAYOUT_NBR][10][3] = { + { { 0, } }, + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_SIDE }, { TYPE_CPE, 4, AAC_CHANNEL_BACK }, { TYPE_CPE, 5, AAC_CHANNEL_BACK }, { TYPE_SCE, 2, AAC_CHANNEL_BACK }, { TYPE_SCE, 3, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_HEXADECAGONAL + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_SIDE }, { TYPE_CPE, 4, AAC_CHANNEL_BACK }, { TYPE_CPE, 5, AAC_CHANNEL_BACK }, { TYPE_SCE, 2, AAC_CHANNEL_BACK }, },// 0x3FF37, 15ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_SIDE }, { TYPE_CPE, 4, AAC_CHANNEL_BACK }, { TYPE_CPE, 5, AAC_CHANNEL_BACK }, },// 0x2FF37, 14ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_SIDE }, { TYPE_CPE, 4, AAC_CHANNEL_BACK }, { TYPE_CPE, 5, AAC_CHANNEL_BACK }, },// 0x17F37, 13ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_SCE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_BACK }, { TYPE_SCE, 3, AAC_CHANNEL_BACK }, },// 0x7F37, 12ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_SCE, 2, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_BACK }, },// 0x5F37, 11ch + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_SCE, 0, AAC_CHANNEL_SIDE }, { TYPE_CPE, 3, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },//0xFF3, 10ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_SCE, 2, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER , 9 ch + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_OCTAGONAL + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_7POINT1 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_7POINT1_WIDE + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_7POINT1_WIDE_BACK + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_6POINT1 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_6POINT1_BACK + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_CPE, 2, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_7POINT0 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, },//AV_CH_LAYOUT_7POINT0_FRONT + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_HEXAGONAL + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_6POINT1_FRONT + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_6POINT0 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_5POINT1 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_5POINT1_BACK + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_4POINT1 + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_FRONT }, { TYPE_CPE, 2, AAC_CHANNEL_SIDE }, },//AV_CH_LAYOUT_6POINT0_FRONT + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, },//AV_CH_LAYOUT_5POINT0 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_5POINT0_BACK + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_4POINT0 + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, },//AV_CH_LAYOUT_3POINT1 + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_BACK }, },//AV_CH_LAYOUT_QUAD + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 1, AAC_CHANNEL_SIDE }, },//AV_CH_LAYOUT_2_2 + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_LFE, 0, AAC_CHANNEL_LFE }, }, //AV_CH_LAYOUT_2POINT1 + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 0, AAC_CHANNEL_BACK }, }, //AV_CH_LAYOUT_2_1 + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, },//AV_CH_LAYOUT_SURROUND + { { TYPE_CPE, 0, AAC_CHANNEL_FRONT }, }, //AV_CH_LAYOUT_STEREO + { { TYPE_SCE, 0, AAC_CHANNEL_FRONT }, }, //AV_CH_LAYOUT_MONO +}; + +/* list of channel layouts supported by the pce encoder /decoder table */ +static const uint64_t pce_channel_layout_list[PCE_LAYOUT_NBR] = { + 0, + AV_CH_LAYOUT_HEXADECAGONAL, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | AV_CH_TOP_FRONT_LEFT | + AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_BACK_CENTER | + AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | AV_CH_TOP_FRONT_LEFT | + AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_BACK_LEFT | + AV_CH_TOP_BACK_RIGHT, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | AV_CH_TOP_FRONT_LEFT | + AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER | AV_CH_TOP_BACK_CENTER, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | AV_CH_TOP_FRONT_LEFT | + AV_CH_TOP_FRONT_RIGHT | AV_CH_TOP_FRONT_CENTER, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT, + AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER | AV_CH_BACK_LEFT | + AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER, + AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER, + AV_CH_LAYOUT_OCTAGONAL, + AV_CH_LAYOUT_7POINT1, + AV_CH_LAYOUT_7POINT1_WIDE, + AV_CH_LAYOUT_7POINT1_WIDE_BACK, + AV_CH_LAYOUT_6POINT1, + AV_CH_LAYOUT_6POINT1_BACK, + AV_CH_LAYOUT_7POINT0, + AV_CH_LAYOUT_7POINT0_FRONT, + AV_CH_LAYOUT_HEXAGONAL, + AV_CH_LAYOUT_6POINT1_FRONT, + AV_CH_LAYOUT_6POINT0, + AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_4POINT1, + AV_CH_LAYOUT_6POINT0_FRONT, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_3POINT1, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_2_2, + AV_CH_LAYOUT_2POINT1, + AV_CH_LAYOUT_2_1, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_MONO, +}; +/** + * Table to remap channels from libavcodec's default order to AAC order. + */ +static const uint8_t aac_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = { + {0}, + {0, 1}, + {2, 0, 1}, + {2, 0, 1, 3}, + {2, 0, 1, 3, 4}, + {2, 0, 1, 4, 5, 3}, + {2, 0, 1, 4, 5, 6, 3}, + {2, 0, 1, 6, 7, 4, 5, 3}, +}; + +static const uint8_t normal_chan_maps[AAC_MAX_CHANNELS][AAC_MAX_CHANNELS] = { + {0}, + {0, 1}, + {0, 1, 2}, + {0, 1, 2, 3}, + {0, 1, 2, 3, 4}, + {0, 1, 2, 3, 4, 5}, + {0, 1, 2, 3, 4, 5, 6}, + {0, 1, 2, 3, 4, 5, 6, 7}, +}; + +/* Supported layouts without using a PCE */ +static const int64_t aac_normal_chan_layouts[8] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_SURROUND, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1_BACK, + 0, + AV_CH_LAYOUT_7POINT1, +}; #endif /* AVCODEC_AACDECTAB_H */ -- 2.16.2.windows.1
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel