📄 ac3dec.c
字号:
typedef struct { int b1_mant[3]; int b2_mant[3]; int b4_mant[2]; int b1ptr; int b2ptr; int b4ptr;} mant_groups;/** * Get the transform coefficients for a particular channel * reference: Section 7.3 Quantization and Decoding of Mantissas */static void get_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m){ GetBitContext *gbc = &s->gbc; int i, gcode, tbap, start, end; uint8_t *exps; uint8_t *bap; int *coeffs;#ifndef __CW32__ exps = s->dexps[ch_index];#else exps = (uint8_t*)s->dexps[ch_index];#endif bap = s->bap[ch_index]; coeffs = s->fixed_coeffs[ch_index]; start = s->start_freq[ch_index]; end = s->end_freq[ch_index]; for (i = start; i < end; i++) { tbap = bap[i]; switch (tbap) { case 0: coeffs[i] = (av_random(&s->dith_state) & 0x7FFFFF) - 4194304; break; case 1: if(m->b1ptr > 2) { gcode = get_bits(gbc, 5); m->b1_mant[0] = b1_mantissas[gcode][0]; m->b1_mant[1] = b1_mantissas[gcode][1]; m->b1_mant[2] = b1_mantissas[gcode][2]; m->b1ptr = 0; } coeffs[i] = m->b1_mant[m->b1ptr++]; break; case 2: if(m->b2ptr > 2) { gcode = get_bits(gbc, 7); m->b2_mant[0] = b2_mantissas[gcode][0]; m->b2_mant[1] = b2_mantissas[gcode][1]; m->b2_mant[2] = b2_mantissas[gcode][2]; m->b2ptr = 0; } coeffs[i] = m->b2_mant[m->b2ptr++]; break; case 3: coeffs[i] = b3_mantissas[get_bits(gbc, 3)]; break; case 4: if(m->b4ptr > 1) { gcode = get_bits(gbc, 7); m->b4_mant[0] = b4_mantissas[gcode][0]; m->b4_mant[1] = b4_mantissas[gcode][1]; m->b4ptr = 0; } coeffs[i] = m->b4_mant[m->b4ptr++]; break; case 5: coeffs[i] = b5_mantissas[get_bits(gbc, 4)]; break; default: { /* asymmetric dequantization */ int qlevel = quantization_tab[tbap]; coeffs[i] = get_sbits(gbc, qlevel) << (24 - qlevel); break; } } coeffs[i] >>= exps[i]; }}/** * Remove random dithering from coefficients with zero-bit mantissas * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0) */static void remove_dithering(AC3DecodeContext *s) { int ch, i; int end=0; int *coeffs; uint8_t *bap; for(ch=1; ch<=s->fbw_channels; ch++) { if(!s->dither_flag[ch]) { coeffs = s->fixed_coeffs[ch]; bap = s->bap[ch]; if(s->channel_in_cpl[ch]) end = s->start_freq[CPL_CH]; else end = s->end_freq[ch]; for(i=0; i<end; i++) { if(!bap[i]) coeffs[i] = 0; } if(s->channel_in_cpl[ch]) { bap = s->bap[CPL_CH]; for(; i<s->end_freq[CPL_CH]; i++) { if(!bap[i]) coeffs[i] = 0; } } } }}/** * Get the transform coefficients. */static void get_transform_coeffs(AC3DecodeContext *s){ int ch, end; int got_cplchan = 0; mant_groups m; m.b1ptr = m.b2ptr = m.b4ptr = 3; for (ch = 1; ch <= s->channels; ch++) { /* transform coefficients for full-bandwidth channel */ get_transform_coeffs_ch(s, ch, &m); /* tranform coefficients for coupling channel come right after the coefficients for the first coupled channel*/ if (s->channel_in_cpl[ch]) { if (!got_cplchan) { get_transform_coeffs_ch(s, CPL_CH, &m); uncouple_channels(s); got_cplchan = 1; } end = s->end_freq[CPL_CH]; } else { end = s->end_freq[ch]; } do s->fixed_coeffs[ch][end] = 0; while(++end < 256); } /* if any channel doesn't use dithering, zero appropriate coefficients */ if(!s->dither_all) remove_dithering(s);}/** * Stereo rematrixing. * reference: Section 7.5.4 Rematrixing : Decoding Technique */static void do_rematrixing(AC3DecodeContext *s){ int bnd, i; int end, bndend; int tmp0, tmp1; end = FFMIN(s->end_freq[1], s->end_freq[2]); for(bnd=0; bnd<s->num_rematrixing_bands; bnd++) { if(s->rematrixing_flags[bnd]) { bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd+1]); for(i=ff_ac3_rematrix_band_tab[bnd]; i<bndend; i++) { tmp0 = s->fixed_coeffs[1][i]; tmp1 = s->fixed_coeffs[2][i]; s->fixed_coeffs[1][i] = tmp0 + tmp1; s->fixed_coeffs[2][i] = tmp0 - tmp1; } } }}/** * Perform the 256-point IMDCT */static void do_imdct_256(AC3DecodeContext *s, int chindex){ int i, k; DECLARE_ALIGNED_16(float, x[128]); FFTComplex z[2][64]; float *o_ptr = s->tmp_output; for(i=0; i<2; i++) { /* de-interleave coefficients */ for(k=0; k<128; k++) { x[k] = s->transform_coeffs[chindex][2*k+i]; } /* run standard IMDCT */ s->imdct_256.fft.imdct_calc(&s->imdct_256, o_ptr, x, s->tmp_imdct); /* reverse the post-rotation & reordering from standard IMDCT */ for(k=0; k<32; k++) { z[i][32+k].re = -o_ptr[128+2*k]; z[i][32+k].im = -o_ptr[2*k]; z[i][31-k].re = o_ptr[2*k+1]; z[i][31-k].im = o_ptr[128+2*k+1]; } } /* apply AC-3 post-rotation & reordering */ for(k=0; k<64; k++) { o_ptr[ 2*k ] = -z[0][ k].im; o_ptr[ 2*k+1] = z[0][63-k].re; o_ptr[128+2*k ] = -z[0][ k].re; o_ptr[128+2*k+1] = z[0][63-k].im; o_ptr[256+2*k ] = -z[1][ k].re; o_ptr[256+2*k+1] = z[1][63-k].im; o_ptr[384+2*k ] = z[1][ k].im; o_ptr[384+2*k+1] = -z[1][63-k].re; }}/** * Inverse MDCT Transform. * Convert frequency domain coefficients to time-domain audio samples. * reference: Section 7.9.4 Transformation Equations */static inline void do_imdct(AC3DecodeContext *s, int channels){ int ch; for (ch=1; ch<=channels; ch++) { if (s->block_switch[ch]) { do_imdct_256(s, ch); } else { s->imdct_512.fft.imdct_calc(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch], s->tmp_imdct); } /* For the first half of the block, apply the window, add the delay from the previous block, and send to output */ s->dsp.vector_fmul_add_add(s->output[ch-1], s->tmp_output, s->window, s->delay[ch-1], 0, 256, 1); /* For the second half of the block, apply the window and store the samples to delay, to be combined with the next block */ s->dsp.vector_fmul_reverse(s->delay[ch-1], s->tmp_output+256, s->window, 256); }}/** * Downmix the output to mono or stereo. */static void ac3_downmix(AC3DecodeContext *s, float samples[AC3_MAX_CHANNELS][256], int ch_offset){ int i, j; float v0, v1; for(i=0; i<256; i++) { v0 = v1 = 0.0f; for(j=0; j<s->fbw_channels; j++) { v0 += samples[j+ch_offset][i] * s->downmix_coeffs[j][0]; v1 += samples[j+ch_offset][i] * s->downmix_coeffs[j][1]; } v0 *= s->downmix_coeff_adjust[0]; v1 *= s->downmix_coeff_adjust[1]; if(s->output_mode == AC3_CHMODE_MONO) { samples[ch_offset][i] = (v0 + v1) * LEVEL_MINUS_3DB; } else if(s->output_mode == AC3_CHMODE_STEREO) { samples[ ch_offset][i] = v0; samples[1+ch_offset][i] = v1; } }}/** * Upmix delay samples from stereo to original channel layout. */static void ac3_upmix_delay(AC3DecodeContext *s){ int channel_data_size = sizeof(s->delay[0]); switch(s->channel_mode) { case AC3_CHMODE_DUALMONO: case AC3_CHMODE_STEREO: /* upmix mono to stereo */ memcpy(s->delay[1], s->delay[0], channel_data_size); break; case AC3_CHMODE_2F2R: memset(s->delay[3], 0, channel_data_size); case AC3_CHMODE_2F1R: memset(s->delay[2], 0, channel_data_size); break; case AC3_CHMODE_3F2R: memset(s->delay[4], 0, channel_data_size); case AC3_CHMODE_3F1R: memset(s->delay[3], 0, channel_data_size); case AC3_CHMODE_3F: memcpy(s->delay[2], s->delay[1], channel_data_size); memset(s->delay[1], 0, channel_data_size); break; }}/** * Parse an audio block from AC-3 bitstream. */static int ac3_parse_audio_block(AC3DecodeContext *s, int blk){ int fbw_channels = s->fbw_channels; int channel_mode = s->channel_mode; int i, bnd, seg, ch; int different_transforms; int downmix_output; int cpl_in_use; GetBitContext *gbc = &s->gbc; uint8_t bit_alloc_stages[AC3_MAX_CHANNELS]; memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS); /* block switch flags */ different_transforms = 0; for (ch = 1; ch <= fbw_channels; ch++) { s->block_switch[ch] = get_bits1(gbc); if(ch > 1 && s->block_switch[ch] != s->block_switch[1]) different_transforms = 1; } /* dithering flags */ s->dither_all = 1; for (ch = 1; ch <= fbw_channels; ch++) { s->dither_flag[ch] = get_bits1(gbc); if(!s->dither_flag[ch]) s->dither_all = 0; } /* dynamic range */ i = !(s->channel_mode); do { if(get_bits1(gbc)) { s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) * s->avctx->drc_scale)+1.0; } else if(blk == 0) { s->dynamic_range[i] = 1.0f; } } while(i--); /* coupling strategy */ if (get_bits1(gbc)) { memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS); cpl_in_use = get_bits1(gbc); if (cpl_in_use) { /* coupling in use */ int cpl_begin_freq, cpl_end_freq; if (channel_mode < AC3_CHMODE_STEREO) { av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); return -1; } /* determine which channels are coupled */ for (ch = 1; ch <= fbw_channels; ch++) s->channel_in_cpl[ch] = get_bits1(gbc); /* phase flags in use */ if (channel_mode == AC3_CHMODE_STEREO) s->phase_flags_in_use = get_bits1(gbc); /* coupling frequency range and band structure */ cpl_begin_freq = get_bits(gbc, 4); cpl_end_freq = get_bits(gbc, 4); if (3 + cpl_end_freq - cpl_begin_freq < 0) { av_log(s->avctx, AV_LOG_ERROR, "3+cplendf = %d < cplbegf = %d\n", 3+cpl_end_freq, cpl_begin_freq); return -1; } s->num_cpl_bands = s->num_cpl_subbands = 3 + cpl_end_freq - cpl_begin_freq; s->start_freq[CPL_CH] = cpl_begin_freq * 12 + 37; s->end_freq[CPL_CH] = cpl_end_freq * 12 + 73; for (bnd = 0; bnd < s->num_cpl_subbands - 1; bnd++) { if (get_bits1(gbc)) { s->cpl_band_struct[bnd] = 1; s->num_cpl_bands--; } } s->cpl_band_struct[s->num_cpl_subbands-1] = 0; } else { /* coupling not in use */ for (ch = 1; ch <= fbw_channels; ch++) s->channel_in_cpl[ch] = 0; } } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must be present in block 0\n"); return -1; } else { cpl_in_use = s->cpl_in_use[blk-1]; } s->cpl_in_use[blk] = cpl_in_use; /* coupling coordinates */ if (cpl_in_use) { int cpl_coords_exist = 0; for (ch = 1; ch <= fbw_channels; ch++) { if (s->channel_in_cpl[ch]) { if (get_bits1(gbc)) { int master_cpl_coord, cpl_coord_exp, cpl_coord_mant; cpl_coords_exist = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -