/* * DCA compatible decoder * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2004 Benjamin Zores * Copyright (C) 2006 Benjamin Larsson * Copyright (C) 2007 Konstantin Shishkov * * This file is part of Libav. * * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <math.h>#include <stddef.h>#include <stdio.h> #include "libavutil/common.h"#include "libavutil/float_dsp.h"#include "libavutil/intmath.h"#include "libavutil/intreadwrite.h"#include "libavutil/mathematics.h"#include "libavutil/audioconvert.h"#include "avcodec.h"#include "dsputil.h"#include "fft.h"#include "get_bits.h"#include "put_bits.h"#include "dcadata.h"#include "dcahuff.h"#include "dca.h"#include "dca_parser.h"#include "synth_filter.h"#include "dcadsp.h"#include "fmtconvert.h" #if ARCH_ARM# include "arm/dca.h"#endif //#define TRACE #define DCA_PRIM_CHANNELS_MAX (7)#define DCA_SUBBANDS (32)#define DCA_ABITS_MAX (32) /* Should be 28 */#define DCA_SUBSUBFRAMES_MAX (4)#define DCA_SUBFRAMES_MAX (16)#define DCA_BLOCKS_MAX (16)#define DCA_LFE_MAX (3) enum DCAMode { DCA_MONO = 0, DCA_CHANNEL, DCA_STEREO, DCA_STEREO_SUMDIFF, DCA_STEREO_TOTAL, DCA_3F, DCA_2F1R, DCA_3F1R, DCA_2F2R, DCA_3F2R, DCA_4F2R}; /* these are unconfirmed but should be mostly correct */enum DCAExSSSpeakerMask { DCA_EXSS_FRONT_CENTER = 0x0001, DCA_EXSS_FRONT_LEFT_RIGHT = 0x0002, DCA_EXSS_SIDE_REAR_LEFT_RIGHT = 0x0004, DCA_EXSS_LFE = 0x0008, DCA_EXSS_REAR_CENTER = 0x0010, DCA_EXSS_FRONT_HIGH_LEFT_RIGHT = 0x0020, DCA_EXSS_REAR_LEFT_RIGHT = 0x0040, DCA_EXSS_FRONT_HIGH_CENTER = 0x0080, DCA_EXSS_OVERHEAD = 0x0100, DCA_EXSS_CENTER_LEFT_RIGHT = 0x0200, DCA_EXSS_WIDE_LEFT_RIGHT = 0x0400, DCA_EXSS_SIDE_LEFT_RIGHT = 0x0800, DCA_EXSS_LFE2 = 0x1000, DCA_EXSS_SIDE_HIGH_LEFT_RIGHT = 0x2000, DCA_EXSS_REAR_HIGH_CENTER = 0x4000, DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000,}; enum DCAExtensionMask { DCA_EXT_CORE = 0x001, ///< core in core substream DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream DCA_EXT_X96 = 0x004, ///< 96/24 extension in core substream DCA_EXT_XCH = 0x008, ///< XCh channel extension in core substream DCA_EXT_EXSS_CORE = 0x010, ///< core in ExSS (extension substream) DCA_EXT_EXSS_XBR = 0x020, ///< extended bitrate extension in ExSS DCA_EXT_EXSS_XXCH = 0x040, ///< XXCh channels extension in ExSS DCA_EXT_EXSS_X96 = 0x080, ///< 96/24 extension in ExSS DCA_EXT_EXSS_LBR = 0x100, ///< low bitrate component in ExSS DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS}; /* -1 are reserved or unknown */static const int dca_ext_audio_descr_mask[] = { DCA_EXT_XCH, -1, DCA_EXT_X96, DCA_EXT_XCH | DCA_EXT_X96, -1, -1, DCA_EXT_XXCH, -1,}; /* extensions that reside in core substream */#define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96) /* Tables for mapping dts channel configurations to libavcodec multichannel api. * Some compromises have been made for special configurations. Most configurations * are never used so complete accuracy is not needed. * * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead. * S -> side, when both rear and back are configured move one of them to the side channel * OV -> center back * All 2 channel configurations -> AV_CH_LAYOUT_STEREO */static const uint64_t dca_core_channel_layout[] = { AV_CH_FRONT_CENTER, ///< 1, A AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono) AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo) AV_CH_LAYOUT_STEREO, ///< 2, (L + R) + (L - R) (sum-difference) AV_CH_LAYOUT_STEREO, ///< 2, LT + RT (left and right total) AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER, ///< 3, C + L + R AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER, ///< 3, L + R + S AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 4, C + L + R + S AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 4, L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 5, C + L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 6, C + L + R + LR + RR + OV AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_BACK_CENTER | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 6, CF + CR + LF + RF + LR + RR AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2 + SR1 + SR2 AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_BACK_CENTER | AV_CH_SIDE_RIGHT, ///< 8, CL + C + CR + L + R + SL + S + SR}; static const int8_t dca_lfe_index[] = { 1, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 1, 3, 2, 3}; static const int8_t dca_channel_reorder_lfe[][9] = { { 0, -1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, -1, -1, -1, -1, -1}, { 0, 1, 3, 4, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, -1, -1, -1, -1}, { 3, 4, 0, 1, 5, 6, -1, -1, -1}, { 2, 0, 1, 4, 5, 6, -1, -1, -1}, { 0, 6, 4, 5, 2, 3, -1, -1, -1}, { 4, 2, 5, 0, 1, 6, 7, -1, -1}, { 5, 6, 0, 1, 7, 3, 8, 4, -1}, { 4, 2, 5, 0, 1, 6, 8, 7, -1},}; static const int8_t dca_channel_reorder_lfe_xch[][9] = { { 0, 2, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, -1, -1, -1, -1, -1}, { 0, 1, 3, 4, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, -1, -1, -1, -1}, { 0, 1, 4, 5, 3, -1, -1, -1, -1}, { 2, 0, 1, 5, 6, 4, -1, -1, -1}, { 3, 4, 0, 1, 6, 7, 5, -1, -1}, { 2, 0, 1, 4, 5, 6, 7, -1, -1}, { 0, 6, 4, 5, 2, 3, 7, -1, -1}, { 4, 2, 5, 0, 1, 7, 8, 6, -1}, { 5, 6, 0, 1, 8, 3, 9, 4, 7}, { 4, 2, 5, 0, 1, 6, 9, 8, 7},}; static const int8_t dca_channel_reorder_nolfe[][9] = { { 0, -1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, -1, -1, -1, -1, -1}, { 0, 1, 2, 3, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, 4, -1, -1, -1, -1}, { 2, 3, 0, 1, 4, 5, -1, -1, -1}, { 2, 0, 1, 3, 4, 5, -1, -1, -1}, { 0, 5, 3, 4, 1, 2, -1, -1, -1}, { 3, 2, 4, 0, 1, 5, 6, -1, -1}, { 4, 5, 0, 1, 6, 2, 7, 3, -1}, { 3, 2, 4, 0, 1, 5, 7, 6, -1},}; static const int8_t dca_channel_reorder_nolfe_xch[][9] = { { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, -1, -1, -1, -1, -1}, { 0, 1, 2, 3, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, 4, -1, -1, -1, -1}, { 0, 1, 3, 4, 2, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, 3, -1, -1, -1}, { 2, 3, 0, 1, 5, 6, 4, -1, -1}, { 2, 0, 1, 3, 4, 5, 6, -1, -1}, { 0, 5, 3, 4, 1, 2, 6, -1, -1}, { 3, 2, 4, 0, 1, 6, 7, 5, -1}, { 4, 5, 0, 1, 7, 2, 8, 3, 6}, { 3, 2, 4, 0, 1, 5, 8, 7, 6},}; #define DCA_DOLBY 101 /* FIXME */ #define DCA_CHANNEL_BITS 6#define DCA_CHANNEL_MASK 0x3F #define DCA_LFE 0x80 #define HEADER_SIZE 14 #define DCA_MAX_FRAME_SIZE 16384#define DCA_MAX_EXSS_HEADER_SIZE 4096 #define DCA_BUFFER_PADDING_SIZE 1024 /** Bit allocation */typedef struct { int offset; ///< code values offset int maxbits[8]; ///< max bits in VLC int wrap; ///< wrap for get_vlc2() VLC vlc[8]; ///< actual codes} BitAlloc; static BitAlloc dca_bitalloc_index; ///< indexes for samples VLC selectstatic BitAlloc dca_tmode; ///< transition mode VLCsstatic BitAlloc dca_scalefactor; ///< scalefactor VLCsstatic BitAlloc dca_smpl_bitalloc[11]; ///< samples VLCs static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx){ return get_vlc2(gb, ba->vlc[idx].table, ba->vlc[idx].bits, ba->wrap) + ba->offset;} typedef struct { AVCodecContext *avctx; AVFrame frame; /* Frame header */ int frame_type; ///< type of the current frame int samples_deficit; ///< deficit sample count int crc_present; ///< crc is present in the bitstream int sample_blocks; ///< number of PCM sample blocks int frame_size; ///< primary frame byte size int amode; ///< audio channels arrangement int sample_rate; ///< audio sampling rate int bit_rate; ///< transmission bit rate int bit_rate_index; ///< transmission bit rate index int downmix; ///< embedded downmix enabled int dynrange; ///< embedded dynamic range flag int timestamp; ///< embedded time stamp flag int aux_data; ///< auxiliary data flag int hdcd; ///< source material is mastered in HDCD int ext_descr; ///< extension audio descriptor flag int ext_coding; ///< extended coding flag int aspf; ///< audio sync word insertion flag int lfe; ///< low frequency effects flag int predictor_history; ///< predictor history flag int header_crc; ///< header crc check bytes int multirate_inter; ///< multirate interpolator switch int version; ///< encoder software revision int copy_history; ///< copy history int source_pcm_res; ///< source pcm resolution int front_sum; ///< front sum/difference flag int surround_sum; ///< surround sum/difference flag int dialog_norm; ///< dialog normalisation parameter /* Primary audio coding header */ int subframes; ///< number of subframes int is_channels_set; ///< check for if the channel number is already set int total_channels; ///< number of channels including extensions int prim_channels; ///< number of primary audio channels int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index int transient_huffman[DCA_PRIM_CHANNELS_MAX]; ///< transient mode code book int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; ///< scale factor code book int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; ///< bit allocation quantizer select int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< quantization index codebook select float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment /* Primary audio coding side information */ int subsubframes[DCA_SUBFRAMES_MAX]; ///< number of subsubframes int partial_samples[DCA_SUBFRAMES_MAX]; ///< partial subsubframe samples count int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not) int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< transition mode (transients) int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients int dynrange_coef; ///< dynamic range coefficient int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data int lfe_scale_factor; /* Subband samples history (for ADPCM) */ DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512]; DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32]; int hist_index[DCA_PRIM_CHANNELS_MAX]; DECLARE_ALIGNED(32, float, raXin)[32]; int output; ///< type of output float scale_bias; ///< output scale DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8]; DECLARE_ALIGNED(32, float, samples)[(DCA_PRIM_CHANNELS_MAX + 1) * 256]; const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1]; uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE]; int dca_buffer_size; ///< how much data is in the dca_buffer const int8_t *channel_order_tab; ///< channel reordering table, lfe and non lfe GetBitContext gb; /* Current position in DCA frame */ int current_subframe; int current_subsubframe; int core_ext_mask; ///< present extensions in the core substream /* XCh extension information */ int xch_present; ///< XCh extension present and valid int xch_base_channel; ///< index of first (only) channel containing XCH data /* ExSS header parser */ int static_fields; ///< static fields present int mix_metadata; ///< mixing metadata present int num_mix_configs; ///< number of mix out configurations int mix_config_num_ch[4]; ///< number of channels in each mix out configuration int profile; int debug_flag; ///< used for suppressing repeated error messages output AVFloatDSPContext fdsp; FFTContext imdct; SynthFilterContext synth; DCADSPContext dcadsp; FmtConvertContext fmt_conv;} DCAContext; static const uint16_t dca_vlc_offs[] = { 0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364, 5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508, 5572, 5604, 5668, 5796, 5860, 5892, 6412, 6668, 6796, 7308, 7564, 7820, 8076, 8620, 9132, 9388, 9910, 10166, 10680, 11196, 11726, 12240, 12752, 13298, 13810, 14326, 14840, 15500, 16022, 16540, 17158, 17678, 18264, 18796, 19352, 19926, 20468, 21472, 22398, 23014, 23622,}; static av_cold void dca_init_vlcs(void){ static int vlcs_initialized = 0; int i, j, c = 14; static VLC_TYPE dca_table[23622][2]; if (vlcs_initialized) return; dca_bitalloc_index.offset = 1; dca_bitalloc_index.wrap = 2; for (i = 0; i < 5; i++) { dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]]; dca_bitalloc_index.vlc[i].table_allocated = dca_vlc_offs[i + 1] - dca_vlc_offs[i]; init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12, bitalloc_12_bits[i], 1, 1, bitalloc_12_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } dca_scalefactor.offset = -64; dca_scalefactor.wrap = 2; for (i = 0; i < 5; i++) { dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]]; dca_scalefactor.vlc[i].table_allocated = dca_vlc_offs[i + 6] - dca_vlc_offs[i + 5]; init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129, scales_bits[i], 1, 1, scales_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } dca_tmode.offset = 0; dca_tmode.wrap = 1; for (i = 0; i < 4; i++) { dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]]; dca_tmode.vlc[i].table_allocated = dca_vlc_offs[i + 11] - dca_vlc_offs[i + 10]; init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4, tmode_bits[i], 1, 1, tmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } for (i = 0; i < 10; i++) for (j = 0; j < 7; j++) { if (!bitalloc_codes[i][j]) break; dca_smpl_bitalloc[i + 1].offset = bitalloc_offsets[i]; dca_smpl_bitalloc[i + 1].wrap = 1 + (j > 4); dca_smpl_bitalloc[i + 1].vlc[j].table = &dca_table[dca_vlc_offs[c]]; dca_smpl_bitalloc[i + 1].vlc[j].table_allocated = dca_vlc_offs[c + 1] - dca_vlc_offs[c]; init_vlc(&dca_smpl_bitalloc[i + 1].vlc[j], bitalloc_maxbits[i][j], bitalloc_sizes[i], bitalloc_bits[i][j], 1, 1, bitalloc_codes[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); c++; } vlcs_initialized = 1;} static inline void get_array(GetBitContext *gb, int *dst, int len, int bits){ while (len--) *dst++ = get_bits(gb, bits);} static int dca_parse_audio_coding_header(DCAContext *s, int base_channel){ int i, j; static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 }; static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel; s->prim_channels = s->total_channels; if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) s->prim_channels = DCA_PRIM_CHANNELS_MAX; for (i = base_channel; i < s->prim_channels; i++) { s->subband_activity[i] = get_bits(&s->gb, 5) + 2; if (s->subband_activity[i] > DCA_SUBBANDS) s->subband_activity[i] = DCA_SUBBANDS; } for (i = base_channel; i < s->prim_channels; i++) { s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; if (s->vq_start_subband[i] > DCA_SUBBANDS) s->vq_start_subband[i] = DCA_SUBBANDS; } get_array(&s->gb, s->joint_intensity + base_channel, s->prim_channels - base_channel, 3); get_array(&s->gb, s->transient_huffman + base_channel, s->prim_channels - base_channel, 2); get_array(&s->gb, s->scalefactor_huffman + base_channel, s->prim_channels - base_channel, 3); get_array(&s->gb, s->bitalloc_huffman + base_channel, s->prim_channels - base_channel, 3); /* Get codebooks quantization indexes */ if (!base_channel) memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); for (j = 1; j < 11; j++) for (i = base_channel; i < s->prim_channels; i++) s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); /* Get scale factor adjustment */Lines 1–500 of 1971. Load more
/* * DCA compatible decoder * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2004 Benjamin Zores * Copyright (C) 2006 Benjamin Larsson * Copyright (C) 2007 Konstantin Shishkov * * This file is part of Libav. * * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include <math.h> #include <stddef.h> #include <stdio.h> #include "libavutil/common.h" #include "libavutil/float_dsp.h" #include "libavutil/intmath.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/audioconvert.h" #include "avcodec.h" #include "dsputil.h" #include "fft.h" #include "get_bits.h" #include "put_bits.h" #include "dcadata.h" #include "dcahuff.h" #include "dca.h" #include "dca_parser.h" #include "synth_filter.h" #include "dcadsp.h" #include "fmtconvert.h" #if ARCH_ARM # include "arm/dca.h" #endif //#define TRACE #define DCA_PRIM_CHANNELS_MAX (7) #define DCA_SUBBANDS (32) #define DCA_ABITS_MAX (32) /* Should be 28 */ #define DCA_SUBSUBFRAMES_MAX (4) #define DCA_SUBFRAMES_MAX (16) #define DCA_BLOCKS_MAX (16) #define DCA_LFE_MAX (3) enum DCAMode { DCA_MONO = 0, DCA_CHANNEL, DCA_STEREO, DCA_STEREO_SUMDIFF, DCA_STEREO_TOTAL, DCA_3F, DCA_2F1R, DCA_3F1R, DCA_2F2R, DCA_3F2R, DCA_4F2R }; /* these are unconfirmed but should be mostly correct */ enum DCAExSSSpeakerMask { DCA_EXSS_FRONT_CENTER = 0x0001, DCA_EXSS_FRONT_LEFT_RIGHT = 0x0002, DCA_EXSS_SIDE_REAR_LEFT_RIGHT = 0x0004, DCA_EXSS_LFE = 0x0008, DCA_EXSS_REAR_CENTER = 0x0010, DCA_EXSS_FRONT_HIGH_LEFT_RIGHT = 0x0020, DCA_EXSS_REAR_LEFT_RIGHT = 0x0040, DCA_EXSS_FRONT_HIGH_CENTER = 0x0080, DCA_EXSS_OVERHEAD = 0x0100, DCA_EXSS_CENTER_LEFT_RIGHT = 0x0200, DCA_EXSS_WIDE_LEFT_RIGHT = 0x0400, DCA_EXSS_SIDE_LEFT_RIGHT = 0x0800, DCA_EXSS_LFE2 = 0x1000, DCA_EXSS_SIDE_HIGH_LEFT_RIGHT = 0x2000, DCA_EXSS_REAR_HIGH_CENTER = 0x4000, DCA_EXSS_REAR_HIGH_LEFT_RIGHT = 0x8000, }; enum DCAExtensionMask { DCA_EXT_CORE = 0x001, ///< core in core substream DCA_EXT_XXCH = 0x002, ///< XXCh channels extension in core substream DCA_EXT_X96 = 0x004, ///< 96/24 extension in core substream DCA_EXT_XCH = 0x008, ///< XCh channel extension in core substream DCA_EXT_EXSS_CORE = 0x010, ///< core in ExSS (extension substream) DCA_EXT_EXSS_XBR = 0x020, ///< extended bitrate extension in ExSS DCA_EXT_EXSS_XXCH = 0x040, ///< XXCh channels extension in ExSS DCA_EXT_EXSS_X96 = 0x080, ///< 96/24 extension in ExSS DCA_EXT_EXSS_LBR = 0x100, ///< low bitrate component in ExSS DCA_EXT_EXSS_XLL = 0x200, ///< lossless extension in ExSS }; /* -1 are reserved or unknown */ static const int dca_ext_audio_descr_mask[] = { DCA_EXT_XCH, -1, DCA_EXT_X96, DCA_EXT_XCH | DCA_EXT_X96, -1, -1, DCA_EXT_XXCH, -1, }; /* extensions that reside in core substream */ #define DCA_CORE_EXTS (DCA_EXT_XCH | DCA_EXT_XXCH | DCA_EXT_X96) /* Tables for mapping dts channel configurations to libavcodec multichannel api. * Some compromises have been made for special configurations. Most configurations * are never used so complete accuracy is not needed. * * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead. * S -> side, when both rear and back are configured move one of them to the side channel * OV -> center back * All 2 channel configurations -> AV_CH_LAYOUT_STEREO */ static const uint64_t dca_core_channel_layout[] = { AV_CH_FRONT_CENTER, ///< 1, A AV_CH_LAYOUT_STEREO, ///< 2, A + B (dual mono) AV_CH_LAYOUT_STEREO, ///< 2, L + R (stereo) AV_CH_LAYOUT_STEREO, ///< 2, (L + R) + (L - R) (sum-difference) AV_CH_LAYOUT_STEREO, ///< 2, LT + RT (left and right total) AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER, ///< 3, C + L + R AV_CH_LAYOUT_STEREO | AV_CH_BACK_CENTER, ///< 3, L + R + S AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 4, C + L + R + S AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 4, L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 5, C + L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR AV_CH_LAYOUT_STEREO | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_FRONT_CENTER | AV_CH_BACK_CENTER, ///< 6, C + L + R + LR + RR + OV AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_BACK_CENTER | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 6, CF + CR + LF + RF + LR + RR AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT | AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2 + SR1 + SR2 AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER | AV_CH_LAYOUT_STEREO | AV_CH_SIDE_LEFT | AV_CH_BACK_CENTER | AV_CH_SIDE_RIGHT, ///< 8, CL + C + CR + L + R + SL + S + SR }; static const int8_t dca_lfe_index[] = { 1, 2, 2, 2, 2, 3, 2, 3, 2, 3, 2, 3, 1, 3, 2, 3 }; static const int8_t dca_channel_reorder_lfe[][9] = { { 0, -1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, -1, -1, -1, -1, -1}, { 0, 1, 3, 4, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, -1, -1, -1, -1}, { 3, 4, 0, 1, 5, 6, -1, -1, -1}, { 2, 0, 1, 4, 5, 6, -1, -1, -1}, { 0, 6, 4, 5, 2, 3, -1, -1, -1}, { 4, 2, 5, 0, 1, 6, 7, -1, -1}, { 5, 6, 0, 1, 7, 3, 8, 4, -1}, { 4, 2, 5, 0, 1, 6, 8, 7, -1}, }; static const int8_t dca_channel_reorder_lfe_xch[][9] = { { 0, 2, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 0, 1, 3, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, -1, -1, -1, -1, -1}, { 0, 1, 3, 4, -1, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, -1, -1, -1, -1}, { 0, 1, 4, 5, 3, -1, -1, -1, -1}, { 2, 0, 1, 5, 6, 4, -1, -1, -1}, { 3, 4, 0, 1, 6, 7, 5, -1, -1}, { 2, 0, 1, 4, 5, 6, 7, -1, -1}, { 0, 6, 4, 5, 2, 3, 7, -1, -1}, { 4, 2, 5, 0, 1, 7, 8, 6, -1}, { 5, 6, 0, 1, 8, 3, 9, 4, 7}, { 4, 2, 5, 0, 1, 6, 9, 8, 7}, }; static const int8_t dca_channel_reorder_nolfe[][9] = { { 0, -1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, -1, -1, -1, -1, -1}, { 0, 1, 2, 3, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, 4, -1, -1, -1, -1}, { 2, 3, 0, 1, 4, 5, -1, -1, -1}, { 2, 0, 1, 3, 4, 5, -1, -1, -1}, { 0, 5, 3, 4, 1, 2, -1, -1, -1}, { 3, 2, 4, 0, 1, 5, 6, -1, -1}, { 4, 5, 0, 1, 6, 2, 7, 3, -1}, { 3, 2, 4, 0, 1, 5, 7, 6, -1}, }; static const int8_t dca_channel_reorder_nolfe_xch[][9] = { { 0, 1, -1, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 0, 1, 2, -1, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, -1, -1, -1, -1, -1}, { 0, 1, 2, 3, -1, -1, -1, -1, -1}, { 2, 0, 1, 3, 4, -1, -1, -1, -1}, { 0, 1, 3, 4, 2, -1, -1, -1, -1}, { 2, 0, 1, 4, 5, 3, -1, -1, -1}, { 2, 3, 0, 1, 5, 6, 4, -1, -1}, { 2, 0, 1, 3, 4, 5, 6, -1, -1}, { 0, 5, 3, 4, 1, 2, 6, -1, -1}, { 3, 2, 4, 0, 1, 6, 7, 5, -1}, { 4, 5, 0, 1, 7, 2, 8, 3, 6}, { 3, 2, 4, 0, 1, 5, 8, 7, 6}, }; #define DCA_DOLBY 101 /* FIXME */ #define DCA_CHANNEL_BITS 6 #define DCA_CHANNEL_MASK 0x3F #define DCA_LFE 0x80 #define HEADER_SIZE 14 #define DCA_MAX_FRAME_SIZE 16384 #define DCA_MAX_EXSS_HEADER_SIZE 4096 #define DCA_BUFFER_PADDING_SIZE 1024 /** Bit allocation */ typedef struct { int offset; ///< code values offset int maxbits[8]; ///< max bits in VLC int wrap; ///< wrap for get_vlc2() VLC vlc[8]; ///< actual codes } BitAlloc; static BitAlloc dca_bitalloc_index; ///< indexes for samples VLC select static BitAlloc dca_tmode; ///< transition mode VLCs static BitAlloc dca_scalefactor; ///< scalefactor VLCs static BitAlloc dca_smpl_bitalloc[11]; ///< samples VLCs static av_always_inline int get_bitalloc(GetBitContext *gb, BitAlloc *ba, int idx) { return get_vlc2(gb, ba->vlc[idx].table, ba->vlc[idx].bits, ba->wrap) + ba->offset; } typedef struct { AVCodecContext *avctx; AVFrame frame; /* Frame header */ int frame_type; ///< type of the current frame int samples_deficit; ///< deficit sample count int crc_present; ///< crc is present in the bitstream int sample_blocks; ///< number of PCM sample blocks int frame_size; ///< primary frame byte size int amode; ///< audio channels arrangement int sample_rate; ///< audio sampling rate int bit_rate; ///< transmission bit rate int bit_rate_index; ///< transmission bit rate index int downmix; ///< embedded downmix enabled int dynrange; ///< embedded dynamic range flag int timestamp; ///< embedded time stamp flag int aux_data; ///< auxiliary data flag int hdcd; ///< source material is mastered in HDCD int ext_descr; ///< extension audio descriptor flag int ext_coding; ///< extended coding flag int aspf; ///< audio sync word insertion flag int lfe; ///< low frequency effects flag int predictor_history; ///< predictor history flag int header_crc; ///< header crc check bytes int multirate_inter; ///< multirate interpolator switch int version; ///< encoder software revision int copy_history; ///< copy history int source_pcm_res; ///< source pcm resolution int front_sum; ///< front sum/difference flag int surround_sum; ///< surround sum/difference flag int dialog_norm; ///< dialog normalisation parameter /* Primary audio coding header */ int subframes; ///< number of subframes int is_channels_set; ///< check for if the channel number is already set int total_channels; ///< number of channels including extensions int prim_channels; ///< number of primary audio channels int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index int transient_huffman[DCA_PRIM_CHANNELS_MAX]; ///< transient mode code book int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; ///< scale factor code book int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; ///< bit allocation quantizer select int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< quantization index codebook select float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment /* Primary audio coding side information */ int subsubframes[DCA_SUBFRAMES_MAX]; ///< number of subsubframes int partial_samples[DCA_SUBFRAMES_MAX]; ///< partial subsubframe samples count int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not) int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< transition mode (transients) int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; ///< scale factors (2 if transient) int joint_huff[DCA_PRIM_CHANNELS_MAX]; ///< joint subband scale factors codebook int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< joint subband scale factors int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; ///< stereo downmix coefficients int dynrange_coef; ///< dynamic range coefficient int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data int lfe_scale_factor; /* Subband samples history (for ADPCM) */ DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512]; DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32]; int hist_index[DCA_PRIM_CHANNELS_MAX]; DECLARE_ALIGNED(32, float, raXin)[32]; int output; ///< type of output float scale_bias; ///< output scale DECLARE_ALIGNED(32, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8]; DECLARE_ALIGNED(32, float, samples)[(DCA_PRIM_CHANNELS_MAX + 1) * 256]; const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX + 1]; uint8_t dca_buffer[DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE + DCA_BUFFER_PADDING_SIZE]; int dca_buffer_size; ///< how much data is in the dca_buffer const int8_t *channel_order_tab; ///< channel reordering table, lfe and non lfe GetBitContext gb; /* Current position in DCA frame */ int current_subframe; int current_subsubframe; int core_ext_mask; ///< present extensions in the core substream /* XCh extension information */ int xch_present; ///< XCh extension present and valid int xch_base_channel; ///< index of first (only) channel containing XCH data /* ExSS header parser */ int static_fields; ///< static fields present int mix_metadata; ///< mixing metadata present int num_mix_configs; ///< number of mix out configurations int mix_config_num_ch[4]; ///< number of channels in each mix out configuration int profile; int debug_flag; ///< used for suppressing repeated error messages output AVFloatDSPContext fdsp; FFTContext imdct; SynthFilterContext synth; DCADSPContext dcadsp; FmtConvertContext fmt_conv; } DCAContext; static const uint16_t dca_vlc_offs[] = { 0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364, 5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508, 5572, 5604, 5668, 5796, 5860, 5892, 6412, 6668, 6796, 7308, 7564, 7820, 8076, 8620, 9132, 9388, 9910, 10166, 10680, 11196, 11726, 12240, 12752, 13298, 13810, 14326, 14840, 15500, 16022, 16540, 17158, 17678, 18264, 18796, 19352, 19926, 20468, 21472, 22398, 23014, 23622, }; static av_cold void dca_init_vlcs(void) { static int vlcs_initialized = 0; int i, j, c = 14; static VLC_TYPE dca_table[23622][2]; if (vlcs_initialized) return; dca_bitalloc_index.offset = 1; dca_bitalloc_index.wrap = 2; for (i = 0; i < 5; i++) { dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]]; dca_bitalloc_index.vlc[i].table_allocated = dca_vlc_offs[i + 1] - dca_vlc_offs[i]; init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12, bitalloc_12_bits[i], 1, 1, bitalloc_12_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } dca_scalefactor.offset = -64; dca_scalefactor.wrap = 2; for (i = 0; i < 5; i++) { dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]]; dca_scalefactor.vlc[i].table_allocated = dca_vlc_offs[i + 6] - dca_vlc_offs[i + 5]; init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129, scales_bits[i], 1, 1, scales_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } dca_tmode.offset = 0; dca_tmode.wrap = 1; for (i = 0; i < 4; i++) { dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]]; dca_tmode.vlc[i].table_allocated = dca_vlc_offs[i + 11] - dca_vlc_offs[i + 10]; init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4, tmode_bits[i], 1, 1, tmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); } for (i = 0; i < 10; i++) for (j = 0; j < 7; j++) { if (!bitalloc_codes[i][j]) break; dca_smpl_bitalloc[i + 1].offset = bitalloc_offsets[i]; dca_smpl_bitalloc[i + 1].wrap = 1 + (j > 4); dca_smpl_bitalloc[i + 1].vlc[j].table = &dca_table[dca_vlc_offs[c]]; dca_smpl_bitalloc[i + 1].vlc[j].table_allocated = dca_vlc_offs[c + 1] - dca_vlc_offs[c]; init_vlc(&dca_smpl_bitalloc[i + 1].vlc[j], bitalloc_maxbits[i][j], bitalloc_sizes[i], bitalloc_bits[i][j], 1, 1, bitalloc_codes[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC); c++; } vlcs_initialized = 1; } static inline void get_array(GetBitContext *gb, int *dst, int len, int bits) { while (len--) *dst++ = get_bits(gb, bits); } static int dca_parse_audio_coding_header(DCAContext *s, int base_channel) { int i, j; static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 }; static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel; s->prim_channels = s->total_channels; if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) s->prim_channels = DCA_PRIM_CHANNELS_MAX; for (i = base_channel; i < s->prim_channels; i++) { s->subband_activity[i] = get_bits(&s->gb, 5) + 2; if (s->subband_activity[i] > DCA_SUBBANDS) s->subband_activity[i] = DCA_SUBBANDS; } for (i = base_channel; i < s->prim_channels; i++) { s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; if (s->vq_start_subband[i] > DCA_SUBBANDS) s->vq_start_subband[i] = DCA_SUBBANDS; } get_array(&s->gb, s->joint_intensity + base_channel, s->prim_channels - base_channel, 3); get_array(&s->gb, s->transient_huffman + base_channel, s->prim_channels - base_channel, 2); get_array(&s->gb, s->scalefactor_huffman + base_channel, s->prim_channels - base_channel, 3); get_array(&s->gb, s->bitalloc_huffman + base_channel, s->prim_channels - base_channel, 3); /* Get codebooks quantization indexes */ if (!base_channel) memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); for (j = 1; j < 11; j++) for (i = base_channel; i < s->prim_channels; i++) s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); /* Get scale factor adjustment */