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
24 * @file libavcodec/libfaad.c
27 * still a bit unfinished - but it plays something
38 * when CONFIG_LIBFAADBIN is true libfaad will be opened at runtime
40 //#undef CONFIG_LIBFAADBIN
41 //#define CONFIG_LIBFAADBIN 0
42 //#define CONFIG_LIBFAADBIN 1
46 static const char* const libfaadname
= "libfaad.so";
53 void* handle
; /* dlopen handle */
54 void* faac_handle
; /* FAAD library handle */
59 faacDecHandle
FAADAPI (*faacDecOpen
)(void);
60 faacDecConfigurationPtr
FAADAPI (*faacDecGetCurrentConfiguration
)(faacDecHandle hDecoder
);
62 int FAADAPI (*faacDecSetConfiguration
)(faacDecHandle hDecoder
,
63 faacDecConfigurationPtr config
);
64 int FAADAPI (*faacDecInit
)(faacDecHandle hDecoder
,
65 unsigned char *buffer
,
66 unsigned long *samplerate
,
67 unsigned long *channels
);
68 int FAADAPI (*faacDecInit2
)(faacDecHandle hDecoder
, unsigned char *pBuffer
,
69 unsigned long SizeOfDecoderSpecificInfo
,
70 unsigned long *samplerate
, unsigned long *channels
);
71 int FAADAPI (*faacDecDecode
)(faacDecHandle hDecoder
,
72 unsigned char *buffer
,
73 unsigned long *bytesconsumed
,
75 unsigned long *samples
);
77 unsigned char FAADAPI (*faacDecSetConfiguration
)(faacDecHandle hDecoder
,
78 faacDecConfigurationPtr config
);
79 long FAADAPI (*faacDecInit
)(faacDecHandle hDecoder
,
80 unsigned char *buffer
,
81 unsigned long buffer_size
,
82 unsigned long *samplerate
,
83 unsigned char *channels
);
84 char FAADAPI (*faacDecInit2
)(faacDecHandle hDecoder
, unsigned char *pBuffer
,
85 unsigned long SizeOfDecoderSpecificInfo
,
86 unsigned long *samplerate
, unsigned char *channels
);
87 void *FAADAPI (*faacDecDecode
)(faacDecHandle hDecoder
,
88 faacDecFrameInfo
*hInfo
,
89 unsigned char *buffer
,
90 unsigned long buffer_size
);
91 char* FAADAPI (*faacDecGetErrorMessage
)(unsigned char errcode
);
94 void FAADAPI (*faacDecClose
)(faacDecHandle hDecoder
);
99 static const unsigned long faac_srates
[] =
101 96000, 88200, 64000, 48000, 44100, 32000,
102 24000, 22050, 16000, 12000, 11025, 8000
105 static void channel_setup(AVCodecContext
*avctx
)
108 FAACContext
*s
= avctx
->priv_data
;
109 if (avctx
->request_channels
> 0 && avctx
->request_channels
== 2 &&
110 avctx
->request_channels
< avctx
->channels
) {
111 faacDecConfigurationPtr faac_cfg
;
113 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
114 faac_cfg
->downMatrix
= 1;
115 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
120 static av_cold
int faac_init_mp4(AVCodecContext
*avctx
)
122 FAACContext
*s
= avctx
->priv_data
;
123 unsigned long samplerate
;
124 #ifndef FAAD2_VERSION
125 unsigned long channels
;
127 unsigned char channels
;
131 if (avctx
->extradata
){
132 r
= s
->faacDecInit2(s
->faac_handle
, (uint8_t*) avctx
->extradata
,
133 avctx
->extradata_size
,
134 &samplerate
, &channels
);
136 av_log(avctx
, AV_LOG_ERROR
,
137 "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n",
138 r
, samplerate
, (long)channels
, avctx
->extradata_size
);
140 avctx
->sample_rate
= samplerate
;
141 avctx
->channels
= channels
;
142 channel_setup(avctx
);
150 static int faac_decode_frame(AVCodecContext
*avctx
,
151 void *data
, int *data_size
,
154 const uint8_t *buf
= avpkt
->data
;
155 int buf_size
= avpkt
->size
;
156 FAACContext
*s
= avctx
->priv_data
;
157 #ifndef FAAD2_VERSION
158 unsigned long bytesconsumed
;
159 short *sample_buffer
= NULL
;
160 unsigned long samples
;
163 faacDecFrameInfo frame_info
;
168 #ifndef FAAD2_VERSION
169 out
= s
->faacDecDecode(s
->faac_handle
,
174 samples
*= s
->sample_size
;
176 *data_size
= samples
;
177 return (buf_size
< (int)bytesconsumed
)
178 ? buf_size
: (int)bytesconsumed
;
183 unsigned char channels
;
184 int r
= s
->faacDecInit(s
->faac_handle
, buf
, buf_size
, &srate
, &channels
);
186 av_log(avctx
, AV_LOG_ERROR
, "faac: codec init failed.\n");
189 avctx
->sample_rate
= srate
;
190 avctx
->channels
= channels
;
191 channel_setup(avctx
);
195 out
= s
->faacDecDecode(s
->faac_handle
, &frame_info
, (unsigned char*)buf
, (unsigned long)buf_size
);
197 if (frame_info
.error
> 0) {
198 av_log(avctx
, AV_LOG_ERROR
, "faac: frame decoding failed: %s\n",
199 s
->faacDecGetErrorMessage(frame_info
.error
));
202 if (!avctx
->frame_size
)
203 avctx
->frame_size
= frame_info
.samples
/avctx
->channels
;
204 frame_info
.samples
*= s
->sample_size
;
205 memcpy(data
, out
, frame_info
.samples
); // CHECKME - can we cheat this one
208 *data_size
= frame_info
.samples
;
210 return (buf_size
< (int)frame_info
.bytesconsumed
)
211 ? buf_size
: (int)frame_info
.bytesconsumed
;
215 static av_cold
int faac_decode_end(AVCodecContext
*avctx
)
217 FAACContext
*s
= avctx
->priv_data
;
219 s
->faacDecClose(s
->faac_handle
);
225 static av_cold
int faac_decode_init(AVCodecContext
*avctx
)
227 FAACContext
*s
= avctx
->priv_data
;
228 faacDecConfigurationPtr faac_cfg
;
230 #if CONFIG_LIBFAADBIN
233 s
->handle
= dlopen(libfaadname
, RTLD_LAZY
);
236 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: %s could not be opened! \n%s\n",
237 libfaadname
, dlerror());
241 #define dfaac(a) do { \
242 const char* n = AV_STRINGIFY(faacDec ## a); \
243 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \
247 #else /* !CONFIG_LIBFAADBIN */
248 #define dfaac(a) s->faacDec ## a = faacDec ## a
249 #endif /* CONFIG_LIBFAADBIN */
251 // resolve all needed function calls
254 dfaac(GetCurrentConfiguration
);
255 dfaac(SetConfiguration
);
260 dfaac(GetErrorMessage
);
265 #if CONFIG_LIBFAADBIN
268 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot resolve %s in %s!\n",
274 s
->faac_handle
= s
->faacDecOpen();
275 if (!s
->faac_handle
) {
276 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot create handler!\n");
277 faac_decode_end(avctx
);
282 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
285 switch (avctx
->bits_per_coded_sample
) {
286 case 8: av_log(avctx
, AV_LOG_ERROR
, "FAADlib unsupported bps %d\n", avctx
->bits_per_coded_sample
); break;
290 faac_cfg
->outputFormat
= FAAD_FMT_16BIT
;
296 faac_cfg
->outputFormat
= FAAD_FMT_24BIT
;
302 faac_cfg
->outputFormat
= FAAD_FMT_32BIT
;
308 faac_cfg
->defSampleRate
= (!avctx
->sample_rate
) ? 44100 : avctx
->sample_rate
;
309 faac_cfg
->defObjectType
= LC
;
312 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
314 faac_init_mp4(avctx
);
316 if(!s
->init
&& avctx
->channels
> 0)
317 channel_setup(avctx
);
319 avctx
->sample_fmt
= SAMPLE_FMT_S16
;
323 AVCodec libfaad_decoder
= {
332 .long_name
= NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"),