Mercurial > libavcodec.hg
changeset 314:289eb941b8ba libavcodec
* encoding of AC3 with more than 2 channels
by Takashi Iwai <tiwai@suse.de>
author | kabi |
---|---|
date | Mon, 08 Apr 2002 12:08:03 +0000 |
parents | a0124152c89d |
children | 40d8092e2ff0 |
files | ac3dec.c ac3enc.c ac3enc.h |
diffstat | 3 files changed, 104 insertions(+), 69 deletions(-) [+] |
line wrap: on
line diff
--- a/ac3dec.c Sun Apr 07 21:44:29 2002 +0000 +++ b/ac3dec.c Mon Apr 08 12:08:03 2002 +0000 @@ -26,6 +26,7 @@ UINT8 *inbuf_ptr; int frame_size; int flags; + int channels; ac3_state_t state; } AC3DecodeState; @@ -52,24 +53,16 @@ return i - 0x43c00000; } -static inline void float_to_int (float * _f, INT16 * s16) +static inline void float_to_int (float * _f, INT16 * s16, int nchannels) { - int i; + int i, j, c; int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format + j = 0; + nchannels *= 256; for (i = 0; i < 256; i++) { - s16[2*i] = blah (f[i]); - s16[2*i+1] = blah (f[i+256]); - } -} - -static inline void float_to_int_mono (float * _f, INT16 * s16) -{ - int i; - int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format - - for (i = 0; i < 256; i++) { - s16[i] = blah (f[i]); + for (c = 0; c < nchannels; c += 256) + s16[j++] = blah (f[i + c]); } } @@ -87,6 +80,9 @@ int sample_rate, bit_rate; short *out_samples = data; float level; + static int ac3_channels[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 + }; *data_size = 0; buf_ptr = buf; @@ -111,10 +107,13 @@ s->frame_size = len; /* update codec info */ avctx->sample_rate = sample_rate; - if ((s->flags & AC3_CHANNEL_MASK) == AC3_MONO) - avctx->channels = 1; - else - avctx->channels = 2; + s->channels = ac3_channels[s->flags & 7]; + if (s->flags & AC3_LFE) + s->channels++; + if (s->channels < avctx->channels) { + fprintf(stderr, "Source channels are less than specified: output to %d channels..\n", s->channels); + avctx->channels = s->channels; + } avctx->bit_rate = bit_rate; } } @@ -128,11 +127,14 @@ s->inbuf_ptr += len; buf_size -= len; } else { +#if 0 if (avctx->channels == 1) flags = AC3_MONO; else flags = AC3_STEREO; - +#else + flags = s->flags; +#endif flags |= AC3_ADJUST_LEVEL; level = 1; if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) { @@ -144,10 +146,7 @@ for (i = 0; i < 6; i++) { if (ac3_block (&s->state)) goto fail; - if (avctx->channels == 1) - float_to_int_mono (*samples, out_samples + i * 256); - else - float_to_int (*samples, out_samples + i * 512); + float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels); } s->inbuf_ptr = s->inbuf; s->frame_size = 0;
--- a/ac3enc.c Sun Apr 07 21:44:29 2002 +0000 +++ b/ac3enc.c Mon Apr 08 12:08:03 2002 +0000 @@ -93,7 +93,7 @@ assumptions. */ void parametric_bit_allocation(AC3EncodeContext *s, UINT8 *bap, INT8 *exp, int start, int end, - int snroffset, int fgain) + int snroffset, int fgain, int is_lfe) { int bin,i,j,k,end1,v,v1,bndstrt,bndend,lowcomp,begin; int fastleak,slowleak,address,tmp; @@ -146,21 +146,25 @@ excite[1] = bndpsd[1] - fgain - lowcomp ; begin = 7 ; for (bin = 2; bin < 7; bin++) { - lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1]) ; + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1]) ; fastleak = bndpsd[bin] - fgain ; slowleak = bndpsd[bin] - s->sgain ; excite[bin] = fastleak - lowcomp ; - if (bndpsd[bin] <= bndpsd[bin+1]) { - begin = bin + 1 ; - break ; - } + if (!(is_lfe && bin == 6)) { + if (bndpsd[bin] <= bndpsd[bin+1]) { + begin = bin + 1 ; + break ; + } + } } end1=bndend; if (end1 > 22) end1=22; for (bin = begin; bin < end1; bin++) { - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin) ; + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin) ; fastleak -= s->fdecay ; v = bndpsd[bin] - fgain; @@ -395,7 +399,7 @@ static void compute_exp_strategy(UINT8 exp_strategy[NB_BLOCKS][AC3_MAX_CHANNELS], UINT8 exp[NB_BLOCKS][AC3_MAX_CHANNELS][N/2], - int ch) + int ch, int is_lfe) { int i, j; int exp_diff; @@ -413,6 +417,9 @@ 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; @@ -432,7 +439,7 @@ exp_strategy[i][ch] = EXP_D15; break; } - i = j; + i = j; } } @@ -593,12 +600,13 @@ s->mant1_cnt = 0; s->mant2_cnt = 0; s->mant4_cnt = 0; - for(ch=0;ch<s->nb_channels;ch++) { + for(ch=0;ch<s->nb_all_channels;ch++) { parametric_bit_allocation(s, bap[i][ch], (INT8 *)encoded_exp[i][ch], 0, s->nb_coefs[ch], (((csnroffst-15) << 4) + fsnroffst) << 2, - fgaintab[s->fgaincod[ch]]); + fgaintab[s->fgaincod[ch]], + ch == s->lfe_channel); frame_bits += compute_mantissa_size(s, bap[i][ch], s->nb_coefs[ch]); } @@ -622,6 +630,7 @@ int i, ch; int csnroffst, fsnroffst; UINT8 bap1[NB_BLOCKS][AC3_MAX_CHANNELS][N/2]; + static int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; /* init default parameters */ s->sdecaycod = 2; @@ -629,7 +638,7 @@ s->sgaincod = 1; s->dbkneecod = 2; s->floorcod = 4; - for(ch=0;ch<s->nb_channels;ch++) + for(ch=0;ch<s->nb_all_channels;ch++) s->fgaincod[ch] = 4; /* compute real values */ @@ -641,18 +650,21 @@ /* header size */ frame_bits += 65; - if (s->acmod == 2) - frame_bits += 2; + // if (s->acmod == 2) + // frame_bits += 2; + frame_bits += frame_bits_inc[s->acmod]; /* audio blocks */ for(i=0;i<NB_BLOCKS;i++) { - frame_bits += s->nb_channels * 2 + 2; + frame_bits += s->nb_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ if (s->acmod == 2) - frame_bits++; - frame_bits += 2 * s->nb_channels; + frame_bits++; /* rematstr */ + frame_bits += 2 * s->nb_channels; /* chexpstr[2] * c */ + if (s->lfe) + frame_bits++; /* lfeexpstr */ for(ch=0;ch<s->nb_channels;ch++) { if (exp_strategy[i][ch] != EXP_REUSE) - frame_bits += 6 + 2; + frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */ } frame_bits++; /* baie */ frame_bits++; /* snr */ @@ -660,7 +672,10 @@ } frame_bits++; /* cplinu for block 0 */ /* bit alloc info */ - frame_bits += 2*4 + 3 + 6 + s->nb_channels * (4 + 3); + /* sdcycod[2], fdcycod[2], sgaincod[2], dbpbcod[2], floorcod[3] */ + /* csnroffset[6] */ + /* (fsnoffset[4] + fgaincod[4]) * c */ + frame_bits += 2*4 + 3 + 6 + s->nb_all_channels * (4 + 3); /* CRC */ frame_bits += 16; @@ -670,11 +685,11 @@ csnroffst = s->csnroffst; while (csnroffst >= 0 && - bit_alloc(s, bap, encoded_exp, exp_strategy, frame_bits, csnroffst, 0) < 0) - csnroffst -= SNR_INC1; + bit_alloc(s, bap, encoded_exp, exp_strategy, frame_bits, csnroffst, 0) < 0) + csnroffst -= SNR_INC1; if (csnroffst < 0) { - fprintf(stderr, "Error !!!\n"); - return -1; + fprintf(stderr, "Yack, Error !!!\n"); + return -1; } while ((csnroffst + SNR_INC1) <= 63 && bit_alloc(s, bap1, encoded_exp, exp_strategy, frame_bits, @@ -703,14 +718,14 @@ } s->csnroffst = csnroffst; - for(ch=0;ch<s->nb_channels;ch++) + for(ch=0;ch<s->nb_all_channels;ch++) s->fsnroffst[ch] = fsnroffst; #if defined(DEBUG_BITALLOC) { int j; for(i=0;i<6;i++) { - for(ch=0;ch<s->nb_channels;ch++) { + for(ch=0;ch<s->nb_all_channels;ch++) { printf("Block #%d Ch%d:\n", i, ch); printf("bap="); for(j=0;j<s->nb_coefs[ch];j++) { @@ -733,18 +748,26 @@ int i, j, k, l, ch, v; float alpha; static unsigned short freqs[3] = { 48000, 44100, 32000 }; + static int acmod_defs[6] = { + 0x01, /* C */ + 0x02, /* L R */ + 0x03, /* L C R */ + 0x06, /* L R SL SR */ + 0x07, /* L C R SL SR */ + 0x07, /* L C R SL SR (+LFE) */ + }; avctx->frame_size = AC3_FRAME_SIZE; avctx->key_frame = 1; /* always key frame */ /* number of channels */ - if (channels == 1) - s->acmod = 1; - else if (channels == 2) - s->acmod = 2; - else - return -1; - s->nb_channels = channels; + if (channels < 1 || channels > 6) + return -1; + s->acmod = acmod_defs[channels - 1]; + s->lfe = (channels == 6) ? 1 : 0; + s->nb_all_channels = channels; + s->nb_channels = channels > 5 ? 5 : channels; + s->lfe_channel = s->lfe ? 5 : -1; /* frequency */ for(i=0;i<3;i++) { @@ -782,6 +805,9 @@ s->chbwcod[ch] = 50; /* sample bandwidth as mpeg audio layer 2 table 0 */ s->nb_coefs[ch] = ((s->chbwcod[ch] + 12) * 3) + 37; } + if (s->lfe) { + s->nb_coefs[s->lfe_channel] = 7; /* fixed */ + } /* initial snr offset */ s->csnroffst = 40; @@ -821,10 +847,13 @@ put_bits(&s->pb, 5, s->bsid); put_bits(&s->pb, 3, s->bsmod); put_bits(&s->pb, 3, s->acmod); - if (s->acmod == 2) { + if ((s->acmod & 0x01) && s->acmod != 0x01) + put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ + if (s->acmod & 0x04) + put_bits(&s->pb, 2, 1); /* XXX -6 dB */ + if (s->acmod == 0x02) put_bits(&s->pb, 2, 0); /* surround not indicated */ - } - put_bits(&s->pb, 1, 0); /* no LFE */ + put_bits(&s->pb, 1, s->lfe); /* LFE */ put_bits(&s->pb, 5, 31); /* dialog norm: -31 db */ put_bits(&s->pb, 1, 0); /* no compression control word */ put_bits(&s->pb, 1, 0); /* no lang code */ @@ -920,13 +949,17 @@ put_bits(&s->pb, 2, exp_strategy[ch]); } + if (s->lfe) { + put_bits(&s->pb, 1, exp_strategy[s->lfe_channel]); + } + for(ch=0;ch<s->nb_channels;ch++) { if (exp_strategy[ch] != EXP_REUSE) put_bits(&s->pb, 6, s->chbwcod[ch]); } /* exponents */ - for (ch = 0; ch < s->nb_channels; ch++) { + for (ch = 0; ch < s->nb_all_channels; ch++) { switch(exp_strategy[ch]) { case EXP_REUSE: continue; @@ -941,7 +974,7 @@ group_size = 4; break; } - nb_groups = (s->nb_coefs[ch] + (group_size * 3) - 4) / (3 * group_size); + nb_groups = (s->nb_coefs[ch] + (group_size * 3) - 4) / (3 * group_size); p = encoded_exp[ch]; /* first exponent */ @@ -969,7 +1002,8 @@ put_bits(&s->pb, 7, ((delta0 * 5 + delta1) * 5) + delta2); } - put_bits(&s->pb, 2, 0); /* no gain range info */ + if (ch != s->lfe_channel) + put_bits(&s->pb, 2, 0); /* no gain range info */ } /* bit allocation info */ @@ -987,7 +1021,7 @@ put_bits(&s->pb, 1, baie); /* always present with bai */ if (baie) { put_bits(&s->pb, 6, s->csnroffst); - for(ch=0;ch<s->nb_channels;ch++) { + for(ch=0;ch<s->nb_all_channels;ch++) { put_bits(&s->pb, 4, s->fsnroffst[ch]); put_bits(&s->pb, 3, s->fgaincod[ch]); } @@ -1004,7 +1038,7 @@ mant1_cnt = mant2_cnt = mant4_cnt = 0; qmant1_ptr = qmant2_ptr = qmant4_ptr = NULL; - for (ch = 0; ch < s->nb_channels; ch++) { + for (ch = 0; ch < s->nb_all_channels; ch++) { int b, c, e, v; for(i=0;i<s->nb_coefs[ch];i++) { @@ -1091,7 +1125,7 @@ } /* second pass : output the values */ - for (ch = 0; ch < s->nb_channels; ch++) { + for (ch = 0; ch < s->nb_all_channels; ch++) { int b, q; for(i=0;i<s->nb_coefs[ch];i++) { @@ -1265,7 +1299,7 @@ int frame_bits; frame_bits = 0; - for(ch=0;ch<s->nb_channels;ch++) { + for(ch=0;ch<s->nb_all_channels;ch++) { /* fixed mdct to the six sub blocks & exponent computation */ for(i=0;i<NB_BLOCKS;i++) { INT16 *sptr; @@ -1273,7 +1307,7 @@ /* compute input samples */ memcpy(input_samples, s->last_samples[ch], N/2 * sizeof(INT16)); - sinc = s->nb_channels; + sinc = s->nb_all_channels; sptr = samples + (sinc * (N/2) * i) + ch; for(j=0;j<N/2;j++) { v = *sptr; @@ -1319,7 +1353,7 @@ } } - compute_exp_strategy(exp_strategy, exp, ch); + compute_exp_strategy(exp_strategy, exp, ch, ch == s->lfe_channel); /* compute the exponents as the decoder will see them. The EXP_REUSE case must be handled carefully : we select the
--- a/ac3enc.h Sun Apr 07 21:44:29 2002 +0000 +++ b/ac3enc.h Mon Apr 08 12:08:03 2002 +0000 @@ -1,12 +1,13 @@ #define AC3_FRAME_SIZE (6*256) #define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ -#define AC3_MAX_CHANNELS 2 /* we handle at most two channels, although - AC3 allows 6 channels */ +#define AC3_MAX_CHANNELS 6 typedef struct AC3EncodeContext { PutBitContext pb; int nb_channels; + int nb_all_channels; + int lfe_channel; int bit_rate; int sample_rate; int bsid; @@ -16,6 +17,7 @@ int frmsizecod; int fscod; /* frequency */ int acmod; + int lfe; int bsmod; short last_samples[AC3_MAX_CHANNELS][256]; int chbwcod[AC3_MAX_CHANNELS];