diff options
author | Zdenek Kabelac <kabi@informatics.muni.cz> | 2002-04-08 12:08:03 +0000 |
---|---|---|
committer | Zdenek Kabelac <kabi@informatics.muni.cz> | 2002-04-08 12:08:03 +0000 |
commit | 30b68f33aa5f6480b4271820c228438e2e6e79eb (patch) | |
tree | c64ac04fdc3aa66af5bd8b4421947d020ce67db4 /libavcodec/ac3dec.c | |
parent | 10bb7023a224adbcd2b97d5115db57bf13094906 (diff) | |
download | ffmpeg-30b68f33aa5f6480b4271820c228438e2e6e79eb.tar.gz |
* encoding of AC3 with more than 2 channels
by Takashi Iwai <tiwai@suse.de>
Originally committed as revision 383 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/ac3dec.c')
-rw-r--r-- | libavcodec/ac3dec.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index bdf5b31586..c0d801da2d 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -26,6 +26,7 @@ typedef struct AC3DecodeState { UINT8 *inbuf_ptr; int frame_size; int flags; + int channels; ac3_state_t state; } AC3DecodeState; @@ -52,24 +53,16 @@ static inline int blah (int32_t i) 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 @@ static int ac3_decode_frame(AVCodecContext *avctx, 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 @@ static int ac3_decode_frame(AVCodecContext *avctx, 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 @@ static int ac3_decode_frame(AVCodecContext *avctx, 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 @@ static int ac3_decode_frame(AVCodecContext *avctx, 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; |