Mercurial > libavcodec.hg
comparison libfaad.c @ 5101:c3f2379b80db libavcodec
Give all wrappers for external libraries names starting with lib.
author | diego |
---|---|
date | Wed, 06 Jun 2007 00:14:18 +0000 |
parents | faad.c@fd173be649b7 |
children | 49d225414a3f |
comparison
equal
deleted
inserted
replaced
5100:daff9ebd2e0b | 5101:c3f2379b80db |
---|---|
1 /* | |
2 * Faad decoder | |
3 * Copyright (c) 2003 Zdenek Kabelac. | |
4 * Copyright (c) 2004 Thomas Raivio. | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 /** | |
24 * @file faad.c | |
25 * AAC decoder. | |
26 * | |
27 * still a bit unfinished - but it plays something | |
28 */ | |
29 | |
30 #include "avcodec.h" | |
31 #include "faad.h" | |
32 | |
33 #ifndef FAADAPI | |
34 #define FAADAPI | |
35 #endif | |
36 | |
37 /* | |
38 * when CONFIG_LIBFAADBIN is defined the libfaad will be opened at runtime | |
39 */ | |
40 //#undef CONFIG_LIBFAADBIN | |
41 //#define CONFIG_LIBFAADBIN | |
42 | |
43 #ifdef CONFIG_LIBFAADBIN | |
44 #include <dlfcn.h> | |
45 static const char* libfaadname = "libfaad.so.0"; | |
46 #else | |
47 #define dlopen(a) | |
48 #define dlclose(a) | |
49 #endif | |
50 | |
51 typedef struct { | |
52 void* handle; /* dlopen handle */ | |
53 void* faac_handle; /* FAAD library handle */ | |
54 int sample_size; | |
55 int init; | |
56 | |
57 /* faad calls */ | |
58 faacDecHandle FAADAPI (*faacDecOpen)(void); | |
59 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); | |
60 #ifndef FAAD2_VERSION | |
61 int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, | |
62 faacDecConfigurationPtr config); | |
63 int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, | |
64 unsigned char *buffer, | |
65 unsigned long *samplerate, | |
66 unsigned long *channels); | |
67 int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, | |
68 unsigned long SizeOfDecoderSpecificInfo, | |
69 unsigned long *samplerate, unsigned long *channels); | |
70 int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, | |
71 unsigned char *buffer, | |
72 unsigned long *bytesconsumed, | |
73 short *sample_buffer, | |
74 unsigned long *samples); | |
75 #else | |
76 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, | |
77 faacDecConfigurationPtr config); | |
78 long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, | |
79 unsigned char *buffer, | |
80 unsigned long buffer_size, | |
81 unsigned long *samplerate, | |
82 unsigned char *channels); | |
83 char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, | |
84 unsigned long SizeOfDecoderSpecificInfo, | |
85 unsigned long *samplerate, unsigned char *channels); | |
86 void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, | |
87 faacDecFrameInfo *hInfo, | |
88 unsigned char *buffer, | |
89 unsigned long buffer_size); | |
90 char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); | |
91 #endif | |
92 | |
93 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); | |
94 | |
95 | |
96 } FAACContext; | |
97 | |
98 static const unsigned long faac_srates[] = | |
99 { | |
100 96000, 88200, 64000, 48000, 44100, 32000, | |
101 24000, 22050, 16000, 12000, 11025, 8000 | |
102 }; | |
103 | |
104 static int faac_init_mp4(AVCodecContext *avctx) | |
105 { | |
106 FAACContext *s = avctx->priv_data; | |
107 unsigned long samplerate; | |
108 #ifndef FAAD2_VERSION | |
109 unsigned long channels; | |
110 #else | |
111 unsigned char channels; | |
112 #endif | |
113 int r = 0; | |
114 | |
115 if (avctx->extradata){ | |
116 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata, | |
117 avctx->extradata_size, | |
118 &samplerate, &channels); | |
119 if (r < 0){ | |
120 av_log(avctx, AV_LOG_ERROR, | |
121 "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n", | |
122 r, samplerate, (long)channels, avctx->extradata_size); | |
123 } else { | |
124 avctx->sample_rate = samplerate; | |
125 avctx->channels = channels; | |
126 s->init = 1; | |
127 } | |
128 } | |
129 | |
130 return r; | |
131 } | |
132 | |
133 static int faac_decode_frame(AVCodecContext *avctx, | |
134 void *data, int *data_size, | |
135 uint8_t *buf, int buf_size) | |
136 { | |
137 FAACContext *s = avctx->priv_data; | |
138 #ifndef FAAD2_VERSION | |
139 unsigned long bytesconsumed; | |
140 short *sample_buffer = NULL; | |
141 unsigned long samples; | |
142 int out; | |
143 #else | |
144 faacDecFrameInfo frame_info; | |
145 void *out; | |
146 #endif | |
147 if(buf_size == 0) | |
148 return 0; | |
149 #ifndef FAAD2_VERSION | |
150 out = s->faacDecDecode(s->faac_handle, | |
151 (unsigned char*)buf, | |
152 &bytesconsumed, | |
153 data, | |
154 &samples); | |
155 samples *= s->sample_size; | |
156 if (data_size) | |
157 *data_size = samples; | |
158 return (buf_size < (int)bytesconsumed) | |
159 ? buf_size : (int)bytesconsumed; | |
160 #else | |
161 | |
162 if(!s->init){ | |
163 unsigned long srate; | |
164 unsigned char channels; | |
165 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); | |
166 if(r < 0){ | |
167 av_log(avctx, AV_LOG_ERROR, "faac: codec init failed: %s\n", | |
168 s->faacDecGetErrorMessage(frame_info.error)); | |
169 return -1; | |
170 } | |
171 avctx->sample_rate = srate; | |
172 avctx->channels = channels; | |
173 s->init = 1; | |
174 } | |
175 | |
176 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); | |
177 | |
178 if (frame_info.error > 0) { | |
179 av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n", | |
180 s->faacDecGetErrorMessage(frame_info.error)); | |
181 return -1; | |
182 } | |
183 | |
184 frame_info.samples *= s->sample_size; | |
185 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one | |
186 | |
187 if (data_size) | |
188 *data_size = frame_info.samples; | |
189 | |
190 return (buf_size < (int)frame_info.bytesconsumed) | |
191 ? buf_size : (int)frame_info.bytesconsumed; | |
192 #endif | |
193 } | |
194 | |
195 static int faac_decode_end(AVCodecContext *avctx) | |
196 { | |
197 FAACContext *s = avctx->priv_data; | |
198 | |
199 s->faacDecClose(s->faac_handle); | |
200 | |
201 dlclose(s->handle); | |
202 return 0; | |
203 } | |
204 | |
205 static int faac_decode_init(AVCodecContext *avctx) | |
206 { | |
207 FAACContext *s = avctx->priv_data; | |
208 faacDecConfigurationPtr faac_cfg; | |
209 | |
210 #ifdef CONFIG_LIBFAADBIN | |
211 const char* err = 0; | |
212 | |
213 s->handle = dlopen(libfaadname, RTLD_LAZY); | |
214 if (!s->handle) | |
215 { | |
216 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", | |
217 libfaadname, dlerror()); | |
218 return -1; | |
219 } | |
220 #define dfaac(a, b) \ | |
221 do { static const char* n = "faacDec" #a; \ | |
222 if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0) | |
223 for(;;) { | |
224 #else /* !CONFIG_LIBFAADBIN */ | |
225 #define dfaac(a, b) s->faacDec ## a = faacDec ## a | |
226 #endif /* CONFIG_LIBFAADBIN */ | |
227 | |
228 // resolve all needed function calls | |
229 dfaac(Open, (faacDecHandle FAADAPI (*)(void))); | |
230 dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder))); | |
231 dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr | |
232 FAADAPI (*)(faacDecHandle))); | |
233 #ifndef FAAD2_VERSION | |
234 dfaac(SetConfiguration, (int FAADAPI (*)(faacDecHandle, | |
235 faacDecConfigurationPtr))); | |
236 | |
237 dfaac(Init, (int FAADAPI (*)(faacDecHandle, unsigned char*, | |
238 unsigned long*, unsigned long*))); | |
239 dfaac(Init2, (int FAADAPI (*)(faacDecHandle, unsigned char*, | |
240 unsigned long, unsigned long*, | |
241 unsigned long*))); | |
242 dfaac(Decode, (int FAADAPI (*)(faacDecHandle, unsigned char*, | |
243 unsigned long*, short*, unsigned long*))); | |
244 #else | |
245 dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle, | |
246 faacDecConfigurationPtr))); | |
247 dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*, | |
248 unsigned long, unsigned long*, unsigned char*))); | |
249 dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*, | |
250 unsigned long, unsigned long*, | |
251 unsigned char*))); | |
252 dfaac(Decode, (void *FAADAPI (*)(faacDecHandle, faacDecFrameInfo*, | |
253 unsigned char*, unsigned long))); | |
254 dfaac(GetErrorMessage, (char* FAADAPI (*)(unsigned char))); | |
255 #endif | |
256 #undef dfacc | |
257 | |
258 #ifdef CONFIG_LIBFAADBIN | |
259 break; | |
260 } | |
261 if (err) { | |
262 dlclose(s->handle); | |
263 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", | |
264 err, libfaadname); | |
265 return -1; | |
266 } | |
267 #endif | |
268 | |
269 s->faac_handle = s->faacDecOpen(); | |
270 if (!s->faac_handle) { | |
271 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); | |
272 faac_decode_end(avctx); | |
273 return -1; | |
274 } | |
275 | |
276 | |
277 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); | |
278 | |
279 if (faac_cfg) { | |
280 switch (avctx->bits_per_sample) { | |
281 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_sample); break; | |
282 default: | |
283 case 16: | |
284 #ifdef FAAD2_VERSION | |
285 faac_cfg->outputFormat = FAAD_FMT_16BIT; | |
286 #endif | |
287 s->sample_size = 2; | |
288 break; | |
289 case 24: | |
290 #ifdef FAAD2_VERSION | |
291 faac_cfg->outputFormat = FAAD_FMT_24BIT; | |
292 #endif | |
293 s->sample_size = 3; | |
294 break; | |
295 case 32: | |
296 #ifdef FAAD2_VERSION | |
297 faac_cfg->outputFormat = FAAD_FMT_32BIT; | |
298 #endif | |
299 s->sample_size = 4; | |
300 break; | |
301 } | |
302 | |
303 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; | |
304 faac_cfg->defObjectType = LC; | |
305 } | |
306 | |
307 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); | |
308 | |
309 faac_init_mp4(avctx); | |
310 | |
311 return 0; | |
312 } | |
313 | |
314 #define AAC_CODEC(id, name) \ | |
315 AVCodec name ## _decoder = { \ | |
316 #name, \ | |
317 CODEC_TYPE_AUDIO, \ | |
318 id, \ | |
319 sizeof(FAACContext), \ | |
320 faac_decode_init, \ | |
321 NULL, \ | |
322 faac_decode_end, \ | |
323 faac_decode_frame, \ | |
324 } | |
325 | |
326 // FIXME - raw AAC files - maybe just one entry will be enough | |
327 AAC_CODEC(CODEC_ID_AAC, libfaad); | |
328 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) | |
329 // If it's mp4 file - usually embeded into Qt Mov | |
330 AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac); | |
331 #endif | |
332 | |
333 #undef AAC_CODEC |