📄 ac3enc.c.svn-base
字号:
/* * 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 + -