3 * Copyright (c) 2003 Zdenek Kabelac.
4 * Copyright (c) 2004 Thomas Raivio.
6 * This file is part of FFmpeg.
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.
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.
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
27 * still a bit unfinished - but it plays something
38 * when CONFIG_LIBFAADBIN is defined the libfaad will be opened at runtime
40 //#undef CONFIG_LIBFAADBIN
41 //#define CONFIG_LIBFAADBIN
43 #ifdef CONFIG_LIBFAADBIN
45 static const char* libfaadname
= "libfaad.so.0";
52 void* handle
; /* dlopen handle */
53 void* faac_handle
; /* FAAD library handle */
58 faacDecHandle
FAADAPI (*faacDecOpen
)(void);
59 faacDecConfigurationPtr
FAADAPI (*faacDecGetCurrentConfiguration
)(faacDecHandle hDecoder
);
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
,
74 unsigned long *samples
);
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
);
93 void FAADAPI (*faacDecClose
)(faacDecHandle hDecoder
);
98 static const unsigned long faac_srates
[] =
100 96000, 88200, 64000, 48000, 44100, 32000,
101 24000, 22050, 16000, 12000, 11025, 8000
104 static int faac_init_mp4(AVCodecContext
*avctx
)
106 FAACContext
*s
= avctx
->priv_data
;
107 unsigned long samplerate
;
108 #ifndef FAAD2_VERSION
109 unsigned long channels
;
111 unsigned char channels
;
115 if (avctx
->extradata
){
116 r
= s
->faacDecInit2(s
->faac_handle
, (uint8_t*) avctx
->extradata
,
117 avctx
->extradata_size
,
118 &samplerate
, &channels
);
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
);
124 avctx
->sample_rate
= samplerate
;
125 avctx
->channels
= channels
;
133 static int faac_decode_frame(AVCodecContext
*avctx
,
134 void *data
, int *data_size
,
135 uint8_t *buf
, int buf_size
)
137 FAACContext
*s
= avctx
->priv_data
;
138 #ifndef FAAD2_VERSION
139 unsigned long bytesconsumed
;
140 short *sample_buffer
= NULL
;
141 unsigned long samples
;
144 faacDecFrameInfo frame_info
;
149 #ifndef FAAD2_VERSION
150 out
= s
->faacDecDecode(s
->faac_handle
,
155 samples
*= s
->sample_size
;
157 *data_size
= samples
;
158 return (buf_size
< (int)bytesconsumed
)
159 ? buf_size
: (int)bytesconsumed
;
164 unsigned char channels
;
165 int r
= s
->faacDecInit(s
->faac_handle
, buf
, buf_size
, &srate
, &channels
);
167 av_log(avctx
, AV_LOG_ERROR
, "faac: codec init failed: %s\n",
168 s
->faacDecGetErrorMessage(frame_info
.error
));
171 avctx
->sample_rate
= srate
;
172 avctx
->channels
= channels
;
176 out
= s
->faacDecDecode(s
->faac_handle
, &frame_info
, (unsigned char*)buf
, (unsigned long)buf_size
);
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
));
184 frame_info
.samples
*= s
->sample_size
;
185 memcpy(data
, out
, frame_info
.samples
); // CHECKME - can we cheat this one
188 *data_size
= frame_info
.samples
;
190 return (buf_size
< (int)frame_info
.bytesconsumed
)
191 ? buf_size
: (int)frame_info
.bytesconsumed
;
195 static int faac_decode_end(AVCodecContext
*avctx
)
197 FAACContext
*s
= avctx
->priv_data
;
199 s
->faacDecClose(s
->faac_handle
);
205 static int faac_decode_init(AVCodecContext
*avctx
)
207 FAACContext
*s
= avctx
->priv_data
;
208 faacDecConfigurationPtr faac_cfg
;
210 #ifdef CONFIG_LIBFAADBIN
213 s
->handle
= dlopen(libfaadname
, RTLD_LAZY
);
216 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: %s could not be opened! \n%s\n",
217 libfaadname
, dlerror());
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)
224 #else /* !CONFIG_LIBFAADBIN */
225 #define dfaac(a, b) s->faacDec ## a = faacDec ## a
226 #endif /* CONFIG_LIBFAADBIN */
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
)));
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*,
242 dfaac(Decode
, (int FAADAPI (*)(faacDecHandle
, unsigned char*,
243 unsigned long*, short*, unsigned long*)));
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*,
252 dfaac(Decode
, (void *FAADAPI (*)(faacDecHandle
, faacDecFrameInfo
*,
253 unsigned char*, unsigned long)));
254 dfaac(GetErrorMessage
, (char* FAADAPI (*)(unsigned char)));
258 #ifdef CONFIG_LIBFAADBIN
263 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot resolve %s in %s!\n",
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
);
277 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
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;
285 faac_cfg
->outputFormat
= FAAD_FMT_16BIT
;
291 faac_cfg
->outputFormat
= FAAD_FMT_24BIT
;
297 faac_cfg
->outputFormat
= FAAD_FMT_32BIT
;
303 faac_cfg
->defSampleRate
= (!avctx
->sample_rate
) ? 44100 : avctx
->sample_rate
;
304 faac_cfg
->defObjectType
= LC
;
307 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
309 faac_init_mp4(avctx
);
314 #define AAC_CODEC(id, name) \
315 AVCodec name ## _decoder = { \
319 sizeof(FAACContext), \
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
);