From patchwork Wed Oct 24 20:03:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pkv.stream" X-Patchwork-Id: 10772 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id D6E5644B632 for ; Wed, 24 Oct 2018 23:03:46 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4CBA7680506; Wed, 24 Oct 2018 23:03:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com [209.85.128.48]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5207C680249 for ; Wed, 24 Oct 2018 23:03:12 +0300 (EEST) Received: by mail-wm1-f48.google.com with SMTP id p2-v6so3385863wmc.2 for ; Wed, 24 Oct 2018 13:03:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=ybO9R9jOuccwimGw+Vlr6lr0blGJTc8otNzjsPl9JIQ=; b=rX/UCqxfJSpS+MEJlM/ij9glW4VcITL6c+jNb5Ge0i0ssX9JrqYkDc2NNNOXv5kyJI Hn6E033QJbdEeCWVEN7P6ge2Rj1QJeFlU29fr5Ffs2omZzvFwI011Mvxo3w1VsOVR1Pw vZqVlEnsB5xycX1U+/85r9n3fF8tcIqMWYiNQ22Dx+FilC5cHffI6lBUApXFUhoNRlUt Y0HcxH8eW81VULMX6PuDmdwJI7i7Z5euO6cZqXnbwse22dKPxYtxVFMTFWRuQcvoZ0JA boODmcW75igD0pjJe3BRPnXFRBLm/9ZBTPz2v9Ay/z6MfgLT7/aR7TLNlkOIbERYqn/S q9RA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=ybO9R9jOuccwimGw+Vlr6lr0blGJTc8otNzjsPl9JIQ=; b=TV455pSFYIKbbTbtwZ7mg1Oo7AUOLf2d4/utcilgxFl7/HUByitcECHvqHOn/uiS7U ozW//cg0cChNSaEjZS6oPHuSSVX1OIeoWYuzuLa8FGPXqpnoWBbWcuaR5p0A13TvjOCd KgtbTZmSOlvvzWMy7je1iUh1MHdbI7WDLwqOg+SgqtLOlOXprJAq43bTkZUFGwePPFuW trb2K5XFaEHFsp7acmxKxX5Lnddf/DxtCJaCrdafE81DI7jpQ3ScfB9t9xtvHDCRKfdp 8Gr0if8IRrcWXJFLjtOU5KYqrpir4/5XjtSov3EVaKfrhOk4n1d+jV72KbMiN9w+rGL7 rB5g== X-Gm-Message-State: AGRZ1gKP7rgJdEsf65eh3ZQdTATyiMhHAlkpa+EMJuadYR/7AGteE+Ro mFL7fMduCT6pZY00j/XYrd6idh37 X-Google-Smtp-Source: AJdET5ep/dJ0GnCgb/UJnU+VYQ3qthnHkIQbJ8WnTJ+x4u7+TX28F9iu7o/fsL8dqgPfMzMVplSg4g== X-Received: by 2002:a1c:3795:: with SMTP id e143-v6mr4327921wma.9.1540411420308; Wed, 24 Oct 2018 13:03:40 -0700 (PDT) Received: from [192.168.0.101] (176-159-7-188.abo.bbox.fr. [176.159.7.188]) by smtp.googlemail.com with ESMTPSA id g76-v6sm6531685wmd.25.2018.10.24.13.03.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 24 Oct 2018 13:03:39 -0700 (PDT) To: ffmpeg-devel@ffmpeg.org From: "pkv.stream" Message-ID: <665f9e88-1c11-c4f1-8c94-a78321ead798@gmail.com> Date: Wed, 24 Oct 2018 22:03:35 +0200 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.2.1 MIME-Version: 1.0 Content-Language: fr Subject: [FFmpeg-devel] [PATCH v3 3/3] avcodec/aacdec: Translate PCE to avutil channel layouts X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 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 --- 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 +#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 */