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

📄 ac3enc.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * The simplest AC3 encoder * Copyright (c) 2000 Fabrice Bellard. * * This file is part of FFmpeg. * * FFmpeg 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. * * FFmpeg 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 FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file ac3enc.c * The simplest AC3 encoder. *///#define DEBUG//#define DEBUG_BITALLOC#include "avcodec.h"#include "bitstream.h"#include "crc.h"#include "ac3.h"typedef struct AC3EncodeContext {    PutBitContext pb;    int nb_channels;    int nb_all_channels;    int lfe_channel;    int bit_rate;    unsigned int sample_rate;    unsigned int bitstream_id;    unsigned int frame_size_min; /* minimum frame size in case rounding is necessary */    unsigned int frame_size; /* current frame size in words */    unsigned int bits_written;    unsigned int samples_written;    int sr_shift;    unsigned int frame_size_code;    unsigned int sr_code; /* frequency */    unsigned int channel_mode;    int lfe;    unsigned int bitstream_mode;    short last_samples[AC3_MAX_CHANNELS][256];    unsigned int chbwcod[AC3_MAX_CHANNELS];    int nb_coefs[AC3_MAX_CHANNELS];    /* bitrate allocation control */    int slow_gain_code, slow_decay_code, fast_decay_code, db_per_bit_code, floor_code;    AC3BitAllocParameters bit_alloc;    int coarse_snr_offset;    int fast_gain_code[AC3_MAX_CHANNELS];    int fine_snr_offset[AC3_MAX_CHANNELS];    /* mantissa encoding */    int mant1_cnt, mant2_cnt, mant4_cnt;} AC3EncodeContext;static int16_t costab[64];static int16_t sintab[64];static int16_t xcos1[128];static int16_t xsin1[128];#define MDCT_NBITS 9#define N         (1 << MDCT_NBITS)/* new exponents are sent if their Norm 1 exceed this number */#define EXP_DIFF_THRESHOLD 1000static inline int16_t fix15(float a){    int v;    v = (int)(a * (float)(1 << 15));    if (v < -32767)        v = -32767;    else if (v > 32767)        v = 32767;    return v;}typedef struct IComplex {    short re,im;} IComplex;static void fft_init(int ln){    int i, n;    float alpha;    n = 1 << ln;    for(i=0;i<(n/2);i++) {        alpha = 2 * M_PI * (float)i / (float)n;        costab[i] = fix15(cos(alpha));        sintab[i] = fix15(sin(alpha));    }}/* butter fly op */#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \{\  int ax, ay, bx, by;\  bx=pre1;\  by=pim1;\  ax=qre1;\  ay=qim1;\  pre = (bx + ax) >> 1;\  pim = (by + ay) >> 1;\  qre = (bx - ax) >> 1;\  qim = (by - ay) >> 1;\}#define MUL16(a,b) ((a) * (b))#define CMUL(pre, pim, are, aim, bre, bim) \{\   pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15;\   pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15;\}/* do a 2^n point complex fft on 2^ln points. */static void fft(IComplex *z, int ln){    int        j, l, np, np2;    int        nblocks, nloops;    register IComplex *p,*q;    int tmp_re, tmp_im;    np = 1 << ln;    /* reverse */    for(j=0;j<np;j++) {        int k = ff_reverse[j] >> (8 - ln);        if (k < j)            FFSWAP(IComplex, z[k], z[j]);    }    /* pass 0 */    p=&z[0];    j=(np >> 1);    do {        BF(p[0].re, p[0].im, p[1].re, p[1].im,           p[0].re, p[0].im, p[1].re, p[1].im);        p+=2;    } while (--j != 0);    /* pass 1 */    p=&z[0];    j=np >> 2;    do {        BF(p[0].re, p[0].im, p[2].re, p[2].im,           p[0].re, p[0].im, p[2].re, p[2].im);        BF(p[1].re, p[1].im, p[3].re, p[3].im,           p[1].re, p[1].im, p[3].im, -p[3].re);        p+=4;    } while (--j != 0);    /* pass 2 .. ln-1 */    nblocks = np >> 3;    nloops = 1 << 2;    np2 = np >> 1;    do {        p = z;        q = z + nloops;        for (j = 0; j < nblocks; ++j) {            BF(p->re, p->im, q->re, q->im,               p->re, p->im, q->re, q->im);            p++;            q++;            for(l = nblocks; l < np2; l += nblocks) {                CMUL(tmp_re, tmp_im, costab[l], -sintab[l], q->re, q->im);                BF(p->re, p->im, q->re, q->im,                   p->re, p->im, tmp_re, tmp_im);                p++;                q++;            }            p += nloops;            q += nloops;        }        nblocks = nblocks >> 1;        nloops = nloops << 1;    } while (nblocks != 0);}/* do a 512 point mdct */static void mdct512(int32_t *out, int16_t *in){    int i, re, im, re1, im1;    int16_t rot[N];    IComplex x[N/4];    /* shift to simplify computations */    for(i=0;i<N/4;i++)        rot[i] = -in[i + 3*N/4];    for(i=N/4;i<N;i++)        rot[i] = in[i - N/4];    /* pre rotation */    for(i=0;i<N/4;i++) {        re = ((int)rot[2*i] - (int)rot[N-1-2*i]) >> 1;        im = -((int)rot[N/2+2*i] - (int)rot[N/2-1-2*i]) >> 1;        CMUL(x[i].re, x[i].im, re, im, -xcos1[i], xsin1[i]);    }    fft(x, MDCT_NBITS - 2);    /* post rotation */    for(i=0;i<N/4;i++) {        re = x[i].re;        im = x[i].im;        CMUL(re1, im1, re, im, xsin1[i], xcos1[i]);        out[2*i] = im1;        out[N/2-1-2*i] = re1;    }}/* XXX: use another norm ? */static int calc_exp_diff(uint8_t *exp1, uint8_t *exp2, int n){    int sum, i;    sum = 0;    for(i=0;i<n;i++) {        sum += abs(exp1[i] - exp2[i]);    }    return sum;}static void compute_exp_strategy(uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS],                                 uint8_t exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],                                 int ch, int is_lfe){    int i, j;    int exp_diff;    /* estimate if the exponent variation & decide if they should be       reused in the next frame */    exp_strategy[0][ch] = EXP_NEW;    for(i=1;i<NB_BLOCKS;i++) {        exp_diff = calc_exp_diff(exp[i][ch], exp[i-1][ch], N/2);#ifdef DEBUG        av_log(NULL, AV_LOG_DEBUG, "exp_diff=%d\n", exp_diff);#endif        if (exp_diff > EXP_DIFF_THRESHOLD)            exp_strategy[i][ch] = EXP_NEW;        else            exp_strategy[i][ch] = EXP_REUSE;    }    if (is_lfe)        return;    /* now select the encoding strategy type : if exponents are often       recoded, we use a coarse encoding */    i = 0;    while (i < NB_BLOCKS) {        j = i + 1;        while (j < NB_BLOCKS && exp_strategy[j][ch] == EXP_REUSE)            j++;        switch(j - i) {        case 1:            exp_strategy[i][ch] = EXP_D45;            break;        case 2:        case 3:            exp_strategy[i][ch] = EXP_D25;            break;        default:            exp_strategy[i][ch] = EXP_D15;            break;        }        i = j;    }}/* set exp[i] to min(exp[i], exp1[i]) */static void exponent_min(uint8_t exp[N/2], uint8_t exp1[N/2], int n){    int i;    for(i=0;i<n;i++) {        if (exp1[i] < exp[i])            exp[i] = exp1[i];    }}/* update the exponents so that they are the ones the decoder will   decode. Return the number of bits used to code the exponents */static int encode_exp(uint8_t encoded_exp[N/2],                      uint8_t exp[N/2],                      int nb_exps,                      int exp_strategy){    int group_size, nb_groups, i, j, k, exp_min;    uint8_t exp1[N/2];    switch(exp_strategy) {    case EXP_D15:        group_size = 1;        break;    case EXP_D25:        group_size = 2;        break;    default:    case EXP_D45:        group_size = 4;        break;    }    nb_groups = ((nb_exps + (group_size * 3) - 4) / (3 * group_size)) * 3;    /* for each group, compute the minimum exponent */    exp1[0] = exp[0]; /* DC exponent is handled separately */    k = 1;    for(i=1;i<=nb_groups;i++) {        exp_min = exp[k];        assert(exp_min >= 0 && exp_min <= 24);        for(j=1;j<group_size;j++) {            if (exp[k+j] < exp_min)                exp_min = exp[k+j];        }        exp1[i] = exp_min;        k += group_size;    }    /* constraint for DC exponent */    if (exp1[0] > 15)        exp1[0] = 15;    /* Decrease the delta between each groups to within 2     * so that they can be differentially encoded */    for (i=1;i<=nb_groups;i++)        exp1[i] = FFMIN(exp1[i], exp1[i-1] + 2);    for (i=nb_groups-1;i>=0;i--)        exp1[i] = FFMIN(exp1[i], exp1[i+1] + 2);    /* now we have the exponent values the decoder will see */    encoded_exp[0] = exp1[0];    k = 1;    for(i=1;i<=nb_groups;i++) {        for(j=0;j<group_size;j++) {            encoded_exp[k+j] = exp1[i];        }        k += group_size;    }#if defined(DEBUG)    av_log(NULL, AV_LOG_DEBUG, "exponents: strategy=%d\n", exp_strategy);    for(i=0;i<=nb_groups * group_size;i++) {        av_log(NULL, AV_LOG_DEBUG, "%d ", encoded_exp[i]);    }    av_log(NULL, AV_LOG_DEBUG, "\n");#endif    return 4 + (nb_groups / 3) * 7;}/* return the size in bits taken by the mantissa */static int compute_mantissa_size(AC3EncodeContext *s, uint8_t *m, int nb_coefs){    int bits, mant, i;    bits = 0;    for(i=0;i<nb_coefs;i++) {        mant = m[i];        switch(mant) {        case 0:            /* nothing */            break;        case 1:            /* 3 mantissa in 5 bits */            if (s->mant1_cnt == 0)                bits += 5;            if (++s->mant1_cnt == 3)                s->mant1_cnt = 0;            break;        case 2:            /* 3 mantissa in 7 bits */            if (s->mant2_cnt == 0)                bits += 7;            if (++s->mant2_cnt == 3)                s->mant2_cnt = 0;            break;        case 3:            bits += 3;            break;        case 4:            /* 2 mantissa in 7 bits */            if (s->mant4_cnt == 0)                bits += 7;            if (++s->mant4_cnt == 2)                s->mant4_cnt = 0;            break;        case 14:            bits += 14;            break;        case 15:            bits += 16;            break;        default:            bits += mant - 1;            break;        }    }    return bits;}static void bit_alloc_masking(AC3EncodeContext *s,                              uint8_t encoded_exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],                              uint8_t exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS],                              int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],                              int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50]){    int blk, ch;    int16_t band_psd[NB_BLOCKS][AC3_MAX_CHANNELS][50];    for(blk=0; blk<NB_BLOCKS; blk++) {        for(ch=0;ch<s->nb_all_channels;ch++) {            if(exp_strategy[blk][ch] == EXP_REUSE) {                memcpy(psd[blk][ch], psd[blk-1][ch], (N/2)*sizeof(int16_t));                memcpy(mask[blk][ch], mask[blk-1][ch], 50*sizeof(int16_t));            } else {                ff_ac3_bit_alloc_calc_psd(encoded_exp[blk][ch], 0,                                          s->nb_coefs[ch],                                          psd[blk][ch], band_psd[blk][ch]);                ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, band_psd[blk][ch],                                           0, s->nb_coefs[ch],                                           ff_ac3_fast_gain_tab[s->fast_gain_code[ch]],                                           ch == s->lfe_channel,                                           DBA_NONE, 0, NULL, NULL, NULL,                                           mask[blk][ch]);            }        }    }}static int bit_alloc(AC3EncodeContext *s,                     int16_t mask[NB_BLOCKS][AC3_MAX_CHANNELS][50],                     int16_t psd[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],                     uint8_t bap[NB_BLOCKS][AC3_MAX_CHANNELS][N/2],                     int frame_bits, int coarse_snr_offset, int fine_snr_offset){    int i, ch;    int snr_offset;    snr_offset = (((coarse_snr_offset - 15) << 4) + fine_snr_offset) << 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -