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";
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 void channel_setup(AVCodecContext
*avctx
)
107 FAACContext
*s
= avctx
->priv_data
;
108 if (avctx
->request_channels
> 0 && avctx
->request_channels
== 2 &&
109 avctx
->request_channels
< avctx
->channels
) {
110 faacDecConfigurationPtr faac_cfg
;
112 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
113 faac_cfg
->downMatrix
= 1;
114 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
119 static int faac_init_mp4(AVCodecContext
*avctx
)
121 FAACContext
*s
= avctx
->priv_data
;
122 unsigned long samplerate
;
123 #ifndef FAAD2_VERSION
124 unsigned long channels
;
126 unsigned char channels
;
130 if (avctx
->extradata
){
131 r
= s
->faacDecInit2(s
->faac_handle
, (uint8_t*) avctx
->extradata
,
132 avctx
->extradata_size
,
133 &samplerate
, &channels
);
135 av_log(avctx
, AV_LOG_ERROR
,
136 "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n",
137 r
, samplerate
, (long)channels
, avctx
->extradata_size
);
139 avctx
->sample_rate
= samplerate
;
140 avctx
->channels
= channels
;
141 channel_setup(avctx
);
149 static int faac_decode_frame(AVCodecContext
*avctx
,
150 void *data
, int *data_size
,
151 uint8_t *buf
, int buf_size
)
153 FAACContext
*s
= avctx
->priv_data
;
154 #ifndef FAAD2_VERSION
155 unsigned long bytesconsumed
;
156 short *sample_buffer
= NULL
;
157 unsigned long samples
;
160 faacDecFrameInfo frame_info
;
165 #ifndef FAAD2_VERSION
166 out
= s
->faacDecDecode(s
->faac_handle
,
171 samples
*= s
->sample_size
;
173 *data_size
= samples
;
174 return (buf_size
< (int)bytesconsumed
)
175 ? buf_size
: (int)bytesconsumed
;
180 unsigned char channels
;
181 int r
= s
->faacDecInit(s
->faac_handle
, buf
, buf_size
, &srate
, &channels
);
183 av_log(avctx
, AV_LOG_ERROR
, "faac: codec init failed.\n");
186 avctx
->sample_rate
= srate
;
187 avctx
->channels
= channels
;
188 channel_setup(avctx
);
192 out
= s
->faacDecDecode(s
->faac_handle
, &frame_info
, (unsigned char*)buf
, (unsigned long)buf_size
);
194 if (frame_info
.error
> 0) {
195 av_log(avctx
, AV_LOG_ERROR
, "faac: frame decoding failed: %s\n",
196 s
->faacDecGetErrorMessage(frame_info
.error
));
199 if (!avctx
->frame_size
)
200 avctx
->frame_size
= frame_info
.samples
/avctx
->channels
;
201 frame_info
.samples
*= s
->sample_size
;
202 memcpy(data
, out
, frame_info
.samples
); // CHECKME - can we cheat this one
205 *data_size
= frame_info
.samples
;
207 return (buf_size
< (int)frame_info
.bytesconsumed
)
208 ? buf_size
: (int)frame_info
.bytesconsumed
;
212 static av_cold
int faac_decode_end(AVCodecContext
*avctx
)
214 FAACContext
*s
= avctx
->priv_data
;
216 s
->faacDecClose(s
->faac_handle
);
222 static av_cold
int faac_decode_init(AVCodecContext
*avctx
)
224 FAACContext
*s
= avctx
->priv_data
;
225 faacDecConfigurationPtr faac_cfg
;
227 #ifdef CONFIG_LIBFAADBIN
230 s
->handle
= dlopen(libfaadname
, RTLD_LAZY
);
233 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: %s could not be opened! \n%s\n",
234 libfaadname
, dlerror());
238 #define dfaac(a) do { \
239 const char* n = AV_STRINGIFY(faacDec ## a); \
240 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \
244 #else /* !CONFIG_LIBFAADBIN */
245 #define dfaac(a) s->faacDec ## a = faacDec ## a
246 #endif /* CONFIG_LIBFAADBIN */
248 // resolve all needed function calls
251 dfaac(GetCurrentConfiguration
);
252 dfaac(SetConfiguration
);
257 dfaac(GetErrorMessage
);
262 #ifdef CONFIG_LIBFAADBIN
265 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot resolve %s in %s!\n",
271 s
->faac_handle
= s
->faacDecOpen();
272 if (!s
->faac_handle
) {
273 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot create handler!\n");
274 faac_decode_end(avctx
);
279 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
282 switch (avctx
->bits_per_sample
) {
283 case 8: av_log(avctx
, AV_LOG_ERROR
, "FAADlib unsupported bps %d\n", avctx
->bits_per_sample
); break;
287 faac_cfg
->outputFormat
= FAAD_FMT_16BIT
;
293 faac_cfg
->outputFormat
= FAAD_FMT_24BIT
;
299 faac_cfg
->outputFormat
= FAAD_FMT_32BIT
;
305 faac_cfg
->defSampleRate
= (!avctx
->sample_rate
) ? 44100 : avctx
->sample_rate
;
306 faac_cfg
->defObjectType
= LC
;
309 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
311 faac_init_mp4(avctx
);
313 if(!s
->init
&& avctx
->channels
> 0)
314 channel_setup(avctx
);
319 #define AAC_CODEC(id, name, long_name_) \
320 AVCodec name ## _decoder = { \
324 sizeof(FAACContext), \
329 .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
332 // FIXME - raw AAC files - maybe just one entry will be enough
333 AAC_CODEC(CODEC_ID_AAC
, libfaad
, "libfaad AAC (Advanced Audio Codec)");
334 #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
335 // If it's mp4 file - usually embeded into Qt Mov
336 AAC_CODEC(CODEC_ID_MPEG4AAC
, mpeg4aac
, "libfaad AAC (Advanced Audio Codec)");