yading@10: /* yading@10: * E-AC-3 decoder yading@10: * Copyright (c) 2007 Bartlomiej Wolowiec yading@10: * Copyright (c) 2008 Justin Ruggles yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /* yading@10: * There are several features of E-AC-3 that this decoder does not yet support. yading@10: * yading@10: * Enhanced Coupling yading@10: * No known samples exist. If any ever surface, this feature should not be yading@10: * too difficult to implement. yading@10: * yading@10: * Reduced Sample Rates yading@10: * No known samples exist. The spec also does not give clear information yading@10: * on how this is to be implemented. yading@10: * yading@10: * Dependent Streams yading@10: * Only the independent stream is currently decoded. Any dependent yading@10: * streams are skipped. We have only come across two examples of this, and yading@10: * they are both just test streams, one for HD-DVD and the other for yading@10: * Blu-ray. yading@10: * yading@10: * Transient Pre-noise Processing yading@10: * This is side information which a decoder should use to reduce artifacts yading@10: * caused by transients. There are samples which are known to have this yading@10: * information, but this decoder currently ignores it. yading@10: */ yading@10: yading@10: yading@10: #include "avcodec.h" yading@10: #include "internal.h" yading@10: #include "aac_ac3_parser.h" yading@10: #include "ac3.h" yading@10: #include "ac3_parser.h" yading@10: #include "ac3dec.h" yading@10: #include "ac3dec_data.h" yading@10: #include "eac3_data.h" yading@10: yading@10: /** gain adaptive quantization mode */ yading@10: typedef enum { yading@10: EAC3_GAQ_NO =0, yading@10: EAC3_GAQ_12, yading@10: EAC3_GAQ_14, yading@10: EAC3_GAQ_124 yading@10: } EAC3GaqMode; yading@10: yading@10: #define EAC3_SR_CODE_REDUCED 3 yading@10: yading@10: void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) yading@10: { yading@10: int bin, bnd, ch, i; yading@10: uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS]; yading@10: float rms_energy[SPX_MAX_BANDS]; yading@10: yading@10: /* Set copy index mapping table. Set wrap flags to apply a notch filter at yading@10: wrap points later on. */ yading@10: bin = s->spx_dst_start_freq; yading@10: num_copy_sections = 0; yading@10: for (bnd = 0; bnd < s->num_spx_bands; bnd++) { yading@10: int copysize; yading@10: int bandsize = s->spx_band_sizes[bnd]; yading@10: if (bin + bandsize > s->spx_src_start_freq) { yading@10: copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; yading@10: bin = s->spx_dst_start_freq; yading@10: wrapflag[bnd] = 1; yading@10: } yading@10: for (i = 0; i < bandsize; i += copysize) { yading@10: if (bin == s->spx_src_start_freq) { yading@10: copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; yading@10: bin = s->spx_dst_start_freq; yading@10: } yading@10: copysize = FFMIN(bandsize - i, s->spx_src_start_freq - bin); yading@10: bin += copysize; yading@10: } yading@10: } yading@10: copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq; yading@10: yading@10: for (ch = 1; ch <= s->fbw_channels; ch++) { yading@10: if (!s->channel_uses_spx[ch]) yading@10: continue; yading@10: yading@10: /* Copy coeffs from normal bands to extension bands */ yading@10: bin = s->spx_src_start_freq; yading@10: for (i = 0; i < num_copy_sections; i++) { yading@10: memcpy(&s->transform_coeffs[ch][bin], yading@10: &s->transform_coeffs[ch][s->spx_dst_start_freq], yading@10: copy_sizes[i]*sizeof(float)); yading@10: bin += copy_sizes[i]; yading@10: } yading@10: yading@10: /* Calculate RMS energy for each SPX band. */ yading@10: bin = s->spx_src_start_freq; yading@10: for (bnd = 0; bnd < s->num_spx_bands; bnd++) { yading@10: int bandsize = s->spx_band_sizes[bnd]; yading@10: float accum = 0.0f; yading@10: for (i = 0; i < bandsize; i++) { yading@10: float coeff = s->transform_coeffs[ch][bin++]; yading@10: accum += coeff * coeff; yading@10: } yading@10: rms_energy[bnd] = sqrtf(accum / bandsize); yading@10: } yading@10: yading@10: /* Apply a notch filter at transitions between normal and extension yading@10: bands and at all wrap points. */ yading@10: if (s->spx_atten_code[ch] >= 0) { yading@10: const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]]; yading@10: bin = s->spx_src_start_freq - 2; yading@10: for (bnd = 0; bnd < s->num_spx_bands; bnd++) { yading@10: if (wrapflag[bnd]) { yading@10: float *coeffs = &s->transform_coeffs[ch][bin]; yading@10: coeffs[0] *= atten_tab[0]; yading@10: coeffs[1] *= atten_tab[1]; yading@10: coeffs[2] *= atten_tab[2]; yading@10: coeffs[3] *= atten_tab[1]; yading@10: coeffs[4] *= atten_tab[0]; yading@10: } yading@10: bin += s->spx_band_sizes[bnd]; yading@10: } yading@10: } yading@10: yading@10: /* Apply noise-blended coefficient scaling based on previously yading@10: calculated RMS energy, blending factors, and SPX coordinates for yading@10: each band. */ yading@10: bin = s->spx_src_start_freq; yading@10: for (bnd = 0; bnd < s->num_spx_bands; bnd++) { yading@10: float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f / INT32_MIN); yading@10: float sscale = s->spx_signal_blend[ch][bnd]; yading@10: for (i = 0; i < s->spx_band_sizes[bnd]; i++) { yading@10: float noise = nscale * (int32_t)av_lfg_get(&s->dith_state); yading@10: s->transform_coeffs[ch][bin] *= sscale; yading@10: s->transform_coeffs[ch][bin++] += noise; yading@10: } yading@10: } yading@10: } yading@10: } yading@10: yading@10: yading@10: /** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */ yading@10: #define COEFF_0 10273905LL yading@10: yading@10: /** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */ yading@10: #define COEFF_1 11863283LL yading@10: yading@10: /** lrint(M_SQRT2*cos(5*M_PI/12)*(1<<23)) */ yading@10: #define COEFF_2 3070444LL yading@10: yading@10: /** yading@10: * Calculate 6-point IDCT of the pre-mantissas. yading@10: * All calculations are 24-bit fixed-point. yading@10: */ yading@10: static void idct6(int pre_mant[6]) yading@10: { yading@10: int tmp; yading@10: int even0, even1, even2, odd0, odd1, odd2; yading@10: yading@10: odd1 = pre_mant[1] - pre_mant[3] - pre_mant[5]; yading@10: yading@10: even2 = ( pre_mant[2] * COEFF_0) >> 23; yading@10: tmp = ( pre_mant[4] * COEFF_1) >> 23; yading@10: odd0 = ((pre_mant[1] + pre_mant[5]) * COEFF_2) >> 23; yading@10: yading@10: even0 = pre_mant[0] + (tmp >> 1); yading@10: even1 = pre_mant[0] - tmp; yading@10: yading@10: tmp = even0; yading@10: even0 = tmp + even2; yading@10: even2 = tmp - even2; yading@10: yading@10: tmp = odd0; yading@10: odd0 = tmp + pre_mant[1] + pre_mant[3]; yading@10: odd2 = tmp + pre_mant[5] - pre_mant[3]; yading@10: yading@10: pre_mant[0] = even0 + odd0; yading@10: pre_mant[1] = even1 + odd1; yading@10: pre_mant[2] = even2 + odd2; yading@10: pre_mant[3] = even2 - odd2; yading@10: pre_mant[4] = even1 - odd1; yading@10: pre_mant[5] = even0 - odd0; yading@10: } yading@10: yading@10: void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) yading@10: { yading@10: int bin, blk, gs; yading@10: int end_bap, gaq_mode; yading@10: GetBitContext *gbc = &s->gbc; yading@10: int gaq_gain[AC3_MAX_COEFS]; yading@10: yading@10: gaq_mode = get_bits(gbc, 2); yading@10: end_bap = (gaq_mode < 2) ? 12 : 17; yading@10: yading@10: /* if GAQ gain is used, decode gain codes for bins with hebap between yading@10: 8 and end_bap */ yading@10: gs = 0; yading@10: if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) { yading@10: /* read 1-bit GAQ gain codes */ yading@10: for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { yading@10: if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap) yading@10: gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1); yading@10: } yading@10: } else if (gaq_mode == EAC3_GAQ_124) { yading@10: /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */ yading@10: int gc = 2; yading@10: for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { yading@10: if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < 17) { yading@10: if (gc++ == 2) { yading@10: int group_code = get_bits(gbc, 5); yading@10: if (group_code > 26) { yading@10: av_log(s->avctx, AV_LOG_WARNING, "GAQ gain group code out-of-range\n"); yading@10: group_code = 26; yading@10: } yading@10: gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][0]; yading@10: gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][1]; yading@10: gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][2]; yading@10: gc = 0; yading@10: } yading@10: } yading@10: } yading@10: } yading@10: yading@10: gs=0; yading@10: for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) { yading@10: int hebap = s->bap[ch][bin]; yading@10: int bits = ff_eac3_bits_vs_hebap[hebap]; yading@10: if (!hebap) { yading@10: /* zero-mantissa dithering */ yading@10: for (blk = 0; blk < 6; blk++) { yading@10: s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000; yading@10: } yading@10: } else if (hebap < 8) { yading@10: /* Vector Quantization */ yading@10: int v = get_bits(gbc, bits); yading@10: for (blk = 0; blk < 6; blk++) { yading@10: s->pre_mantissa[ch][bin][blk] = ff_eac3_mantissa_vq[hebap][v][blk] << 8; yading@10: } yading@10: } else { yading@10: /* Gain Adaptive Quantization */ yading@10: int gbits, log_gain; yading@10: if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) { yading@10: log_gain = gaq_gain[gs++]; yading@10: } else { yading@10: log_gain = 0; yading@10: } yading@10: gbits = bits - log_gain; yading@10: yading@10: for (blk = 0; blk < 6; blk++) { yading@10: int mant = get_sbits(gbc, gbits); yading@10: if (log_gain && mant == -(1 << (gbits-1))) { yading@10: /* large mantissa */ yading@10: int b; yading@10: int mbits = bits - (2 - log_gain); yading@10: mant = get_sbits(gbc, mbits); yading@10: mant <<= (23 - (mbits - 1)); yading@10: /* remap mantissa value to correct for asymmetric quantization */ yading@10: if (mant >= 0) yading@10: b = 1 << (23 - log_gain); yading@10: else yading@10: b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1] << 8; yading@10: mant += ((ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * (int64_t)mant) >> 15) + b; yading@10: } else { yading@10: /* small mantissa, no GAQ, or Gk=1 */ yading@10: mant <<= 24 - bits; yading@10: if (!log_gain) { yading@10: /* remap mantissa value for no GAQ or Gk=1 */ yading@10: mant += (ff_eac3_gaq_remap_1[hebap-8] * (int64_t)mant) >> 15; yading@10: } yading@10: } yading@10: s->pre_mantissa[ch][bin][blk] = mant; yading@10: } yading@10: } yading@10: idct6(s->pre_mantissa[ch][bin]); yading@10: } yading@10: } yading@10: yading@10: int ff_eac3_parse_header(AC3DecodeContext *s) yading@10: { yading@10: int i, blk, ch; yading@10: int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data; yading@10: int parse_transient_proc_info; yading@10: int num_cpl_blocks; yading@10: GetBitContext *gbc = &s->gbc; yading@10: yading@10: /* An E-AC-3 stream can have multiple independent streams which the yading@10: application can select from. each independent stream can also contain yading@10: dependent streams which are used to add or replace channels. */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { yading@10: avpriv_request_sample(s->avctx, "Dependent substream decoding"); yading@10: return AAC_AC3_PARSE_ERROR_FRAME_TYPE; yading@10: } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) { yading@10: av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n"); yading@10: return AAC_AC3_PARSE_ERROR_FRAME_TYPE; yading@10: } yading@10: yading@10: /* The substream id indicates which substream this frame belongs to. each yading@10: independent stream has its own substream id, and the dependent streams yading@10: associated to an independent stream have matching substream id's. */ yading@10: if (s->substreamid) { yading@10: /* only decode substream with id=0. skip any additional substreams. */ yading@10: avpriv_request_sample(s->avctx, "Additional substreams"); yading@10: return AAC_AC3_PARSE_ERROR_FRAME_TYPE; yading@10: } yading@10: yading@10: if (s->bit_alloc_params.sr_code == EAC3_SR_CODE_REDUCED) { yading@10: /* The E-AC-3 specification does not tell how to handle reduced sample yading@10: rates in bit allocation. The best assumption would be that it is yading@10: handled like AC-3 DolbyNet, but we cannot be sure until we have a yading@10: sample which utilizes this feature. */ yading@10: avpriv_request_sample(s->avctx, "Reduced sampling rate"); yading@10: return AVERROR_PATCHWELCOME; yading@10: } yading@10: skip_bits(gbc, 5); // skip bitstream id yading@10: yading@10: /* volume control params */ yading@10: for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { yading@10: skip_bits(gbc, 5); // skip dialog normalization yading@10: if (get_bits1(gbc)) { yading@10: skip_bits(gbc, 8); // skip compression gain word yading@10: } yading@10: } yading@10: yading@10: /* dependent stream channel map */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) { yading@10: if (get_bits1(gbc)) { yading@10: skip_bits(gbc, 16); // skip custom channel map yading@10: } yading@10: } yading@10: yading@10: /* mixing metadata */ yading@10: if (get_bits1(gbc)) { yading@10: /* center and surround mix levels */ yading@10: if (s->channel_mode > AC3_CHMODE_STEREO) { yading@10: skip_bits(gbc, 2); // skip preferred stereo downmix mode yading@10: if (s->channel_mode & 1) { yading@10: /* if three front channels exist */ yading@10: skip_bits(gbc, 3); //skip Lt/Rt center mix level yading@10: s->center_mix_level = get_bits(gbc, 3); yading@10: } yading@10: if (s->channel_mode & 4) { yading@10: /* if a surround channel exists */ yading@10: skip_bits(gbc, 3); //skip Lt/Rt surround mix level yading@10: s->surround_mix_level = get_bits(gbc, 3); yading@10: } yading@10: } yading@10: yading@10: /* lfe mix level */ yading@10: if (s->lfe_on && get_bits1(gbc)) { yading@10: // TODO: use LFE mix level yading@10: skip_bits(gbc, 5); // skip LFE mix level code yading@10: } yading@10: yading@10: /* info for mixing with other streams and substreams */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) { yading@10: for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { yading@10: // TODO: apply program scale factor yading@10: if (get_bits1(gbc)) { yading@10: skip_bits(gbc, 6); // skip program scale factor yading@10: } yading@10: } yading@10: if (get_bits1(gbc)) { yading@10: skip_bits(gbc, 6); // skip external program scale factor yading@10: } yading@10: /* skip mixing parameter data */ yading@10: switch(get_bits(gbc, 2)) { yading@10: case 1: skip_bits(gbc, 5); break; yading@10: case 2: skip_bits(gbc, 12); break; yading@10: case 3: { yading@10: int mix_data_size = (get_bits(gbc, 5) + 2) << 3; yading@10: skip_bits_long(gbc, mix_data_size); yading@10: break; yading@10: } yading@10: } yading@10: /* skip pan information for mono or dual mono source */ yading@10: if (s->channel_mode < AC3_CHMODE_STEREO) { yading@10: for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { yading@10: if (get_bits1(gbc)) { yading@10: /* note: this is not in the ATSC A/52B specification yading@10: reference: ETSI TS 102 366 V1.1.1 yading@10: section: E.1.3.1.25 */ yading@10: skip_bits(gbc, 8); // skip pan mean direction index yading@10: skip_bits(gbc, 6); // skip reserved paninfo bits yading@10: } yading@10: } yading@10: } yading@10: /* skip mixing configuration information */ yading@10: if (get_bits1(gbc)) { yading@10: for (blk = 0; blk < s->num_blocks; blk++) { yading@10: if (s->num_blocks == 1 || get_bits1(gbc)) { yading@10: skip_bits(gbc, 5); yading@10: } yading@10: } yading@10: } yading@10: } yading@10: } yading@10: yading@10: /* informational metadata */ yading@10: if (get_bits1(gbc)) { yading@10: s->bitstream_mode = get_bits(gbc, 3); yading@10: skip_bits(gbc, 2); // skip copyright bit and original bitstream bit yading@10: if (s->channel_mode == AC3_CHMODE_STEREO) { yading@10: skip_bits(gbc, 4); // skip Dolby surround and headphone mode yading@10: } yading@10: if (s->channel_mode >= AC3_CHMODE_2F2R) { yading@10: skip_bits(gbc, 2); // skip Dolby surround EX mode yading@10: } yading@10: for (i = 0; i < (s->channel_mode ? 1 : 2); i++) { yading@10: if (get_bits1(gbc)) { yading@10: skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type yading@10: } yading@10: } yading@10: if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) { yading@10: skip_bits1(gbc); // skip source sample rate code yading@10: } yading@10: } yading@10: yading@10: /* converter synchronization flag yading@10: If frames are less than six blocks, this bit should be turned on yading@10: once every 6 blocks to indicate the start of a frame set. yading@10: reference: RFC 4598, Section 2.1.3 Frame Sets */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) { yading@10: skip_bits1(gbc); // skip converter synchronization flag yading@10: } yading@10: yading@10: /* original frame size code if this stream was converted from AC-3 */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT && yading@10: (s->num_blocks == 6 || get_bits1(gbc))) { yading@10: skip_bits(gbc, 6); // skip frame size code yading@10: } yading@10: yading@10: /* additional bitstream info */ yading@10: if (get_bits1(gbc)) { yading@10: int addbsil = get_bits(gbc, 6); yading@10: for (i = 0; i < addbsil + 1; i++) { yading@10: skip_bits(gbc, 8); // skip additional bit stream info yading@10: } yading@10: } yading@10: yading@10: /* audio frame syntax flags, strategy data, and per-frame data */ yading@10: yading@10: if (s->num_blocks == 6) { yading@10: ac3_exponent_strategy = get_bits1(gbc); yading@10: parse_aht_info = get_bits1(gbc); yading@10: } else { yading@10: /* less than 6 blocks, so use AC-3-style exponent strategy syntax, and yading@10: do not use AHT */ yading@10: ac3_exponent_strategy = 1; yading@10: parse_aht_info = 0; yading@10: } yading@10: yading@10: s->snr_offset_strategy = get_bits(gbc, 2); yading@10: parse_transient_proc_info = get_bits1(gbc); yading@10: yading@10: s->block_switch_syntax = get_bits1(gbc); yading@10: if (!s->block_switch_syntax) yading@10: memset(s->block_switch, 0, sizeof(s->block_switch)); yading@10: yading@10: s->dither_flag_syntax = get_bits1(gbc); yading@10: if (!s->dither_flag_syntax) { yading@10: for (ch = 1; ch <= s->fbw_channels; ch++) yading@10: s->dither_flag[ch] = 1; yading@10: } yading@10: s->dither_flag[CPL_CH] = s->dither_flag[s->lfe_ch] = 0; yading@10: yading@10: s->bit_allocation_syntax = get_bits1(gbc); yading@10: if (!s->bit_allocation_syntax) { yading@10: /* set default bit allocation parameters */ yading@10: s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[2]; yading@10: s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[1]; yading@10: s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab [1]; yading@10: s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[2]; yading@10: s->bit_alloc_params.floor = ff_ac3_floor_tab [7]; yading@10: } yading@10: yading@10: s->fast_gain_syntax = get_bits1(gbc); yading@10: s->dba_syntax = get_bits1(gbc); yading@10: s->skip_syntax = get_bits1(gbc); yading@10: parse_spx_atten_data = get_bits1(gbc); yading@10: yading@10: /* coupling strategy occurrence and coupling use per block */ yading@10: num_cpl_blocks = 0; yading@10: if (s->channel_mode > 1) { yading@10: for (blk = 0; blk < s->num_blocks; blk++) { yading@10: s->cpl_strategy_exists[blk] = (!blk || get_bits1(gbc)); yading@10: if (s->cpl_strategy_exists[blk]) { yading@10: s->cpl_in_use[blk] = get_bits1(gbc); yading@10: } else { yading@10: s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; yading@10: } yading@10: num_cpl_blocks += s->cpl_in_use[blk]; yading@10: } yading@10: } else { yading@10: memset(s->cpl_in_use, 0, sizeof(s->cpl_in_use)); yading@10: } yading@10: yading@10: /* exponent strategy data */ yading@10: if (ac3_exponent_strategy) { yading@10: /* AC-3-style exponent strategy syntax */ yading@10: for (blk = 0; blk < s->num_blocks; blk++) { yading@10: for (ch = !s->cpl_in_use[blk]; ch <= s->fbw_channels; ch++) { yading@10: s->exp_strategy[blk][ch] = get_bits(gbc, 2); yading@10: } yading@10: } yading@10: } else { yading@10: /* LUT-based exponent strategy syntax */ yading@10: for (ch = !((s->channel_mode > 1) && num_cpl_blocks); ch <= s->fbw_channels; ch++) { yading@10: int frmchexpstr = get_bits(gbc, 5); yading@10: for (blk = 0; blk < 6; blk++) { yading@10: s->exp_strategy[blk][ch] = ff_eac3_frm_expstr[frmchexpstr][blk]; yading@10: } yading@10: } yading@10: } yading@10: /* LFE exponent strategy */ yading@10: if (s->lfe_on) { yading@10: for (blk = 0; blk < s->num_blocks; blk++) { yading@10: s->exp_strategy[blk][s->lfe_ch] = get_bits1(gbc); yading@10: } yading@10: } yading@10: /* original exponent strategies if this stream was converted from AC-3 */ yading@10: if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && yading@10: (s->num_blocks == 6 || get_bits1(gbc))) { yading@10: skip_bits(gbc, 5 * s->fbw_channels); // skip converter channel exponent strategy yading@10: } yading@10: yading@10: /* determine which channels use AHT */ yading@10: if (parse_aht_info) { yading@10: /* For AHT to be used, all non-zero blocks must reuse exponents from yading@10: the first block. Furthermore, for AHT to be used in the coupling yading@10: channel, all blocks must use coupling and use the same coupling yading@10: strategy. */ yading@10: s->channel_uses_aht[CPL_CH]=0; yading@10: for (ch = (num_cpl_blocks != 6); ch <= s->channels; ch++) { yading@10: int use_aht = 1; yading@10: for (blk = 1; blk < 6; blk++) { yading@10: if ((s->exp_strategy[blk][ch] != EXP_REUSE) || yading@10: (!ch && s->cpl_strategy_exists[blk])) { yading@10: use_aht = 0; yading@10: break; yading@10: } yading@10: } yading@10: s->channel_uses_aht[ch] = use_aht && get_bits1(gbc); yading@10: } yading@10: } else { yading@10: memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht)); yading@10: } yading@10: yading@10: /* per-frame SNR offset */ yading@10: if (!s->snr_offset_strategy) { yading@10: int csnroffst = (get_bits(gbc, 6) - 15) << 4; yading@10: int snroffst = (csnroffst + get_bits(gbc, 4)) << 2; yading@10: for (ch = 0; ch <= s->channels; ch++) yading@10: s->snr_offset[ch] = snroffst; yading@10: } yading@10: yading@10: /* transient pre-noise processing data */ yading@10: if (parse_transient_proc_info) { yading@10: for (ch = 1; ch <= s->fbw_channels; ch++) { yading@10: if (get_bits1(gbc)) { // channel in transient processing yading@10: skip_bits(gbc, 10); // skip transient processing location yading@10: skip_bits(gbc, 8); // skip transient processing length yading@10: } yading@10: } yading@10: } yading@10: yading@10: /* spectral extension attenuation data */ yading@10: for (ch = 1; ch <= s->fbw_channels; ch++) { yading@10: if (parse_spx_atten_data && get_bits1(gbc)) { yading@10: s->spx_atten_code[ch] = get_bits(gbc, 5); yading@10: } else { yading@10: s->spx_atten_code[ch] = -1; yading@10: } yading@10: } yading@10: yading@10: /* block start information */ yading@10: if (s->num_blocks > 1 && get_bits1(gbc)) { yading@10: /* reference: Section E2.3.2.27 yading@10: nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame))) yading@10: The spec does not say what this data is or what it's used for. yading@10: It is likely the offset of each block within the frame. */ yading@10: int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2)); yading@10: skip_bits_long(gbc, block_start_bits); yading@10: avpriv_request_sample(s->avctx, "Block start info"); yading@10: } yading@10: yading@10: /* syntax state initialization */ yading@10: for (ch = 1; ch <= s->fbw_channels; ch++) { yading@10: s->first_spx_coords[ch] = 1; yading@10: s->first_cpl_coords[ch] = 1; yading@10: } yading@10: s->first_cpl_leak = 1; yading@10: yading@10: return 0; yading@10: }