Remove explicit filename from Doxygen @file commands.
[libav.git] / libavcodec / libfaad.c
CommitLineData
280bd7b7
ZK
1/*
2 * Faad decoder
406792e7
DB
3 * Copyright (c) 2003 Zdenek Kabelac
4 * Copyright (c) 2004 Thomas Raivio
280bd7b7 5 *
b78e7197
DB
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
280bd7b7
ZK
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
b78e7197 11 * version 2.1 of the License, or (at your option) any later version.
280bd7b7 12 *
b78e7197 13 * FFmpeg is distributed in the hope that it will be useful,
280bd7b7
ZK
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
b78e7197 19 * License along with FFmpeg; if not, write to the Free Software
5509bffa 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
280bd7b7
ZK
21 */
22
23/**
ba87f080 24 * @file
280bd7b7
ZK
25 * AAC decoder.
26 *
27 * still a bit unfinished - but it plays something
28 */
29
30#include "avcodec.h"
31#include "faad.h"
32
305fa264
MN
33#ifndef FAADAPI
34#define FAADAPI
35#endif
36
280bd7b7 37/*
b250f9c6 38 * when CONFIG_LIBFAADBIN is true libfaad will be opened at runtime
280bd7b7 39 */
2eed5a46 40//#undef CONFIG_LIBFAADBIN
b250f9c6
AJ
41//#define CONFIG_LIBFAADBIN 0
42//#define CONFIG_LIBFAADBIN 1
280bd7b7 43
b250f9c6 44#if CONFIG_LIBFAADBIN
280bd7b7 45#include <dlfcn.h>
9b5ede5b 46static const char* const libfaadname = "libfaad.so";
280bd7b7
ZK
47#else
48#define dlopen(a)
49#define dlclose(a)
50#endif
51
52typedef struct {
bb270c08
DB
53 void* handle; /* dlopen handle */
54 void* faac_handle; /* FAAD library handle */
280bd7b7 55 int sample_size;
79b0b66b 56 int init;
280bd7b7
ZK
57
58 /* faad calls */
59 faacDecHandle FAADAPI (*faacDecOpen)(void);
60 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder);
931c85d0 61#ifndef FAAD2_VERSION
0f44edaa 62 int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder,
931c85d0 63 faacDecConfigurationPtr config);
0f44edaa
MR
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,
931c85d0
TR
69 unsigned long SizeOfDecoderSpecificInfo,
70 unsigned long *samplerate, unsigned long *channels);
0f44edaa
MR
71 int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder,
72 unsigned char *buffer,
73 unsigned long *bytesconsumed,
74 short *sample_buffer,
75 unsigned long *samples);
931c85d0 76#else
0f44edaa 77 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder,
931c85d0 78 faacDecConfigurationPtr config);
0f44edaa
MR
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,
280bd7b7
ZK
85 unsigned long SizeOfDecoderSpecificInfo,
86 unsigned long *samplerate, unsigned char *channels);
0f44edaa
MR
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);
931c85d0 92#endif
115329f1 93
280bd7b7 94 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder);
115329f1
DB
95
96
280bd7b7
ZK
97} FAACContext;
98
99static const unsigned long faac_srates[] =
100{
101 96000, 88200, 64000, 48000, 44100, 32000,
102 24000, 22050, 16000, 12000, 11025, 8000
103};
104
ef7f2bb7
JR
105static void channel_setup(AVCodecContext *avctx)
106{
107#ifdef FAAD2_VERSION
108 FAACContext *s = avctx->priv_data;
109 if (avctx->request_channels > 0 && avctx->request_channels == 2 &&
0f44edaa 110 avctx->request_channels < avctx->channels) {
ef7f2bb7
JR
111 faacDecConfigurationPtr faac_cfg;
112 avctx->channels = 2;
113 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle);
114 faac_cfg->downMatrix = 1;
115 s->faacDecSetConfiguration(s->faac_handle, faac_cfg);
116 }
117#endif
118}
119
5ef251e5 120static av_cold int faac_init_mp4(AVCodecContext *avctx)
280bd7b7 121{
e4141433 122 FAACContext *s = avctx->priv_data;
280bd7b7 123 unsigned long samplerate;
931c85d0
TR
124#ifndef FAAD2_VERSION
125 unsigned long channels;
126#else
280bd7b7 127 unsigned char channels;
931c85d0 128#endif
280bd7b7
ZK
129 int r = 0;
130
79b0b66b 131 if (avctx->extradata){
bb270c08
DB
132 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata,
133 avctx->extradata_size,
134 &samplerate, &channels);
79b0b66b
MR
135 if (r < 0){
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);
139 } else {
140 avctx->sample_rate = samplerate;
141 avctx->channels = channels;
ef7f2bb7 142 channel_setup(avctx);
79b0b66b
MR
143 s->init = 1;
144 }
145 }
940aed50 146
280bd7b7
ZK
147 return r;
148}
149
280bd7b7
ZK
150static int faac_decode_frame(AVCodecContext *avctx,
151 void *data, int *data_size,
7a00bbad 152 AVPacket *avpkt)
280bd7b7 153{
7a00bbad
TB
154 const uint8_t *buf = avpkt->data;
155 int buf_size = avpkt->size;
e4141433 156 FAACContext *s = avctx->priv_data;
931c85d0
TR
157#ifndef FAAD2_VERSION
158 unsigned long bytesconsumed;
159 short *sample_buffer = NULL;
160 unsigned long samples;
161 int out;
162#else
280bd7b7 163 faacDecFrameInfo frame_info;
931c85d0
TR
164 void *out;
165#endif
166 if(buf_size == 0)
bb270c08 167 return 0;
931c85d0 168#ifndef FAAD2_VERSION
115329f1
DB
169 out = s->faacDecDecode(s->faac_handle,
170 (unsigned char*)buf,
171 &bytesconsumed,
172 data,
931c85d0
TR
173 &samples);
174 samples *= s->sample_size;
175 if (data_size)
bb270c08 176 *data_size = samples;
931c85d0 177 return (buf_size < (int)bytesconsumed)
bb270c08 178 ? buf_size : (int)bytesconsumed;
931c85d0 179#else
115329f1 180
79b0b66b
MR
181 if(!s->init){
182 unsigned long srate;
183 unsigned char channels;
289f999d 184 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels);
79b0b66b 185 if(r < 0){
254dd3f1 186 av_log(avctx, AV_LOG_ERROR, "libfaad: codec init failed.\n");
980bbb13 187 return -1;
79b0b66b
MR
188 }
189 avctx->sample_rate = srate;
190 avctx->channels = channels;
ef7f2bb7 191 channel_setup(avctx);
79b0b66b
MR
192 s->init = 1;
193 }
194
931c85d0 195 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size);
280bd7b7
ZK
196
197 if (frame_info.error > 0) {
254dd3f1 198 av_log(avctx, AV_LOG_ERROR, "libfaad: frame decoding failed: %s\n",
0f44edaa 199 s->faacDecGetErrorMessage(frame_info.error));
980bbb13 200 return -1;
280bd7b7 201 }
f056c8e9
BC
202 if (!avctx->frame_size)
203 avctx->frame_size = frame_info.samples/avctx->channels;
280bd7b7
ZK
204 frame_info.samples *= s->sample_size;
205 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one
206
207 if (data_size)
bb270c08 208 *data_size = frame_info.samples;
280bd7b7
ZK
209
210 return (buf_size < (int)frame_info.bytesconsumed)
bb270c08 211 ? buf_size : (int)frame_info.bytesconsumed;
931c85d0 212#endif
280bd7b7
ZK
213}
214
98a6fff9 215static av_cold int faac_decode_end(AVCodecContext *avctx)
280bd7b7 216{
e4141433 217 FAACContext *s = avctx->priv_data;
280bd7b7 218
b83f7eb2 219 s->faacDecClose(s->faac_handle);
280bd7b7
ZK
220
221 dlclose(s->handle);
222 return 0;
223}
224
98a6fff9 225static av_cold int faac_decode_init(AVCodecContext *avctx)
280bd7b7 226{
e4141433 227 FAACContext *s = avctx->priv_data;
280bd7b7
ZK
228 faacDecConfigurationPtr faac_cfg;
229
b250f9c6 230#if CONFIG_LIBFAADBIN
280bd7b7
ZK
231 const char* err = 0;
232
233 s->handle = dlopen(libfaadname, RTLD_LAZY);
234 if (!s->handle)
235 {
bb270c08 236 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n",
0f44edaa 237 libfaadname, dlerror());
280bd7b7
ZK
238 return -1;
239 }
7b0dee28
MR
240
241#define dfaac(a) do { \
242 const char* n = AV_STRINGIFY(faacDec ## a); \
243 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \
244 err = n; \
245 } \
246 } while(0)
2eed5a46 247#else /* !CONFIG_LIBFAADBIN */
7b0dee28 248#define dfaac(a) s->faacDec ## a = faacDec ## a
2eed5a46 249#endif /* CONFIG_LIBFAADBIN */
280bd7b7 250
7b0dee28
MR
251 // resolve all needed function calls
252 dfaac(Open);
253 dfaac(Close);
254 dfaac(GetCurrentConfiguration);
255 dfaac(SetConfiguration);
256 dfaac(Init);
257 dfaac(Init2);
258 dfaac(Decode);
259#ifdef FAAD2_VERSION
260 dfaac(GetErrorMessage);
931c85d0 261#endif
7b0dee28
MR
262
263#undef dfaac
280bd7b7 264
b250f9c6 265#if CONFIG_LIBFAADBIN
280bd7b7
ZK
266 if (err) {
267 dlclose(s->handle);
bb270c08 268 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n",
0f44edaa 269 err, libfaadname);
280bd7b7
ZK
270 return -1;
271 }
272#endif
273
274 s->faac_handle = s->faacDecOpen();
275 if (!s->faac_handle) {
3d0ef6dd 276 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n");
280bd7b7
ZK
277 faac_decode_end(avctx);
278 return -1;
279 }
280
281
282 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle);
283
284 if (faac_cfg) {
dd1c8f3e
LA
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;
bb270c08
DB
287 default:
288 case 16:
931c85d0 289#ifdef FAAD2_VERSION
bb270c08 290 faac_cfg->outputFormat = FAAD_FMT_16BIT;
931c85d0 291#endif
bb270c08
DB
292 s->sample_size = 2;
293 break;
294 case 24:
931c85d0 295#ifdef FAAD2_VERSION
bb270c08 296 faac_cfg->outputFormat = FAAD_FMT_24BIT;
931c85d0 297#endif
bb270c08
DB
298 s->sample_size = 3;
299 break;
300 case 32:
931c85d0 301#ifdef FAAD2_VERSION
bb270c08 302 faac_cfg->outputFormat = FAAD_FMT_32BIT;
931c85d0 303#endif
bb270c08
DB
304 s->sample_size = 4;
305 break;
306 }
280bd7b7 307
bb270c08
DB
308 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate;
309 faac_cfg->defObjectType = LC;
280bd7b7
ZK
310 }
311
312 s->faacDecSetConfiguration(s->faac_handle, faac_cfg);
313
314 faac_init_mp4(avctx);
315
ef7f2bb7
JR
316 if(!s->init && avctx->channels > 0)
317 channel_setup(avctx);
318
fd76c37f 319 avctx->sample_fmt = SAMPLE_FMT_S16;
280bd7b7
ZK
320 return 0;
321}
322
59701aeb 323AVCodec libfaad_decoder = {
9d9de444 324 "libfaad",
72415b2a 325 AVMEDIA_TYPE_AUDIO,
59701aeb
DB
326 CODEC_ID_AAC,
327 sizeof(FAACContext),
328 faac_decode_init,
329 NULL,
330 faac_decode_end,
331 faac_decode_frame,
332 .long_name = NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"),
9d9de444 333};