annotate ac3dec.c @ 625:bb6a69f9d409 libavcodec

slow but accurate integer dct from IJG (should be ok with the LGPL as the old DCT is the fast integer DCT from IJG) per context DCT selection
author michaelni
date Thu, 29 Aug 2002 23:55:32 +0000
parents 718a22dc121f
children b32afefe7d33
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
1 /*
986e461dc072 Initial revision
glantau
parents:
diff changeset
2 * AC3 decoder
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
3 * Copyright (c) 2001 Fabrice Bellard.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
4 *
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
5 * This library is free software; you can redistribute it and/or
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
7 * License as published by the Free Software Foundation; either
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
8 * version 2 of the License, or (at your option) any later version.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
9 *
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
10 * This library is distributed in the hope that it will be useful,
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
13 * Lesser General Public License for more details.
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
14 *
429
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
16 * License along with this library; if not, write to the Free Software
718a22dc121f license/copyright change
glantau
parents: 323
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
18 */
986e461dc072 Initial revision
glantau
parents:
diff changeset
19 #include "avcodec.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
20 #include "libac3/ac3.h"
986e461dc072 Initial revision
glantau
parents:
diff changeset
21
986e461dc072 Initial revision
glantau
parents:
diff changeset
22 /* currently, I use libac3 which is Copyright (C) Aaron Holtzman and
986e461dc072 Initial revision
glantau
parents:
diff changeset
23 released under the GPL license. I may reimplement it someday... */
986e461dc072 Initial revision
glantau
parents:
diff changeset
24 typedef struct AC3DecodeState {
986e461dc072 Initial revision
glantau
parents:
diff changeset
25 UINT8 inbuf[4096]; /* input buffer */
986e461dc072 Initial revision
glantau
parents:
diff changeset
26 UINT8 *inbuf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
27 int frame_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
28 int flags;
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
29 int channels;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
30 ac3_state_t state;
986e461dc072 Initial revision
glantau
parents:
diff changeset
31 } AC3DecodeState;
986e461dc072 Initial revision
glantau
parents:
diff changeset
32
986e461dc072 Initial revision
glantau
parents:
diff changeset
33 static int ac3_decode_init(AVCodecContext *avctx)
986e461dc072 Initial revision
glantau
parents:
diff changeset
34 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
35 AC3DecodeState *s = avctx->priv_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
36
986e461dc072 Initial revision
glantau
parents:
diff changeset
37 ac3_init ();
986e461dc072 Initial revision
glantau
parents:
diff changeset
38 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
39 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
40 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
41 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
42
986e461dc072 Initial revision
glantau
parents:
diff changeset
43 stream_samples_t samples;
986e461dc072 Initial revision
glantau
parents:
diff changeset
44
986e461dc072 Initial revision
glantau
parents:
diff changeset
45 /**** the following two functions comes from ac3dec */
986e461dc072 Initial revision
glantau
parents:
diff changeset
46 static inline int blah (int32_t i)
986e461dc072 Initial revision
glantau
parents:
diff changeset
47 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
48 if (i > 0x43c07fff)
986e461dc072 Initial revision
glantau
parents:
diff changeset
49 return 32767;
986e461dc072 Initial revision
glantau
parents:
diff changeset
50 else if (i < 0x43bf8000)
986e461dc072 Initial revision
glantau
parents:
diff changeset
51 return -32768;
986e461dc072 Initial revision
glantau
parents:
diff changeset
52 else
986e461dc072 Initial revision
glantau
parents:
diff changeset
53 return i - 0x43c00000;
986e461dc072 Initial revision
glantau
parents:
diff changeset
54 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
55
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
56 static inline void float_to_int (float * _f, INT16 * s16, int nchannels)
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
57 {
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
58 int i, j, c;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
59 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format
986e461dc072 Initial revision
glantau
parents:
diff changeset
60
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
61 j = 0;
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
62 nchannels *= 256;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
63 for (i = 0; i < 256; i++) {
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
64 for (c = 0; c < nchannels; c += 256)
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
65 s16[j++] = blah (f[i + c]);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
66 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
67 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
68
986e461dc072 Initial revision
glantau
parents:
diff changeset
69 /**** end */
986e461dc072 Initial revision
glantau
parents:
diff changeset
70
986e461dc072 Initial revision
glantau
parents:
diff changeset
71 #define HEADER_SIZE 7
986e461dc072 Initial revision
glantau
parents:
diff changeset
72
986e461dc072 Initial revision
glantau
parents:
diff changeset
73 static int ac3_decode_frame(AVCodecContext *avctx,
986e461dc072 Initial revision
glantau
parents:
diff changeset
74 void *data, int *data_size,
986e461dc072 Initial revision
glantau
parents:
diff changeset
75 UINT8 *buf, int buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
76 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
77 AC3DecodeState *s = avctx->priv_data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
78 UINT8 *buf_ptr;
986e461dc072 Initial revision
glantau
parents:
diff changeset
79 int flags, i, len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
80 int sample_rate, bit_rate;
986e461dc072 Initial revision
glantau
parents:
diff changeset
81 short *out_samples = data;
986e461dc072 Initial revision
glantau
parents:
diff changeset
82 float level;
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
83 static const int ac3_channels[8] = {
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
84 2, 1, 2, 3, 3, 4, 4, 5
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
85 };
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
86
986e461dc072 Initial revision
glantau
parents:
diff changeset
87 *data_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
88 buf_ptr = buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
89 while (buf_size > 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
90 len = s->inbuf_ptr - s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
91 if (s->frame_size == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
92 /* no header seen : find one. We need at least 7 bytes to parse it */
986e461dc072 Initial revision
glantau
parents:
diff changeset
93 len = HEADER_SIZE - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
94 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
95 len = buf_size;
986e461dc072 Initial revision
glantau
parents:
diff changeset
96 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
97 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
98 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
99 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
100 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
101 len = ac3_syncinfo (s->inbuf, &s->flags, &sample_rate, &bit_rate);
986e461dc072 Initial revision
glantau
parents:
diff changeset
102 if (len == 0) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
103 /* no sync found : move by one byte (inefficient, but simple!) */
986e461dc072 Initial revision
glantau
parents:
diff changeset
104 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1);
986e461dc072 Initial revision
glantau
parents:
diff changeset
105 s->inbuf_ptr--;
986e461dc072 Initial revision
glantau
parents:
diff changeset
106 } else {
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
107 s->frame_size = len;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
108 /* update codec info */
986e461dc072 Initial revision
glantau
parents:
diff changeset
109 avctx->sample_rate = sample_rate;
314
289eb941b8ba * encoding of AC3 with more than 2 channels
kabi
parents: 64
diff changeset
110 s->channels = ac3_channels[s->flags & 7];
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
111 if (s->flags & AC3_LFE)
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
112 s->channels++;
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
113 if (avctx->channels == 0)
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
114 /* No specific number of channel requested */
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
115 avctx->channels = s->channels;
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
116 else if (s->channels < avctx->channels) {
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
117 fprintf(stderr, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len);
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
118 avctx->channels = s->channels;
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
119 }
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
120 avctx->bit_rate = bit_rate;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
121 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
122 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
123 } else if (len < s->frame_size) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
124 len = s->frame_size - len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
125 if (len > buf_size)
986e461dc072 Initial revision
glantau
parents:
diff changeset
126 len = buf_size;
323
68cc7650c645 * minor - slightly modified debug message
kabi
parents: 318
diff changeset
127
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
128 memcpy(s->inbuf_ptr, buf_ptr, len);
986e461dc072 Initial revision
glantau
parents:
diff changeset
129 buf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
130 s->inbuf_ptr += len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
131 buf_size -= len;
986e461dc072 Initial revision
glantau
parents:
diff changeset
132 } else {
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
133 flags = s->flags;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
134 if (avctx->channels == 1)
986e461dc072 Initial revision
glantau
parents:
diff changeset
135 flags = AC3_MONO;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
136 else if (avctx->channels == 2)
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
137 flags = AC3_STEREO;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
138 else
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
139 flags |= AC3_ADJUST_LEVEL;
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
140 level = 1;
986e461dc072 Initial revision
glantau
parents:
diff changeset
141 if (ac3_frame (&s->state, s->inbuf, &flags, &level, 384)) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
142 fail:
986e461dc072 Initial revision
glantau
parents:
diff changeset
143 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
144 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
145 continue;
986e461dc072 Initial revision
glantau
parents:
diff changeset
146 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
147 for (i = 0; i < 6; i++) {
986e461dc072 Initial revision
glantau
parents:
diff changeset
148 if (ac3_block (&s->state))
986e461dc072 Initial revision
glantau
parents:
diff changeset
149 goto fail;
318
21697f35a9ca - Fixed AC3 decoding for 5:1 AC3 streams. Now when calling av_audio_decode for
pulento
parents: 314
diff changeset
150 float_to_int (*samples, out_samples + i * 256 * avctx->channels, avctx->channels);
0
986e461dc072 Initial revision
glantau
parents:
diff changeset
151 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
152 s->inbuf_ptr = s->inbuf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
153 s->frame_size = 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
154 *data_size = 6 * avctx->channels * 256 * sizeof(INT16);
986e461dc072 Initial revision
glantau
parents:
diff changeset
155 break;
986e461dc072 Initial revision
glantau
parents:
diff changeset
156 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
157 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
158 return buf_ptr - buf;
986e461dc072 Initial revision
glantau
parents:
diff changeset
159 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
160
986e461dc072 Initial revision
glantau
parents:
diff changeset
161 static int ac3_decode_end(AVCodecContext *s)
986e461dc072 Initial revision
glantau
parents:
diff changeset
162 {
986e461dc072 Initial revision
glantau
parents:
diff changeset
163 return 0;
986e461dc072 Initial revision
glantau
parents:
diff changeset
164 }
986e461dc072 Initial revision
glantau
parents:
diff changeset
165
986e461dc072 Initial revision
glantau
parents:
diff changeset
166 AVCodec ac3_decoder = {
986e461dc072 Initial revision
glantau
parents:
diff changeset
167 "ac3",
986e461dc072 Initial revision
glantau
parents:
diff changeset
168 CODEC_TYPE_AUDIO,
986e461dc072 Initial revision
glantau
parents:
diff changeset
169 CODEC_ID_AC3,
986e461dc072 Initial revision
glantau
parents:
diff changeset
170 sizeof(AC3DecodeState),
986e461dc072 Initial revision
glantau
parents:
diff changeset
171 ac3_decode_init,
986e461dc072 Initial revision
glantau
parents:
diff changeset
172 NULL,
986e461dc072 Initial revision
glantau
parents:
diff changeset
173 ac3_decode_end,
986e461dc072 Initial revision
glantau
parents:
diff changeset
174 ac3_decode_frame,
986e461dc072 Initial revision
glantau
parents:
diff changeset
175 };