Mercurial > libavcodec.hg
annotate a52dec.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | bc434522dfc2 |
rev | line source |
---|---|
332 | 1 /* |
2 * A52 decoder | |
429 | 3 * Copyright (c) 2001 Fabrice Bellard. |
332 | 4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
429 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
332 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
332 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Lesser General Public License for more details. | |
332 | 16 * |
429 | 17 * You should have received a copy of the GNU Lesser General Public |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3059
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
332 | 20 */ |
1106 | 21 |
22 /** | |
23 * @file a52dec.c | |
24 * A52 decoder. | |
25 */ | |
26 | |
332 | 27 #include "avcodec.h" |
28 #include "liba52/a52.h" | |
29 | |
338 | 30 #ifdef CONFIG_A52BIN |
332 | 31 #include <dlfcn.h> |
32 static const char* liba52name = "liba52.so.0"; | |
33 #endif | |
34 | |
35 /** | |
36 * liba52 - Copyright (C) Aaron Holtzman | |
37 * released under the GPL license. | |
38 */ | |
39 typedef struct AC3DecodeState { | |
1064 | 40 uint8_t inbuf[4096]; /* input buffer */ |
41 uint8_t *inbuf_ptr; | |
332 | 42 int frame_size; |
43 int flags; | |
44 int channels; | |
45 a52_state_t* state; | |
46 sample_t* samples; | |
47 | |
48 /* | |
49 * virtual method table | |
50 * | |
51 * using this function table so the liba52 doesn't | |
52 * have to be really linked together with ffmpeg | |
53 * and might be linked in runtime - this allows binary | |
54 * distribution of ffmpeg library which doens't depend | |
55 * on liba52 library - but if user has it installed | |
56 * it will be used - user might install such library | |
57 * separately | |
58 */ | |
59 void* handle; | |
60 a52_state_t* (*a52_init)(uint32_t mm_accel); | |
61 sample_t* (*a52_samples)(a52_state_t * state); | |
62 int (*a52_syncinfo)(uint8_t * buf, int * flags, | |
2979 | 63 int * sample_rate, int * bit_rate); |
332 | 64 int (*a52_frame)(a52_state_t * state, uint8_t * buf, int * flags, |
2979 | 65 sample_t * level, sample_t bias); |
332 | 66 void (*a52_dynrng)(a52_state_t * state, |
2979 | 67 sample_t (* call) (sample_t, void *), void * data); |
332 | 68 int (*a52_block)(a52_state_t * state); |
69 void (*a52_free)(a52_state_t * state); | |
70 | |
71 } AC3DecodeState; | |
72 | |
338 | 73 #ifdef CONFIG_A52BIN |
332 | 74 static void* dlsymm(void* handle, const char* symbol) |
75 { | |
76 void* f = dlsym(handle, symbol); | |
77 if (!f) | |
2846
40765c51a7a9
Compilation fixes part 1 patch by (Arvind R. and Burkhard Plaum, plaum, ipf uni-stuttgart de)
michael
parents:
2028
diff
changeset
|
78 av_log( NULL, AV_LOG_ERROR, "A52 Decoder - function '%s' can't be resolved\n", symbol); |
332 | 79 return f; |
80 } | |
81 #endif | |
82 | |
83 static int a52_decode_init(AVCodecContext *avctx) | |
84 { | |
85 AC3DecodeState *s = avctx->priv_data; | |
86 | |
338 | 87 #ifdef CONFIG_A52BIN |
332 | 88 s->handle = dlopen(liba52name, RTLD_LAZY); |
89 if (!s->handle) | |
90 { | |
2846
40765c51a7a9
Compilation fixes part 1 patch by (Arvind R. and Burkhard Plaum, plaum, ipf uni-stuttgart de)
michael
parents:
2028
diff
changeset
|
91 av_log( avctx, AV_LOG_ERROR, "A52 library %s could not be opened! \n%s\n", liba52name, dlerror()); |
332 | 92 return -1; |
93 } | |
94 s->a52_init = (a52_state_t* (*)(uint32_t)) dlsymm(s->handle, "a52_init"); | |
95 s->a52_samples = (sample_t* (*)(a52_state_t*)) dlsymm(s->handle, "a52_samples"); | |
96 s->a52_syncinfo = (int (*)(uint8_t*, int*, int*, int*)) dlsymm(s->handle, "a52_syncinfo"); | |
97 s->a52_frame = (int (*)(a52_state_t*, uint8_t*, int*, sample_t*, sample_t)) dlsymm(s->handle, "a52_frame"); | |
98 s->a52_block = (int (*)(a52_state_t*)) dlsymm(s->handle, "a52_block"); | |
99 s->a52_free = (void (*)(a52_state_t*)) dlsymm(s->handle, "a52_free"); | |
100 if (!s->a52_init || !s->a52_samples || !s->a52_syncinfo | |
101 || !s->a52_frame || !s->a52_block || !s->a52_free) | |
102 { | |
2979 | 103 dlclose(s->handle); |
332 | 104 return -1; |
105 } | |
106 #else | |
107 /* static linked version */ | |
108 s->handle = 0; | |
1018 | 109 s->a52_init = a52_init; |
110 s->a52_samples = a52_samples; | |
111 s->a52_syncinfo = a52_syncinfo; | |
112 s->a52_frame = a52_frame; | |
113 s->a52_block = a52_block; | |
114 s->a52_free = a52_free; | |
332 | 115 #endif |
116 s->state = s->a52_init(0); /* later use CPU flags */ | |
117 s->samples = s->a52_samples(s->state); | |
118 s->inbuf_ptr = s->inbuf; | |
119 s->frame_size = 0; | |
120 | |
121 return 0; | |
122 } | |
123 | |
124 /**** the following two functions comes from a52dec */ | |
125 static inline int blah (int32_t i) | |
126 { | |
127 if (i > 0x43c07fff) | |
2979 | 128 return 32767; |
332 | 129 else if (i < 0x43bf8000) |
2979 | 130 return -32768; |
332 | 131 return i - 0x43c00000; |
132 } | |
133 | |
1064 | 134 static inline void float_to_int (float * _f, int16_t * s16, int nchannels) |
332 | 135 { |
136 int i, j, c; | |
2979 | 137 int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format |
332 | 138 |
139 j = 0; | |
140 nchannels *= 256; | |
141 for (i = 0; i < 256; i++) { | |
2979 | 142 for (c = 0; c < nchannels; c += 256) |
143 s16[j++] = blah (f[i + c]); | |
332 | 144 } |
145 } | |
146 | |
147 /**** end */ | |
148 | |
149 #define HEADER_SIZE 7 | |
150 | |
151 static int a52_decode_frame(AVCodecContext *avctx, | |
152 void *data, int *data_size, | |
1064 | 153 uint8_t *buf, int buf_size) |
332 | 154 { |
155 AC3DecodeState *s = avctx->priv_data; | |
1064 | 156 uint8_t *buf_ptr; |
332 | 157 int flags, i, len; |
158 int sample_rate, bit_rate; | |
159 short *out_samples = data; | |
160 float level; | |
161 static const int ac3_channels[8] = { | |
2979 | 162 2, 1, 2, 3, 3, 4, 4, 5 |
332 | 163 }; |
164 | |
165 buf_ptr = buf; | |
166 while (buf_size > 0) { | |
167 len = s->inbuf_ptr - s->inbuf; | |
168 if (s->frame_size == 0) { | |
169 /* no header seen : find one. We need at least 7 bytes to parse it */ | |
170 len = HEADER_SIZE - len; | |
171 if (len > buf_size) | |
172 len = buf_size; | |
173 memcpy(s->inbuf_ptr, buf_ptr, len); | |
174 buf_ptr += len; | |
175 s->inbuf_ptr += len; | |
176 buf_size -= len; | |
177 if ((s->inbuf_ptr - s->inbuf) == HEADER_SIZE) { | |
178 len = s->a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
179 if (len == 0) { | |
180 /* no sync found : move by one byte (inefficient, but simple!) */ | |
181 memcpy(s->inbuf, s->inbuf + 1, HEADER_SIZE - 1); | |
182 s->inbuf_ptr--; | |
183 } else { | |
2979 | 184 s->frame_size = len; |
332 | 185 /* update codec info */ |
186 avctx->sample_rate = sample_rate; | |
187 s->channels = ac3_channels[s->flags & 7]; | |
188 if (s->flags & A52_LFE) | |
2979 | 189 s->channels++; |
190 if (avctx->channels == 0) | |
191 /* No specific number of channel requested */ | |
192 avctx->channels = s->channels; | |
193 else if (s->channels < avctx->channels) { | |
194 av_log(avctx, AV_LOG_ERROR, "ac3dec: AC3 Source channels are less than specified: output to %d channels.. (frmsize: %d)\n", s->channels, len); | |
195 avctx->channels = s->channels; | |
196 } | |
197 avctx->bit_rate = bit_rate; | |
332 | 198 } |
199 } | |
200 } else if (len < s->frame_size) { | |
201 len = s->frame_size - len; | |
202 if (len > buf_size) | |
203 len = buf_size; | |
204 | |
205 memcpy(s->inbuf_ptr, buf_ptr, len); | |
206 buf_ptr += len; | |
207 s->inbuf_ptr += len; | |
208 buf_size -= len; | |
209 } else { | |
210 flags = s->flags; | |
211 if (avctx->channels == 1) | |
212 flags = A52_MONO; | |
213 else if (avctx->channels == 2) | |
214 flags = A52_STEREO; | |
215 else | |
216 flags |= A52_ADJUST_LEVEL; | |
217 level = 1; | |
218 if (s->a52_frame(s->state, s->inbuf, &flags, &level, 384)) { | |
219 fail: | |
220 s->inbuf_ptr = s->inbuf; | |
221 s->frame_size = 0; | |
222 continue; | |
223 } | |
224 for (i = 0; i < 6; i++) { | |
225 if (s->a52_block(s->state)) | |
226 goto fail; | |
227 float_to_int(s->samples, out_samples + i * 256 * avctx->channels, avctx->channels); | |
228 } | |
229 s->inbuf_ptr = s->inbuf; | |
230 s->frame_size = 0; | |
1064 | 231 *data_size = 6 * avctx->channels * 256 * sizeof(int16_t); |
332 | 232 break; |
233 } | |
234 } | |
235 return buf_ptr - buf; | |
236 } | |
237 | |
238 static int a52_decode_end(AVCodecContext *avctx) | |
239 { | |
240 AC3DecodeState *s = avctx->priv_data; | |
241 s->a52_free(s->state); | |
338 | 242 #ifdef CONFIG_A52BIN |
332 | 243 dlclose(s->handle); |
244 #endif | |
245 return 0; | |
246 } | |
247 | |
248 AVCodec ac3_decoder = { | |
249 "ac3", | |
250 CODEC_TYPE_AUDIO, | |
251 CODEC_ID_AC3, | |
252 sizeof(AC3DecodeState), | |
253 a52_decode_init, | |
254 NULL, | |
255 a52_decode_end, | |
256 a52_decode_frame, | |
257 }; |