From patchwork Sun Oct 21 23:47:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pkv.stream" X-Patchwork-Id: 10741 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 2129B449398 for ; Mon, 22 Oct 2018 02:47:51 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7745668A66B; Mon, 22 Oct 2018 02:47:32 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BC93568A4F5 for ; Mon, 22 Oct 2018 02:47:26 +0300 (EEST) Received: by mail-wm1-f43.google.com with SMTP id 206-v6so8414807wmb.5 for ; Sun, 21 Oct 2018 16:47:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=1rP0Vy8YCLl3seUDWS0F63ofibHLmUlOZiQgmA0jHoA=; b=Y3KStoZqykbCdNo4GyEgtEMfGvEvdUM0/0ehxXidhaqzXdF6/Q9OuFzuuz4+uhtTDN dUJ1SoxjIbWimewQW+cC5TsF13Gs+U68B5yBiVu0Et+I6Z3MXEEvLvmVQUkZk9zAbMBb pADhfRJPTTy1uud/nFRnowpaQY9Z4Hh79kZomxoLGs1WGlPbNwFXceQmukgqiFLcKoY5 3pYQ6ynQIVvF5JvhXZsmDax6IBQC2fXF+0wrEdYRezhQjyMEhjz1JIGnvAVKCm6juvvh Uh6IYoWVLpGd7LnHQt6WFucL20TGxoFg4tRvzZL7xj2xG/jJcsE0EhScLnl9tyoPuSHe SncQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=1rP0Vy8YCLl3seUDWS0F63ofibHLmUlOZiQgmA0jHoA=; b=rDTBmVoSFjcrDZkK0pL3EJ5h+R/ftUfJUXcuNi5f8yVJDZbI0sUhB2dt9UVgYHAacS ZoXfl5HtmEy4b9QlxJT41IGaWTR2AzeBAJafwtRZlZj12zE2hC/sGRG6+FrnBFzOX3Xm xhpCemBuKuMWaKUks1v0MptrS0Y68uJnWXfUbDD1PoO0qo1AwAXQGO/bV+ysPZgukhqb HqJkDpK0iCATDdLhRwKcW18QTH7ezM6tmcbTk4NcjXOZS8f1BJo7Edx7HuzfrN5EUUMX wRfD76P26wL9XwkWjp1fd6yr0WXEjlg/Mfe28oJaaTjAlJhxDqU65aY76ugznZv1Okst vMLw== X-Gm-Message-State: ABuFfojTezrn6JC6Z6ta6msK3wZYShuEZAu6EGXlMyUX7iuPxzy2Otmm kDjfrU07uoTI1rBxEdnByN5RzL9h X-Google-Smtp-Source: ACcGV63x4Z3fLEeOw0/tV7ARSYNW5hcNSi3Tis89Rha4/6VkOPJtdw4z2+B1o9wPifOs+nHv5iaxdQ== X-Received: by 2002:a1c:8d83:: with SMTP id p125-v6mr13899360wmd.61.1540165673407; Sun, 21 Oct 2018 16:47:53 -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 u9-v6sm27456383wrr.66.2018.10.21.16.47.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 21 Oct 2018 16:47:52 -0700 (PDT) From: "pkv.stream" To: ffmpeg-devel@ffmpeg.org Message-ID: Date: Mon, 22 Oct 2018 01:47:47 +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 X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: [FFmpeg-devel] [PATCH v2 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" (commit message changed to include number of trac tricket solved) For context , search for the discussion: aacenc: remove unsupported PCE mappings Additional details: the aac decoder decodes PCE correctly but since avutil channel layouts are obviously not part of the spec there is no pre-defined one to one correspondance between ffmpeg channel layouts and any PCE. At the moment the decoder makes educated guesses for translating PCE to avutil layouts. In the case of PCE written by the native aac encoder, there exists a correspondence though of avutil channel layouts to PCE. The patch adds that table to the decoder; for PCE which are not in the table, the patch adds an algo to assign a ffmpeg layout. The patch was tested extensively for all channel layouts in PCE table which include all the channel layouts in channel-layout.h (ln 85 - 111), (except AV_CH_LAYOUT_STEREO_DOWNMIX ) From a12637c97c3140a1676f20b19c91647313379b39 Mon Sep 17 00:00:00 2001 From: pkviet Date: Sun, 9 Sep 2018 16:47:32 +0200 Subject: [PATCH 3/3] avcodec/aacdec: Translate pce to avutil channel_layout This commit enables the native aac decoder to translate pce to ffmpeg channel layouts without any user input. For all pce generated by the native aac encoder a table is used. For more general pce (up to 20 channels) a custom layout is built. Fixes trac issue 7273 with patch 1 of the series. Signed-off-by: pkviet --- libavcodec/aacdec_template.c | 195 +++++++++++++++++++++++++++++++++++++++++-- libavcodec/aacdectab.h | 43 ++++++++++ 2 files changed, 233 insertions(+), 5 deletions(-) diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index b60b31a92c..53b7ea6669 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -155,6 +155,26 @@ static av_cold int che_configure(AACContext *ac, return 0; } +static uint8_t* pce_reorder_map(uint64_t layout) +{ + uint8_t map[8] = {0, 1, 2, 3, 4, 5, 6, 7}; + uint8_t map8[8] = { 2, 0, 1, 6, 7, 4, 5, 3 }; + uint8_t map7[7] = { 2, 0, 1, 4, 5, 6, 3 }; + uint8_t map6[6] = { 2, 0, 1, 4, 5, 3 }; + uint8_t map5[5] = { 2, 0, 1, 4, 3 }; + if (layout == AV_CH_LAYOUT_7POINT1 || layout == AV_CH_LAYOUT_7POINT1_WIDE || + layout == AV_CH_LAYOUT_7POINT1_WIDE_BACK) + return map8; + if (layout == AV_CH_LAYOUT_6POINT1 || layout == AV_CH_LAYOUT_6POINT1_BACK || + layout == AV_CH_LAYOUT_6POINT1_FRONT) + return map7; + if (layout == AV_CH_LAYOUT_5POINT1 || layout == AV_CH_LAYOUT_5POINT1_BACK) + return map6; + if (layout == AV_CH_LAYOUT_4POINT1) + return map5; + return map; +} + static int frame_configure_elements(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; @@ -180,10 +200,15 @@ 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 }; + if (ac->oc[1].m4ac.chan_config == 0 && ac->oc[1].channel_layout && avctx->channels < 9) + memcpy(reorder, pce_reorder_map(ac->oc[1].channel_layout), 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 +282,167 @@ 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) + break; + if (layout_map[i][0] == type) { + if (type == TYPE_CPE) + num_pos_channels += 2; + if (type == TYPE_SCE || type == TYPE_LFE) + 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 correspondance 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; + } + } + + switch(config) { + case 1: return AV_CH_LAYOUT_HEXADECAGONAL; + case 2: return 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; + case 3: return 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; + case 4: return 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; + case 5: return AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | + AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT | + AV_CH_TOP_FRONT_CENTER; + case 6: return AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER | + AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT; + case 7: return AV_CH_LAYOUT_6POINT0_FRONT | AV_CH_BACK_CENTER | + AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_CENTER; + case 8: return AV_CH_LAYOUT_OCTAGONAL | AV_CH_TOP_CENTER; + case 9: return AV_CH_LAYOUT_OCTAGONAL; + case 10: return AV_CH_LAYOUT_7POINT1; + case 11: return AV_CH_LAYOUT_7POINT1_WIDE; + case 12: return AV_CH_LAYOUT_7POINT1_WIDE_BACK; + case 13: return AV_CH_LAYOUT_6POINT1; + case 14: return AV_CH_LAYOUT_6POINT1_BACK; + case 15: return AV_CH_LAYOUT_7POINT0; + case 16: return AV_CH_LAYOUT_7POINT0_FRONT; + case 17: return AV_CH_LAYOUT_HEXAGONAL; + case 18: return AV_CH_LAYOUT_6POINT1_FRONT; + case 19: return AV_CH_LAYOUT_6POINT0; + case 20: return AV_CH_LAYOUT_5POINT1; + case 21: return AV_CH_LAYOUT_5POINT1_BACK; + case 22: return AV_CH_LAYOUT_4POINT1; + case 23: return AV_CH_LAYOUT_6POINT0_FRONT; + case 24: return AV_CH_LAYOUT_5POINT0; + case 25: return AV_CH_LAYOUT_5POINT0_BACK; + case 26: return AV_CH_LAYOUT_4POINT0; + case 27: return AV_CH_LAYOUT_3POINT1; + case 28: return AV_CH_LAYOUT_QUAD; + case 29: return AV_CH_LAYOUT_2_2; + case 30: return AV_CH_LAYOUT_2POINT1; + case 31: return AV_CH_LAYOUT_2_1; + case 32: return AV_CH_LAYOUT_SURROUND; + case 33: return AV_CH_LAYOUT_STEREO; + case 34: return AV_CH_LAYOUT_MONO; + case 0: + default: return 0; + } +} + +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 channels; uint64_t layout; + if (ac->oc[1].m4ac.chan_config == 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) + layout = 0; + 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); + 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->avctx->channels != channels || ac->avctx->channels > 20) + goto guess; + switch (num_LFE_channels) { + case 1: layout |= AV_CH_LOW_FREQUENCY; + case 2: layout |= AV_CH_LOW_FREQUENCY | AV_CH_LOW_FREQUENCY_2; + case 0: layout += 0; + default: return 0; + } + switch (num_front_channels_SCE) { + case 1: layout |= AV_CH_FRONT_CENTER; + case 2: layout |= AV_CH_FRONT_CENTER | AV_CH_TOP_FRONT_CENTER; + case 0: layout += 0; + default: return 0; + } + switch (num_front_channels_CPE) { + case 2: layout |= AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT; + case 4: layout |= AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER; + 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; + case 0: layout += 0; + default: return 0; + } + switch (num_back_channels_SCE) { + case 1: layout |= AV_CH_BACK_CENTER; + case 2: layout |= AV_CH_BACK_CENTER | AV_CH_TOP_BACK_CENTER; + case 0: layout += 0; + default: return 0; + } + switch (num_back_channels_CPE) { + case 2: layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT; + case 4: layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_TOP_BACK_LEFT | AV_CH_TOP_BACK_RIGHT; + case 0: layout += 0; + default: return 0; + } + switch (num_side_channels_CPE) { + case 2: layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT; + case 4: layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT; + case 0: layout += 0; + default: return 0; + } + 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)", buf, layout); + return layout; + } + } + +guess: if (FF_ARRAY_ELEMS(e2c_vec) < tags) return 0; @@ -463,7 +642,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]; @@ -732,13 +911,13 @@ static inline void relative_align_get_bits(GetBitContext *gb, * @return Returns error status. 0 - OK, !0 - error */ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, - uint8_t (*layout_map)[3], + uint8_t layout_map[MAX_ELEM_ID * 4][3], GetBitContext *gb, int byte_align_ref) { 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 @@ -780,6 +959,11 @@ 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); @@ -838,6 +1022,7 @@ static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx, if (channel_config == 0) { skip_bits(gb, 4); // element_instance_tag tags = decode_pce(avctx, m4ac, layout_map, gb, get_bit_alignment); + if (tags < 0) return tags; } else { diff --git a/libavcodec/aacdectab.h b/libavcodec/aacdectab.h index baf51a74bf..bdd1f15839 100644 --- a/libavcodec/aacdectab.h +++ b/libavcodec/aacdectab.h @@ -71,4 +71,47 @@ 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[35] = {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[35][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_SCE, 0, AAC_CHANNEL_FRONT }, { TYPE_CPE, 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 +}; #endif /* AVCODEC_AACDECTAB_H */