Mercurial > libavcodec.hg
annotate a52dec.c @ 787:4914252c963a libavcodec
postprocessing cleanup:
remove opendivx #ifdefs
remove rk1 filter
remove unused / obsolete stuff
add -1,4,2,4,-1 deinterlacing filter (ffmpeg uses that)
threadsafe / no more non-const globals
some optimizations
different strides for Y,U,V possible
remove ebx usage (someone really should fix gcc, this is really lame)
change the dering filter slightly (tell me if its worse for any files)
author | michael |
---|---|
date | Mon, 28 Oct 2002 19:30:58 +0000 |
parents | 718a22dc121f |
children | e113a950c074 |
rev | line source |
---|---|
332 | 1 /* |
2 * A52 decoder | |
429 | 3 * Copyright (c) 2001 Fabrice Bellard. |
332 | 4 * |
429 | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
332 | 9 * |
429 | 10 * This library is distributed in the hope that it will be useful, |
332 | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Lesser General Public License for more details. | |
332 | 14 * |
429 | 15 * You should have received a copy of the GNU Lesser General Public |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
332 | 18 */ |
19 #include "avcodec.h" | |
20 #include "liba52/a52.h" | |
21 | |
338 | 22 #ifdef CONFIG_A52BIN |
332 | 23 #include <dlfcn.h> |
24 static const char* liba52name = "liba52.so.0"; | |
25 #endif | |
26 | |
27 /** | |
28 * liba52 - Copyright (C) Aaron Holtzman | |
29 * released under the GPL license. | |
30 */ | |
31 typedef struct AC3DecodeState { | |
32 UINT8 inbuf[4096]; /* input buffer */ | |
33 UINT8 *inbuf_ptr; | |
34 int frame_size; | |
35 int flags; | |
36 int channels; | |
37 a52_state_t* state; | |
38 sample_t* samples; | |
39 | |
40 /* | |
41 * virtual method table | |
42 * | |
43 * using this function table so the liba52 doesn't | |
44 * have to be really linked together with ffmpeg | |
45 * and might be linked in runtime - this allows binary | |
46 * distribution of ffmpeg library which doens't depend | |
47 * on liba52 library - but if user has it installed | |
48 * it will be used - user might install such library | |
49 * separately | |
50 */ | |
51 void* handle; | |
52 a52_state_t* (*a52_init)(uint32_t mm_accel); | |
53 sample_t* (*a52_samples)(a52_state_t * state); | |
54 int (*a52_syncinfo)(uint8_t * buf, int * flags, | |
55 int * sample_rate, int * bit_rate); | |
56 int (*a52_frame)(a52_state_t * state, uint8_t * buf, int * flags, | |
57 sample_t * level, sample_t bias); | |
58 void (*a52_dynrng)(a52_state_t * state, | |
59 sample_t (* call) (sample_t, void *), void * data); | |
60 int (*a52_block)(a52_state_t * state); | |
61 void (*a52_free)(a52_state_t * state); | |
62 | |
63 } AC3DecodeState; | |
64 | |
338 | 65 #ifdef CONFIG_A52BIN |
332 | 66 static void* dlsymm(void* handle, const char* symbol) |
67 { | |
68 void* f = dlsym(handle, symbol); | |
69 if (!f) | |
70 fprintf(stderr, "A52 Decoder - function '%s' can't be resolved\n", symbol); | |
71 return f; | |
72 } | |
73 #endif | |
74 | |
75 static int a52_decode_init(AVCodecContext *avctx) | |
76 { | |
77 AC3DecodeState *s = avctx->priv_data; | |
78 | |
338 | 79 #ifdef CONFIG_A52BIN |
332 | 80 s->handle = dlopen(liba52name, RTLD_LAZY); |
81 if (!s->handle) | |
82 { | |
368
1db6950d81ea
- Segfault fixed when liba52 dynamic library isn't found.
pulento
parents:
338
diff
changeset
|
83 fprintf(stderr, "A52 library %s could not be opened! \n%s\n", liba52name, dlerror()); |
332 | 84 return -1; |
85 } | |
86 s->a52_init = (a52_state_t* (*)(uint32_t)) dlsymm(s->handle, "a52_init"); | |
87 s->a52_samples = (sample_t* (*)(a52_state_t*)) dlsymm(s->handle, "a52_samples"); | |
88 s->a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsymm(s->handle, "a52_syncinfo"); | |
89 s->a52_frame = (int (*)(a52_state_t*, uint8_t*, int*, sample_t*, sample_t)) dlsymm(s->handle, "a52_frame"); | |
90 s->a52_block = (int (*)(a52_state_t*)) dlsymm(s->handle, "a52_block"); | |
91 s->a52_free = (void (*)(a52_state_t*)) dlsymm(s->handle, "a52_free"); | |
92 if (!s->a52_init || !s->a52_samples || !s->a52_syncinfo | |
93 || !s->a52_frame || !s->a52_block || !s->a52_free) | |
94 { | |
95 dlclose(s->handle); | |
96 return -1; | |
97 } | |
98 #else | |
99 /* static linked version */ | |
100 s->handle = 0; | |
101 s->a52_init = a52_init; | |
102 s->a52_samples = a52_samples; | |
103 s->a52_syncinfo = a52_syncinfo; | |
104 s->a52_frame = a52_frame; | |
105 s->a52_block = a52_block; | |
106 s->a52_free = a52_free; | |
107 #endif | |
108 s->state = s->a52_init(0); /* later use CPU flags */ | |
109 s->samples = s->a52_samples(s->state); | |
110 s->inbuf_ptr = s->inbuf; | |
111 s->frame_size = 0; | |
112 | |
113 return 0; | |
114 } | |
115 | |
116 /**** the following two functions comes from a52dec */ | |
117 static inline int blah (int32_t i) | |
118 { | |
119 if (i > 0x43c07fff) | |
120 return 32767; | |
121 else if (i < 0x43bf8000) | |
122 return -32768; | |
123 return i - 0x43c00000; | |
124 } | |
125 | |
126 static inline void float_to_int (float * _f, INT16 * s16, int nchannels) | |
127 { | |
128 int i, j, c; | |
129 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format | |
130 | |
131 j = 0; | |
132 nchannels *= 256; | |
133 for (i = 0; i < 256; i++) { | |
134 for (c = 0; c < nchannels; c += 256) | |
135 s16[j++] = blah (f[i + c]); | |
136 } | |
137 } | |
138 | |
139 /**** end */ | |
140 | |
141 #define HEADER_SIZE 7 | |
142 | |
143 static int a52_decode_frame(AVCodecContext *avctx, | |
144 void *data, int *data_size, | |
145 UINT8 *buf, int buf_size) | |
146 { | |
147 AC3DecodeState *s = avctx->priv_data; | |
148 UINT8 *buf_ptr; | |
149 int flags, i, len; | |
150 int sample_rate, bit_rate; | |
151 short *out_samples = data; | |
152 float level; | |
153 static const int ac3_channels[8] = { | |
154 2, 1, 2, 3, 3, 4, 4, 5 | |
155 }; | |
156 | |
157 *data_size = 0; | |
158 buf_ptr = buf; | |
159 while (buf_size > 0) { | |
160 len = s->inbuf_ptr - s->inbuf; | |
161 if (s->frame_size == 0) { | |
162 /* no header seen : find one. We need at least 7 bytes to parse it */ | |
163 len = HEADER_SIZE - len; | |
164 if (len > buf_size) | |
165 len = buf_size; | |
166 memcpy(s->inbuf_ptr, buf_ptr, len); | |
167 buf_ptr += len; | |
168 s->inbuf_ptr += len; | |
169 buf_size -= len; | |
170 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) { | |
171 len = s->a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
172 if (len == 0) { | |
173 /* no sync found : move by one byte (inefficient, but simple!) */ | |
174 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1); | |
175 s->inbuf_ptr--; | |
176 } else { | |
177 s->frame_size = len; | |
178 /* update codec info */ | |
179 avctx->sample_rate = sample_rate; | |
180 s->channels = ac3_channels[s->flags & 7]; | |
181 if (s->flags & A52_LFE) | |
182 s->channels++; | |
183 if (avctx->channels == 0) | |
184 /* No specific number of channel requested */ | |
185 avctx->channels = s->channels; | |
186 else if (s->channels < avctx->channels) { | |
187 fprintf(stderr, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len); | |
188 avctx->channels = s->channels; | |
189 } | |
190 avctx->bit_rate = bit_rate; | |
191 } | |
192 } | |
193 } else if (len < s->frame_size) { | |
194 len = s->frame_size - len; | |
195 if (len > buf_size) | |
196 len = buf_size; | |
197 | |
198 memcpy(s->inbuf_ptr, buf_ptr, len); | |
199 buf_ptr += len; | |
200 s->inbuf_ptr += len; | |
201 buf_size -= len; | |
202 } else { | |
203 flags = s->flags; | |
204 if (avctx->channels == 1) | |
205 flags = A52_MONO; | |
206 else if (avctx->channels == 2) | |
207 flags = A52_STEREO; | |
208 else | |
209 flags |= A52_ADJUST_LEVEL; | |
210 level = 1; | |
211 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { | |
212 fail: | |
213 s->inbuf_ptr = s->inbuf; | |
214 s->frame_size = 0; | |
215 continue; | |
216 } | |
217 for (i = 0; i < 6; i++) { | |
218 if (s->a52_block(s->state)) | |
219 goto fail; | |
220 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); | |
221 } | |
222 s->inbuf_ptr = s->inbuf; | |
223 s->frame_size = 0; | |
224 *data_size = 6 * avctx->channels * 256 * sizeof(INT16); | |
225 break; | |
226 } | |
227 } | |
228 return buf_ptr - buf; | |
229 } | |
230 | |
231 static int a52_decode_end(AVCodecContext *avctx) | |
232 { | |
233 AC3DecodeState *s = avctx->priv_data; | |
234 s->a52_free(s->state); | |
338 | 235 #ifdef CONFIG_A52BIN |
332 | 236 dlclose(s->handle); |
237 #endif | |
238 return 0; | |
239 } | |
240 | |
241 AVCodec ac3_decoder = { | |
242 "ac3", | |
243 CODEC_TYPE_AUDIO, | |
244 CODEC_ID_AC3, | |
245 sizeof(AC3DecodeState), | |
246 a52_decode_init, | |
247 NULL, | |
248 a52_decode_end, | |
249 a52_decode_frame, | |
250 }; |