⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ac3dec.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -