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
,
152 uint8_t *buf
, int buf_size
)
154 FAACContext
*s
= avctx
->priv_data
;
155 #ifndef FAAD2_VERSION
156 unsigned long bytesconsumed
;
157 short *sample_buffer
= NULL
;
158 unsigned long samples
;
161 faacDecFrameInfo frame_info
;
166 #ifndef FAAD2_VERSION
167 out
= s
->faacDecDecode(s
->faac_handle
,
172 samples
*= s
->sample_size
;
174 *data_size
= samples
;
175 return (buf_size
< (int)bytesconsumed
)
176 ? buf_size
: (int)bytesconsumed
;
181 unsigned char channels
;
182 int r
= s
->faacDecInit(s
->faac_handle
, buf
, buf_size
, &srate
, &channels
);
184 av_log(avctx
, AV_LOG_ERROR
, "faac: codec init failed.\n");
187 avctx
->sample_rate
= srate
;
188 avctx
->channels
= channels
;
189 channel_setup(avctx
);
193 out
= s
->faacDecDecode(s
->faac_handle
, &frame_info
, (unsigned char*)buf
, (unsigned long)buf_size
);
195 if (frame_info
.error
> 0) {
196 av_log(avctx
, AV_LOG_ERROR
, "faac: frame decoding failed: %s\n",
197 s
->faacDecGetErrorMessage(frame_info
.error
));
200 if (!avctx
->frame_size
)
201 avctx
->frame_size
= frame_info
.samples
/avctx
->channels
;
202 frame_info
.samples
*= s
->sample_size
;
203 memcpy(data
, out
, frame_info
.samples
); // CHECKME - can we cheat this one
206 *data_size
= frame_info
.samples
;
208 return (buf_size
< (int)frame_info
.bytesconsumed
)
209 ? buf_size
: (int)frame_info
.bytesconsumed
;
213 static av_cold
int faac_decode_end(AVCodecContext
*avctx
)
215 FAACContext
*s
= avctx
->priv_data
;
217 s
->faacDecClose(s
->faac_handle
);
223 static av_cold
int faac_decode_init(AVCodecContext
*avctx
)
225 FAACContext
*s
= avctx
->priv_data
;
226 faacDecConfigurationPtr faac_cfg
;
228 #if CONFIG_LIBFAADBIN
231 s
->handle
= dlopen(libfaadname
, RTLD_LAZY
);
234 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: %s could not be opened! \n%s\n",
235 libfaadname
, dlerror());
239 #define dfaac(a) do { \
240 const char* n = AV_STRINGIFY(faacDec ## a); \
241 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \
245 #else /* !CONFIG_LIBFAADBIN */
246 #define dfaac(a) s->faacDec ## a = faacDec ## a
247 #endif /* CONFIG_LIBFAADBIN */
249 // resolve all needed function calls
252 dfaac(GetCurrentConfiguration
);
253 dfaac(SetConfiguration
);
258 dfaac(GetErrorMessage
);
263 #if CONFIG_LIBFAADBIN
266 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot resolve %s in %s!\n",
272 s
->faac_handle
= s
->faacDecOpen();
273 if (!s
->faac_handle
) {
274 av_log(avctx
, AV_LOG_ERROR
, "FAAD library: cannot create handler!\n");
275 faac_decode_end(avctx
);
280 faac_cfg
= s
->faacDecGetCurrentConfiguration(s
->faac_handle
);
283 switch (avctx
->bits_per_coded_sample
) {
284 case 8: av_log(avctx
, AV_LOG_ERROR
, "FAADlib unsupported bps %d\n", avctx
->bits_per_coded_sample
); break;
288 faac_cfg
->outputFormat
= FAAD_FMT_16BIT
;
294 faac_cfg
->outputFormat
= FAAD_FMT_24BIT
;
300 faac_cfg
->outputFormat
= FAAD_FMT_32BIT
;
306 faac_cfg
->defSampleRate
= (!avctx
->sample_rate
) ? 44100 : avctx
->sample_rate
;
307 faac_cfg
->defObjectType
= LC
;
310 s
->faacDecSetConfiguration(s
->faac_handle
, faac_cfg
);
312 faac_init_mp4(avctx
);
314 if(!s
->init
&& avctx
->channels
> 0)
315 channel_setup(avctx
);
317 avctx
->sample_fmt
= SAMPLE_FMT_S16
;
321 AVCodec libfaad_decoder
= {
330 .long_name
= NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"),