📄 wmadeci.c
字号:
/* compute bit reverse table */ for(i=0;i<n;i++) { m=0; for(j=0;j<nbits;j++) { m |= ((i >> j) & 1) << (nbits-j-1); } s->revtab[i]=m; } return 0;fail: av_freep(&s->revtab); av_freep(&s->exptab); av_freep(&s->exptab1); return -1;}/* butter fly op */#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \{\ fixed32 ax, ay, bx, by;\ bx=pre1;\ by=pim1;\ ax=qre1;\ ay=qim1;\ pre = (bx + ax);\ pim = (by + ay);\ qre = (bx - ax);\ qim = (by - ay);\}/** * Do a complex FFT with the parameters defined in fft_init(). The * input data must be permuted before with s->revtab table. No * 1.0/sqrt(n) normalization is done. */void fft_calc(FFTContext *s, FFTComplex *z){ int ln = s->nbits; int j, np, np2; int nblocks, nloops; register FFTComplex *p, *q; FFTComplex *exptab = s->exptab; int l; fixed32 tmp_re, tmp_im; np = 1 << ln; /* 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; if (s->inverse) { 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); } else { 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, exptab[l].re, exptab[l].im, 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 the permutation needed BEFORE calling fft_calc() */void fft_permute(FFTContext *s, FFTComplex *z){ int j, k, np; FFTComplex tmp; const uint16_t *revtab = s->revtab; /* reverse */ np = 1 << s->nbits; for(j=0;j<np;j++) { k = revtab[j]; if (k < j) { tmp = z[k]; z[k] = z[j]; z[j] = tmp; } }}void fft_end(FFTContext *s){ av_freep(&s->revtab); av_freep(&s->exptab); av_freep(&s->exptab1);}/* VLC decoding */#define GET_DATA(v, table, i, wrap, size) \{\ const uint8_t *ptr = (const uint8_t *)table + i * wrap;\ switch(size) {\ case 1:\ v = *(const uint8_t *)ptr;\ break;\ case 2:\ v = *(const uint16_t *)ptr;\ break;\ default:\ v = *(const uint32_t *)ptr;\ break;\ }\}/* deprecated, dont use get_vlc for new code, use get_vlc2 instead or use GET_VLC directly */static inline int get_vlc(GetBitContext *s, VLC *vlc){ int code; VLC_TYPE (*table)[2]= vlc->table; OPEN_READER(re, s) UPDATE_CACHE(re, s) GET_VLC(code, re, s, table, vlc->bits, 3) CLOSE_READER(re, s) return code;}static int alloc_table(VLC *vlc, int size){ int index; index = vlc->table_size; vlc->table_size += size; if (vlc->table_size > vlc->table_allocated) { vlc->table_allocated += (1 << vlc->bits); vlc->table = av_realloc(vlc->table, sizeof(VLC_TYPE) * 2 * vlc->table_allocated); if (!vlc->table) return -1; } return index;}static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, uint32_t code_prefix, int n_prefix){ int i, j, k, n, table_size, table_index, nb, n1, index; uint32_t code; VLC_TYPE (*table)[2]; table_size = 1 << table_nb_bits; table_index = alloc_table(vlc, table_size); if (table_index < 0) return -1; table = &vlc->table[table_index]; for(i=0;i<table_size;i++) { table[i][1] = 0; table[i][0] = -1; } /* first pass: map codes and compute auxillary table sizes */ for(i=0;i<nb_codes;i++) { GET_DATA(n, bits, i, bits_wrap, bits_size); GET_DATA(code, codes, i, codes_wrap, codes_size); /* we accept tables with holes */ if (n <= 0) continue; /* if code matches the prefix, it is in the table */ n -= n_prefix; if (n > 0 && (code >> n) == code_prefix) { if (n <= table_nb_bits) { /* no need to add another table */ j = (code << (table_nb_bits - n)) & (table_size - 1); nb = 1 << (table_nb_bits - n); for(k=0;k<nb;k++) { table[j][1] = n; table[j][0] = i; j++; } } else { n -= table_nb_bits; j = (code >> n) & ((1 << table_nb_bits) - 1); /* compute table size */ n1 = -table[j][1]; if (n > n1) n1 = n; table[j][1] = -n1; } } } /* second pass : fill auxillary tables recursively */ for(i=0;i<table_size;i++) { n = table[i][1]; if (n < 0) { n = -n; if (n > table_nb_bits) { n = table_nb_bits; table[i][1] = -n; } index = build_table(vlc, n, nb_codes, bits, bits_wrap, bits_size, codes, codes_wrap, codes_size, (code_prefix << table_nb_bits) | i, n_prefix + table_nb_bits); if (index < 0) return -1; /* note: realloc has been done, so reload tables */ table = &vlc->table[table_index]; table[i][0] = index; } } return table_index;}/* Build VLC decoding tables suitable for use with get_vlc(). 'nb_bits' set thee decoding table size (2^nb_bits) entries. The bigger it is, the faster is the decoding. But it should not be too big to save memory and L1 cache. '9' is a good compromise. 'nb_codes' : number of vlcs codes 'bits' : table which gives the size (in bits) of each vlc code. 'codes' : table which gives the bit pattern of of each vlc code. 'xxx_wrap' : give the number of bytes between each entry of the 'bits' or 'codes' tables. 'xxx_size' : gives the number of bytes of each entry of the 'bits' or 'codes' tables. 'wrap' and 'size' allows to use any memory configuration and types (byte/word/long) to store the 'bits' and 'codes' tables.*/int init_vlc(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size){ vlc->bits = nb_bits; vlc->table = NULL; vlc->table_allocated = 0; vlc->table_size = 0; if (build_table(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, codes, codes_wrap, codes_size, 0, 0) < 0) { av_free(vlc->table); return -1; } return 0;}/** * init MDCT or IMDCT computation. */int ff_mdct_init(MDCTContext *s, int nbits, int inverse){ int n, n4, i; fixed32 alpha; memset(s, 0, sizeof(*s)); n = 1 << nbits; s->nbits = nbits; s->n = n; n4 = n >> 2; s->tcos = av_malloc(n4 * sizeof(fixed32)); if (!s->tcos) goto fail; s->tsin = av_malloc(n4 * sizeof(fixed32)); if (!s->tsin) goto fail; for(i=0;i<n4;i++) { fixed32 pi2 = fixmul32(0x20000, M_PI_F); fixed32 ip = itofix32(i) + 0x2000; ip = fixdiv32(ip,itofix32(n)); /* PJJ optimize */ alpha = fixmul32(pi2, ip); s->tcos[i] = -fixcos32(alpha); s->tsin[i] = -fixsin32(alpha); } if (fft_inits(&s->fft, s->nbits - 2, inverse) < 0) goto fail; return 0;fail: av_freep(&s->tcos); av_freep(&s->tsin); return -1;}/** * Compute inverse MDCT of size N = 2^nbits * @param output N samples * @param input N/2 samples * @param tmp N/2 samples */void ff_imdct_calc(MDCTContext *s, fixed32 *output, const fixed32 *input, FFTComplex *tmp){ int k, n8, n4, n2, n, j; const uint16_t *revtab = s->fft.revtab; const fixed32 *tcos = s->tcos; const fixed32 *tsin = s->tsin; const fixed32 *in1, *in2; FFTComplex *z = (FFTComplex *)tmp; n = 1 << s->nbits; n2 = n >> 1; n4 = n >> 2; n8 = n >> 3; /* pre rotation */ in1 = input; in2 = input + n2 - 1; for(k = 0; k < n4; k++) { j=revtab[k]; CMUL(&z[j].re, &z[j].im, *in2, *in1, tcos[k], tsin[k]); in1 += 2; in2 -= 2; } fft_calc(&s->fft, z); /* post rotation + reordering */ /* XXX: optimize */ for(k = 0; k < n4; k++) { CMUL(&z[k].re, &z[k].im, z[k].re, z[k].im, tcos[k], tsin[k]); } for(k = 0; k < n8; k++) { fixed32 r1,r2,r3,r4,r1n,r2n,r3n; r1 = z[n8 + k].im; r1n = r1 * -1.0; r2 = z[n8-1-k].re; r2n = r2 * -1.0; r3 = z[k+n8].re; r3n = r3 * -1.0; r4 = z[n8-k-1].im; output[2*k] = r1n; output[n2-1-2*k] = r1; output[2*k+1] = r2; output[n2-1-2*k-1] = r2n; output[n2 + 2*k]= r3n; output[n-1- 2*k]= r3n; output[n2 + 2*k+1]= r4; output[n-2 - 2 * k] = r4; }}void ff_mdct_end(MDCTContext *s){ av_freep(&s->tcos); av_freep(&s->tsin); fft_end(&s->fft);}static void init_coef_vlc(VLC *vlc, uint16_t **prun_table, uint16_t **plevel_table, const CoefVLCTable *vlc_table){ int n = vlc_table->n; const uint8_t *table_bits = vlc_table->huffbits; const uint32_t *table_codes = vlc_table->huffcodes; const uint16_t *levels_table = vlc_table->levels; uint16_t *run_table, *level_table; const uint16_t *p; int i, l, j, level; init_vlc(vlc, 9, n, table_bits, 1, 1, table_codes, 4, 4); run_table = av_malloc(n * sizeof(uint16_t)); level_table = av_malloc(n * sizeof(uint16_t)); p = levels_table; i = 2; level = 1; while (i < n) { l = *p++; for(j=0;j<l;++j) { run_table[i] = j; level_table[i] = level; ++i; } ++level; } *prun_table = run_table; *plevel_table = level_table;}/* interpolate values for a bigger or smaller block. The block must have multiple sizes */static void interpolate_array(fixed32 *scale, int old_size, int new_size){ int i, j, jincr, k; fixed32 v; if (new_size > old_size) { jincr = new_size / old_size; j = new_size; for(i = old_size - 1; i >=0; --i) { v = scale[i]; k = jincr; do { scale[--j] = v; } while (--k); } } else if (new_size < old_size) { j = 0; jincr = old_size / new_size; for(i = 0; i < new_size; ++i)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -