[Ffmpeg-devel] [PATCH] ac3 decoder
Michael Niedermayer
michaelni
Sun Oct 1 00:18:13 CEST 2006
Hi
On Thu, Sep 28, 2006 at 08:41:01PM +0200, Benjamin Larsson wrote:
> Here is the patch with the ac3 decoder from SoC. Included is the patch
> to enable the sse imdct from Loren Merrit.
[...]
>
> #define N 512 /* constant for IMDCT Block size */
change the commets to doxygen compatible format
>
> #define MAX_CHANNELS 6
> #define BLOCK_SIZE 256
> #define AUDIO_BLOCKS 6
>
> /* Exponent strategies. */
> #define AC3_EXPSTR_D15 0x01
> #define AC3_EXPSTR_D25 0x02
> #define AC3_EXPSTR_D45 0x03
> #define AC3_EXPSTR_REUSE 0x00
this could be a enum maybe
id also suggest to remove the AC3 prefix, its rather redundant for a local
identifer in a ac3 specific file
[...]
> /* Mersenne Twister */
> #define NMT 624
> #define MMT 397
> #define MATRIX_A 0x9908b0df
> #define UPPER_MASK 0x80000000
> #define LOWER_MASK 0x7fffffff
>
>
> typedef struct {
> uint32_t mt[NMT];
> int mti;
> } dither_state;
> /* Mersenne Twister */
the mersenne twister should be split out of this file and patch
[...]
> DECLARE_ALIGNED_16(float, window[BLOCK_SIZE]); //window coefficients
window is constant, isnt it? if so it should be static and not duplicated in
every context
[...]
> /*********** BEGIN INIT HELPER FUNCTIONS ***********/
> /**
> * Generate a Kaiser-Bessel Derived Window.
> */
> static void ac3_window_init(float *window)
> {
> int i, j;
> double sum = 0.0, bessel, tmp;
> double local_window[256];
> double alpha2 = (5.0 * M_PI / 256.0) * (5.0 * M_PI / 256.0);
>
> for (i = 0; i < 256; i++) {
> tmp = i * (256 - i) * alpha2;
> bessel = 1.0;
> for (j = 100; j > 0; j--) /* defaul to 100 iterations */
> bessel = bessel * tmp / (j * j) + 1;
> sum += bessel;
> local_window[i] = sum;
> }
>
> sum++;
> for (i = 0; i < 256; i++)
> window[i] = sqrt(local_window[i] / sum);
> }
figure out what sum is and hardcode it so the local_window and the second
loop can be avoided
>
> /*
> * Generate quantizer tables.
> */
> static void generate_quantizers_table(int16_t quantizers[], int level, int length)
> {
> int i;
>
> for (i = 0; i < length; i++)
> quantizers[i] = ((2 * i - level + 1) << 15) / level;
> }
>
> static void generate_quantizers_table_1(int16_t quantizers[], int level, int length1, int length2, int size)
> {
> int i, j;
> int16_t v;
>
> for (i = 0; i < length1; i++) {
> v = ((2 * i - level + 1) << 15) / level;
> for (j = 0; j < length2; j++)
> quantizers[i * length2 + j] = v;
> }
>
> for (i = length1 * length2; i < size; i++)
> quantizers[i] = 0;
> }
why is v not an int?
and generate_quantizers_table() seems just a redundant special case of this
>
> static void generate_quantizers_table_2(int16_t quantizers[], int level, int length1, int length2, int size)
> {
> int i, j;
> int16_t v;
>
> for (i = 0; i < length1; i++) {
> v = ((2 * (i % level) - level + 1) << 15) / level;
> for (j = 0; j < length2; j++)
> quantizers[i * length2 + j] = v;
> }
>
> for (i = length1 * length2; i < size; i++)
> quantizers[i] = 0;
>
> }
this should be merged with generate_quantizers_table_1()
i also think all the = 0 stuff at the end is unneeded, isnt the memory
memset() to 0 somewhere anyway?
[...]
> /* Exponent Decoding Tables */
> for (i = 0; i < 5; i++) {
> v = i - 2;
> for (j = 0; j < 25; j++)
> exp_1[i * 25 + j] = v;
> }
>
> for (i = 0; i < 25; i++) {
> v = (i % 5) - 2;
> for (j = 0; j < 5; j++)
> exp_2[i * 5 + j] = v;
> }
>
> for (i = 0; i < 25; i++) {
> v = -2;
> for (j = 0; j < 5; j++)
> exp_3[i * 5 + j] = v++;
> }
the 3 loops can be merged, this is just init code and not speed critical
[...]
> /* Synchronize to ac3 bitstream.
> * This function searches for the syncword '0xb77'.
> *
> * @param buf Pointer to "probable" ac3 bitstream buffer
> * @param buf_size Size of buffer
> * @return Returns the position where syncword is found, -1 if no syncword is found
> */
doxygen comments start with /** or various other ones but normal
/* isnt parsed i think
[...]
> static int ac3_parse_sync_info(AC3DecodeContext *ctx)
> {
> GetBitContext *gb = &ctx->gb;
> int frmsizecod, bsid;
>
> skip_bits(gb, 16); //skip the sync_word, sync_info->sync_word = get_bits(gb, 16);
> ctx->crc1 = get_bits(gb, 16);
> ctx->fscod = get_bits(gb, 2);
> if (ctx->fscod == 0x03)
> return 0;
> frmsizecod = get_bits(gb, 6);
> if (frmsizecod >= 38)
> return 0;
id suggest to return negative values for errors, for consistency with the
rest of lavc
[...]
> switch (ctx->fscod) {
> case 0x00:
> ctx->frame_size = 4 * ctx->bit_rate;
> return ctx->frame_size;
> case 0x01:
> ctx->frame_size = 2 * (320 * ctx->bit_rate / 147 + (frmsizecod & 1));
> return ctx->frame_size;
> case 0x02:
> ctx->frame_size = 6 * ctx->bit_rate;
> return ctx->frame_size;
> }
>
> /* never reached */
> return 0;
the return ctx->frame_size; in the switch can be factored out
[...]
> i = get_bits(gb, 6); //additional bsi length
> do {
> skip_bits(gb, 8);
> } while(i--);
skip_bits_long(gb, 8*i);
[...]
> if (deltba[seg] >= 4)
> delta = (deltba[seg] - 3) << 7;
> else
> delta = (deltba[seg] - 4) << 7;
maybe change to
delta = (deltba[seg] - 3 - (deltba[seg] < 4)) << 7;
> for (k = 0; k < deltlen[seg]; k++) {
> mask[band] += delta;
> band++;
> }
> }
> }
>
> /*compute the bit allocation */
> i = start;
> j = masktab[start];
> do {
> lastbin = FFMIN((bndtab[j] + bndsz[j]), end);
superfluous () and this isnt the only one, not that i suggest to remove
every () which can be removed but this one here and a few others dont
help readability at all ...
> mask[j] -= snroffset;
> mask[j] -= floor;
> if (mask[j] < 0)
> mask[j] = 0;
> mask[j] &= 0x1fe0;
> mask[j] += floor;
> for (k = i; k < lastbin; k++) {
> address = (psd[i] - mask[j]) >> 5;
> address = FFMIN(63, (FFMAX(0, address)));
clip()
[...]
> if ((ctx->csnroffst) || (ctx->cplinu && ctx->cplfsnroffst) ||
> (ctx->lfeon && ctx->lfefsnroffst))
if( ctx->csnroffst
||(ctx->cplinu && ctx->cplfsnroffst)
||(ctx->lfeon && ctx->lfefsnroffst))
is IMHO more readable
[...]
> static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
> {
> GetBitContext *gb = &ctx->gb;
> int ch, start, end, cplbndstrc, bnd, gcode, tbap;
> float cplcos[5], cplcoeff;
> uint8_t *exps = ctx->dcplexps;
> uint8_t *bap = ctx->cplbap;
>
> cplbndstrc = ctx->cplbndstrc;
> start = ctx->cplstrtmant;
> bnd = 0;
>
> while (start < ctx->cplendmant) {
> end = start + 12;
> while (cplbndstrc & 1) {
> end += 12;
> cplbndstrc >>= 1;
> }
> cplbndstrc >>= 1;
> for (ch = 0; ch < ctx->nfchans; ch++)
> cplcos[ch] = ctx->chcoeffs[ch] * ctx->cplco[ch][bnd];
> bnd++;
>
> while (start < end) {
> tbap = bap[start];
> switch(tbap) {
> case 0:
> for (ch = 0; ch < ctx->nfchans; ch++)
> if (((ctx->chincpl) >> ch) & 1) {
> if ((ctx->dithflag >> ch) & 1) {
> TRANSFORM_COEFF(cplcoeff, dither_int16(&ctx->dith_state), exps[start], scale_factors);
> ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch] * LEVEL_MINUS_3DB;
> } else
> ctx->transform_coeffs[ch + 1][start] = 0;
> }
> start++;
> continue;
> case 1:
> if (m->l3ptr > 2) {
> gcode = get_bits(gb, 5);
> m->l3_quantizers[0] = l3_quantizers_1[gcode];
> m->l3_quantizers[1] = l3_quantizers_2[gcode];
> m->l3_quantizers[2] = l3_quantizers_3[gcode];
> m->l3ptr = 0;
> }
> TRANSFORM_COEFF(cplcoeff, m->l3_quantizers[m->l3ptr++], exps[start], scale_factors);
> break;
>
> case 2:
> if (m->l5ptr > 2) {
> gcode = get_bits(gb, 7);
> m->l5_quantizers[0] = l5_quantizers_1[gcode];
> m->l5_quantizers[1] = l5_quantizers_2[gcode];
> m->l5_quantizers[2] = l5_quantizers_3[gcode];
> m->l5ptr = 0;
> }
> TRANSFORM_COEFF(cplcoeff, m->l5_quantizers[m->l5ptr++], exps[start], scale_factors);
> break;
>
> case 3:
> TRANSFORM_COEFF(cplcoeff, l7_quantizers[get_bits(gb, 3)], exps[start], scale_factors);
> break;
>
> case 4:
> if (m->l11ptr > 1) {
> gcode = get_bits(gb, 7);
> m->l11_quantizers[0] = l11_quantizers_1[gcode];
> m->l11_quantizers[1] = l11_quantizers_2[gcode];
> m->l11ptr = 0;
> }
> TRANSFORM_COEFF(cplcoeff, m->l11_quantizers[m->l11ptr++], exps[start], scale_factors);
> break;
>
> case 5:
> TRANSFORM_COEFF(cplcoeff, l15_quantizers[get_bits(gb, 4)], exps[start], scale_factors);
> break;
>
> default:
> TRANSFORM_COEFF(cplcoeff, get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]),
> exps[start], scale_factors);
> }
> for (ch = 0; ch < ctx->nfchans; ch++)
> if ((ctx->chincpl >> ch) & 1)
> ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch];
> start++;
> }
> }
>
> return 0;
> }
>
> /* Get the transform coefficients for particular channel */
> static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_groups *m)
> {
> GetBitContext *gb = &ctx->gb;
> int i, gcode, tbap, dithflag, end;
> uint8_t *exps;
> uint8_t *bap;
> float *coeffs;
> float factors[25];
>
> for (i = 0; i < 25; i++)
> factors[i] = scale_factors[i] * ctx->chcoeffs[ch_index];
>
> if (ch_index != -1) { /* fbw channels */
> dithflag = (ctx->dithflag >> ch_index) & 1;
> exps = ctx->dexps[ch_index];
> bap = ctx->bap[ch_index];
> coeffs = ctx->transform_coeffs[ch_index + 1];
> end = ctx->endmant[ch_index];
> } else if (ch_index == -1) {
> dithflag = 0;
> exps = ctx->dlfeexps;
> bap = ctx->lfebap;
> coeffs = ctx->transform_coeffs[0];
> end = 7;
> }
>
>
> for (i = 0; i < end; i++) {
> tbap = bap[i];
> switch (tbap) {
> case 0:
> if (!dithflag) {
> coeffs[i] = 0;
> continue;
> }
> else {
> TRANSFORM_COEFF(coeffs[i], dither_int16(&ctx->dith_state), exps[i], factors);
> coeffs[i] *= LEVEL_MINUS_3DB;
> continue;
> }
>
> case 1:
> if (m->l3ptr > 2) {
> gcode = get_bits(gb, 5);
> m->l3_quantizers[0] = l3_quantizers_1[gcode];
> m->l3_quantizers[1] = l3_quantizers_2[gcode];
> m->l3_quantizers[2] = l3_quantizers_3[gcode];
> m->l3ptr = 0;
> }
> TRANSFORM_COEFF(coeffs[i], m->l3_quantizers[m->l3ptr++], exps[i], factors);
> continue;
>
> case 2:
> if (m->l5ptr > 2) {
> gcode = get_bits(gb, 7);
> m->l5_quantizers[0] = l5_quantizers_1[gcode];
> m->l5_quantizers[1] = l5_quantizers_2[gcode];
> m->l5_quantizers[2] = l5_quantizers_3[gcode];
> m->l5ptr = 0;
> }
> TRANSFORM_COEFF(coeffs[i], m->l5_quantizers[m->l5ptr++], exps[i], factors);
> continue;
>
> case 3:
> TRANSFORM_COEFF(coeffs[i], l7_quantizers[get_bits(gb, 3)], exps[i], factors);
> continue;
>
> case 4:
> if (m->l11ptr > 1) {
> gcode = get_bits(gb, 7);
> m->l11_quantizers[0] = l11_quantizers_1[gcode];
> m->l11_quantizers[1] = l11_quantizers_2[gcode];
> m->l11ptr = 0;
> }
> TRANSFORM_COEFF(coeffs[i], m->l11_quantizers[m->l11ptr++], exps[i], factors);
> continue;
>
> case 5:
> TRANSFORM_COEFF(coeffs[i], l15_quantizers[get_bits(gb, 4)], exps[i], factors);
> continue;
>
> default:
> TRANSFORM_COEFF(coeffs[i], get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), exps[i], factors);
> continue;
> }
> }
>
> return 0;
> }
this looks fairly similar to get_transform_coeffs_cpling() shouldnt that
be merged ...
[...]
> do
> ctx->transform_coeffs[i + 1][end] = 0;
> while(++end < 256);
memset(0)
> }
> if (ctx->lfeon) {
> if (get_transform_coeffs_ch(ctx, -1, &m))
> return -1;
> for (i = 7; i < 256; i++) {
> ctx->transform_coeffs[0][i] = 0;
> }
memset(0)
[...]
> static void do_rematrixing(AC3DecodeContext *ctx)
> {
> int bnd1 = 13, bnd2 = 25, bnd3 = 37, bnd4 = 61;
> int end, bndend;
>
> end = FFMIN(ctx->endmant[0], ctx->endmant[1]);
>
> if (ctx->rematflg & 1)
> do_rematrixing1(ctx, bnd1, bnd2);
>
> if (ctx->rematflg & 2)
> do_rematrixing1(ctx, bnd2, bnd3);
>
> bndend = bnd4;
> if (bndend > end) {
> bndend = end;
> if (ctx->rematflg & 4)
> do_rematrixing1(ctx, bnd3, bndend);
> } else {
> if (ctx->rematflg & 4)
> do_rematrixing1(ctx, bnd3, bnd4);
> if (ctx->rematflg & 8)
> do_rematrixing1(ctx, bnd4, end);
> }
the following is simpler
bnd[4]= FFMIN(ctx->endmant[0], ctx->endmant[1]);
bnd[3]= FFMIN(bnd[3], bnd[4]);
for(i=0; i<4; i++){
if(ctx->rematflg & (1<<i))
do_rematrixing1(ctx, bnd[i], bnd[i+1]);
}
[...]
> /* This function sets the normalized channel coefficients.
> * Transform coefficients are multipllied by the channel
> * coefficients to get normalized transform coefficients.
> */
> static void get_downmix_coeffs(AC3DecodeContext *ctx)
> {
> int from = ctx->acmod;
> int to = ctx->blkoutput;
> float clev = clevs[ctx->cmixlev];
> float slev = slevs[ctx->surmixlev];
> float nf = 1.0; //normalization factor for downmix coeffs
> int i;
>
> if (!ctx->acmod) {
> ctx->chcoeffs[0] = 2 * ctx->dynrng;
> ctx->chcoeffs[1] = 2 * ctx->dynrng2;
> } else {
> for (i = 0; i < ctx->nfchans; i++)
> ctx->chcoeffs[i] = 2 * ctx->dynrng;
> }
>
> if (to == AC3_OUTPUT_UNMODIFIED)
> return;
>
> switch (from) {
> case AC3_INPUT_DUALMONO:
> switch (to) {
> case AC3_OUTPUT_MONO:
> case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */
> nf = 0.5;
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> break;
> }
> break;
> case AC3_INPUT_MONO:
> switch (to) {
> case AC3_OUTPUT_STEREO:
> nf = LEVEL_MINUS_3DB;
> ctx->chcoeffs[0] *= nf;
> break;
> }
> break;
> case AC3_INPUT_STEREO:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = LEVEL_MINUS_3DB;
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> break;
> }
> break;
> case AC3_INPUT_3F:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = LEVEL_MINUS_3DB / (1.0 + clev);
> ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[1] *= ((nf * clev * LEVEL_MINUS_3DB) / 2.0);
> break;
> case AC3_OUTPUT_STEREO:
> nf = 1.0 / (1.0 + clev);
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[2] *= nf;
> ctx->chcoeffs[1] *= (nf * clev);
> break;
> }
> break;
> case AC3_INPUT_2F_1R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = 2.0 * LEVEL_MINUS_3DB / (2.0 + slev);
> ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_STEREO:
> nf = 1.0 / (1.0 + (slev * LEVEL_MINUS_3DB));
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_DOLBY:
> nf = 1.0 / (1.0 + LEVEL_MINUS_3DB);
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
> break;
> }
> break;
> case AC3_INPUT_3F_1R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = LEVEL_MINUS_3DB / (1.0 + clev + (slev / 2.0));
> ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
> ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_STEREO:
> nf = 1.0 / (1.0 + clev + (slev * LEVEL_MINUS_3DB));
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[2] *= nf;
> ctx->chcoeffs[1] *= (nf * clev);
> ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_DOLBY:
> nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
> break;
> }
> break;
> case AC3_INPUT_2F_2R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = LEVEL_MINUS_3DB / (1.0 + slev);
> ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
> ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_STEREO:
> nf = 1.0 / (1.0 + slev);
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[2] *= (nf * slev);
> ctx->chcoeffs[3] *= (nf * slev);
> break;
> case AC3_OUTPUT_DOLBY:
> nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
> break;
> }
> break;
> case AC3_INPUT_3F_2R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> nf = LEVEL_MINUS_3DB / (1.0 + clev + slev);
> ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
> ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
> ctx->chcoeffs[4] *= (nf * slev * LEVEL_MINUS_3DB);
> break;
> case AC3_OUTPUT_STEREO:
> nf = 1.0 / (1.0 + clev + slev);
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[2] *= nf;
> ctx->chcoeffs[1] *= (nf * clev);
> ctx->chcoeffs[3] *= (nf * slev);
> ctx->chcoeffs[4] *= (nf * slev);
> break;
> case AC3_OUTPUT_DOLBY:
> nf = 1.0 / (1.0 + (3.0 * LEVEL_MINUS_3DB));
> ctx->chcoeffs[0] *= nf;
> ctx->chcoeffs[1] *= nf;
> ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
typo?
> ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
> ctx->chcoeffs[4] *= (nf * LEVEL_MINUS_3DB);
> break;
> }
> break;
> }
and please simplify this mess
[...]
>
> /* Downmix the output.
> * This function downmixes the output when the number of input
> * channels is not equal to the number of output channels requested.
> */
> static void do_downmix(AC3DecodeContext *ctx)
> {
> int from = ctx->acmod;
> int to = ctx->blkoutput;
>
> if (to == AC3_OUTPUT_UNMODIFIED)
> return;
>
> switch (from) {
> case AC3_INPUT_DUALMONO:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_dualmono_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO: /* We assume that sum of both mono channels is requested */
> mix_dualmono_to_stereo(ctx);
> break;
> }
> break;
> case AC3_INPUT_MONO:
> switch (to) {
> case AC3_OUTPUT_STEREO:
> upmix_mono_to_stereo(ctx);
> break;
> }
> break;
> case AC3_INPUT_STEREO:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_stereo_to_mono(ctx);
> break;
> }
> break;
> case AC3_INPUT_3F:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_3f_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO:
> mix_3f_to_stereo(ctx);
> break;
> }
> break;
> case AC3_INPUT_2F_1R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_2f_1r_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO:
> mix_2f_1r_to_stereo(ctx);
> break;
> case AC3_OUTPUT_DOLBY:
> mix_2f_1r_to_dolby(ctx);
> break;
> }
> break;
> case AC3_INPUT_3F_1R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_3f_1r_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO:
> mix_3f_1r_to_stereo(ctx);
> break;
> case AC3_OUTPUT_DOLBY:
> mix_3f_1r_to_dolby(ctx);
> break;
> }
> break;
> case AC3_INPUT_2F_2R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_2f_2r_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO:
> mix_2f_2r_to_stereo(ctx);
> break;
> case AC3_OUTPUT_DOLBY:
> mix_2f_2r_to_dolby(ctx);
> break;
> }
> break;
> case AC3_INPUT_3F_2R:
> switch (to) {
> case AC3_OUTPUT_MONO:
> mix_3f_2r_to_mono(ctx);
> break;
> case AC3_OUTPUT_STEREO:
> mix_3f_2r_to_stereo(ctx);
> break;
> case AC3_OUTPUT_DOLBY:
> mix_3f_2r_to_dolby(ctx);
> break;
> }
> break;
> }
an array of function pointers, initalizd with
[AC3_INPUT_... + X*AC3_OUTPUT_...]= ...,
...
seems much simpler ... (and eventually this can b changed to offsets
into dspcontext)
[...]
> if (get_bits1(gb)) { /* dynamic range */
> dynrng = get_sbits(gb, 8);
> ctx->dynrng = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
> }
>
> if (acmod == 0x00 && get_bits1(gb)) { /* dynamic range 1+1 mode */
> dynrng = get_sbits(gb, 8);
> ctx->dynrng2 = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
> }
maybe change to
for(i=0; i<=!acmod; i++){
if(get_bits1(gb)){
dynrng = get_sbits(gb, 8);
ctx->dynrng[i] = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
}
}
>
> get_downmix_coeffs(ctx);
>
> if (get_bits1(gb)) { /* coupling strategy */
> ctx->cplinu = get_bits1(gb);
> ctx->cplbndstrc = 0;
> ctx->chincpl = 0;
> if (ctx->cplinu) { /* coupling in use */
> for (i = 0; i < nfchans; i++)
> ctx->chincpl |= get_bits1(gb) << i;
reading nfchans bits in reverse is done several times either
A. change the thing so a simple get_bits(gb, nfchans) can be used
B. add a function / macro which does this reverse reading
[...]
> static inline int16_t convert(int32_t i)
> {
> if (i > 0x43c07fff)
> return 32767;
> else if (i <= 0x43bf8000)
> return -32768;
> else
> return (i - 0x43c00000);
> }
this should be replaced by float_to_int16 from dspcontext
>
> static int frame_count = 0;
uhm ...
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is
More information about the ffmpeg-devel
mailing list