From patchwork Sun Oct 21 12:27:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "pkv.stream" X-Patchwork-Id: 10737 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 D4FBE448E3C for ; Sun, 21 Oct 2018 15:27:50 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 3B09668A81F; Sun, 21 Oct 2018 15:27:32 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f47.google.com (mail-wr1-f47.google.com [209.85.221.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8F55C68A6CD for ; Sun, 21 Oct 2018 15:27:26 +0300 (EEST) Received: by mail-wr1-f47.google.com with SMTP id d2-v6so41947947wro.7 for ; Sun, 21 Oct 2018 05:27:53 -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=WLthFrwzJPR1xa0ZVhK3Atb2rFpafkMkJ+COGyykOls=; b=gKctI4hEpuSuHNklbV8kjtGkPYxx1e91rORo4Lk6P+08GrHghR0WuHoA1me1o2/DfE rgjxAFC2NNKdvo4TTEONIQCO7SYQ5/JgdChpbR9pUgAy+HyBldqixY4r4i3Od09uQi46 JuXO1jRWPWC9wxU93oYN+ce8hLZ5ZhyVbsxVMFpU0mrwSl1wB5KhJdDz2fEt/NOctt6Y cI24jlPPSW/vx7sp1pNnalijhr5BIgdK/UTOzOb9+sYceQFueqs/xy6lLuw9aj4HA7p8 b9n95CLY0ZTkY3lumLfUunNwEdvvfaiT0i3WgBJbBBR0AvkkapZnpoQen7Tsdvth3xeb J1TQ== 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=WLthFrwzJPR1xa0ZVhK3Atb2rFpafkMkJ+COGyykOls=; b=DupO0pvbl1RgVOrpiFhISoqhALUli40wXzsgqD67pZx3Qn5D7xHKSWY4Pn5ewkYmqP rv6jMBuvwRpaI1lDTHcnIuRluQL/9stwtqy8Zcu5Lcdrdc76UMnpL4z/ZyN0bvITqcXs tEYp/qt0dpFByPuzRu1BD7Oct/SMBu6esy3x/N2awPPxdh+ZJkJBb0DV1vWQqz8VS/wR 0pOqDDtFPZgJtDEaz3DIIJ7QMLaTLfFllzd1J5Ww+YEh9KFemx3vooER6/W1f/Xb3cRQ 4BHU94GJyvobbd1XUh+7YQ8fmkoyLo6/wIfU1npwU04+bzUaAxJC2n8UwuXGW4Zk8r25 n3LQ== X-Gm-Message-State: ABuFfohec8MdlEu16ku5cs3Wmp8wvJpwxiF7/OajHdfsN95OIXYBPClA qJGUda4XQPkDgpQeujfg27xA9IlC X-Google-Smtp-Source: ACcGV62HkgReOVrxznYsq00dnNsXt58iEJ4ip8bWxHgmo/xV+OCELLo8E4iLcVMuJBJfej1TNBc+DA== X-Received: by 2002:a5d:568b:: with SMTP id f11-v6mr16293655wrv.301.1540124873300; Sun, 21 Oct 2018 05:27: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 64-v6sm26614540wrr.64.2018.10.21.05.27.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 21 Oct 2018 05:27:52 -0700 (PDT) To: ffmpeg-devel@ffmpeg.org From: "pkv.stream" Message-ID: Date: Sun, 21 Oct 2018 14:27:48 +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 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" 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. 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 */