~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/faad.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20081226001006-wd8cuqn8d81smkdp
Tags: upstream-1.1.7
ImportĀ upstreamĀ versionĀ 1.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Faad decoder
3
 
 * Copyright (c) 2003 Zdenek Kabelac.
4
 
 * Copyright (c) 2004 Thomas Raivio.
5
 
 *
6
 
 * This file is part of FFmpeg.
7
 
 *
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.
12
 
 *
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.
17
 
 *
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
21
 
 */
22
 
 
23
 
/**
24
 
 * @file faad.c
25
 
 * AAC decoder.
26
 
 *
27
 
 * still a bit unfinished - but it plays something
28
 
 */
29
 
 
30
 
#include "avcodec.h"
31
 
#include "faad.h"
32
 
 
33
 
#ifndef FAADAPI
34
 
#define FAADAPI
35
 
#endif
36
 
 
37
 
/*
38
 
 * when CONFIG_LIBFAADBIN is defined the libfaad will be opened at runtime
39
 
 */
40
 
//#undef CONFIG_LIBFAADBIN
41
 
//#define CONFIG_LIBFAADBIN
42
 
 
43
 
#ifdef CONFIG_LIBFAADBIN
44
 
#include <dlfcn.h>
45
 
static const char* libfaadname = "libfaad.so.0";
46
 
#else
47
 
#define dlopen(a)
48
 
#define dlclose(a)
49
 
#endif
50
 
 
51
 
typedef struct {
52
 
    void* handle;               /* dlopen handle */
53
 
    void* faac_handle;          /* FAAD library handle */
54
 
    int sample_size;
55
 
    int init;
56
 
 
57
 
    /* faad calls */
58
 
    faacDecHandle FAADAPI (*faacDecOpen)(void);
59
 
    faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder);
60
 
#ifndef FAAD2_VERSION
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,
73
 
                                short *sample_buffer,
74
 
                                unsigned long *samples);
75
 
#else
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);
91
 
#endif
92
 
 
93
 
    void FAADAPI (*faacDecClose)(faacDecHandle hDecoder);
94
 
 
95
 
 
96
 
} FAACContext;
97
 
 
98
 
static const unsigned long faac_srates[] =
99
 
{
100
 
    96000, 88200, 64000, 48000, 44100, 32000,
101
 
    24000, 22050, 16000, 12000, 11025, 8000
102
 
};
103
 
 
104
 
static int faac_init_mp4(AVCodecContext *avctx)
105
 
{
106
 
    FAACContext *s = (FAACContext *) avctx->priv_data;
107
 
    unsigned long samplerate;
108
 
#ifndef FAAD2_VERSION
109
 
    unsigned long channels;
110
 
#else
111
 
    unsigned char channels;
112
 
#endif
113
 
    int r = 0;
114
 
 
115
 
    if (avctx->extradata){
116
 
        r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata,
117
 
                            avctx->extradata_size,
118
 
                            &samplerate, &channels);
119
 
        if (r < 0){
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);
123
 
        } else {
124
 
            avctx->sample_rate = samplerate;
125
 
            avctx->channels = channels;
126
 
            s->init = 1;
127
 
        }
128
 
    }
129
 
 
130
 
    return r;
131
 
}
132
 
 
133
 
static int faac_decode_frame(AVCodecContext *avctx,
134
 
                             void *data, int *data_size,
135
 
                             uint8_t *buf, int buf_size)
136
 
{
137
 
    FAACContext *s = (FAACContext *) avctx->priv_data;
138
 
#ifndef FAAD2_VERSION
139
 
    unsigned long bytesconsumed;
140
 
    short *sample_buffer = NULL;
141
 
    unsigned long samples;
142
 
    int out;
143
 
#else
144
 
    faacDecFrameInfo frame_info;
145
 
    void *out;
146
 
#endif
147
 
    if(buf_size == 0)
148
 
        return 0;
149
 
#ifndef FAAD2_VERSION
150
 
    out = s->faacDecDecode(s->faac_handle,
151
 
                           (unsigned char*)buf,
152
 
                           &bytesconsumed,
153
 
                           data,
154
 
                           &samples);
155
 
    samples *= s->sample_size;
156
 
    if (data_size)
157
 
        *data_size = samples;
158
 
    return (buf_size < (int)bytesconsumed)
159
 
        ? buf_size : (int)bytesconsumed;
160
 
#else
161
 
 
162
 
    if(!s->init){
163
 
        unsigned long srate;
164
 
        unsigned char channels;
165
 
        int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels);
166
 
        if(r < 0){
167
 
            av_log(avctx, AV_LOG_ERROR, "faac: codec init failed: %s\n",
168
 
                   s->faacDecGetErrorMessage(frame_info.error));
169
 
            return -1;
170
 
        }
171
 
        avctx->sample_rate = srate;
172
 
        avctx->channels = channels;
173
 
        s->init = 1;
174
 
    }
175
 
 
176
 
    out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size);
177
 
 
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));
181
 
        return -1;
182
 
    }
183
 
 
184
 
    frame_info.samples *= s->sample_size;
185
 
    memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one
186
 
 
187
 
    if (data_size)
188
 
        *data_size = frame_info.samples;
189
 
 
190
 
    return (buf_size < (int)frame_info.bytesconsumed)
191
 
        ? buf_size : (int)frame_info.bytesconsumed;
192
 
#endif
193
 
}
194
 
 
195
 
static int faac_decode_end(AVCodecContext *avctx)
196
 
{
197
 
    FAACContext *s = (FAACContext *) avctx->priv_data;
198
 
 
199
 
    if (s->faacDecClose)
200
 
        s->faacDecClose(s->faac_handle);
201
 
 
202
 
    dlclose(s->handle);
203
 
    return 0;
204
 
}
205
 
 
206
 
static int faac_decode_init(AVCodecContext *avctx)
207
 
{
208
 
    FAACContext *s = (FAACContext *) avctx->priv_data;
209
 
    faacDecConfigurationPtr faac_cfg;
210
 
 
211
 
#ifdef CONFIG_LIBFAADBIN
212
 
    const char* err = 0;
213
 
 
214
 
    s->handle = dlopen(libfaadname, RTLD_LAZY);
215
 
    if (!s->handle)
216
 
    {
217
 
        av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n",
218
 
                libfaadname, dlerror());
219
 
        return -1;
220
 
    }
221
 
#define dfaac(a, b) \
222
 
    do { static const char* n = "faacDec" #a; \
223
 
    if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0)
224
 
    for(;;) {
225
 
#else  /* !CONFIG_LIBFAADBIN */
226
 
#define dfaac(a, b)     s->faacDec ## a = faacDec ## a
227
 
#endif /* CONFIG_LIBFAADBIN */
228
 
 
229
 
        // resolve all needed function calls
230
 
        dfaac(Open, (faacDecHandle FAADAPI (*)(void)));
231
 
        dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr
232
 
                                        FAADAPI (*)(faacDecHandle)));
233
 
#ifndef FAAD2_VERSION
234
 
        dfaac(SetConfiguration, (int FAADAPI (*)(faacDecHandle,
235
 
                                                           faacDecConfigurationPtr)));
236
 
 
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*,
241
 
                                       unsigned long*)));
242
 
    dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder)));
243
 
        dfaac(Decode, (int FAADAPI (*)(faacDecHandle, unsigned char*,
244
 
                             unsigned long*, short*, unsigned long*)));
245
 
#else
246
 
        dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle,
247
 
                                                           faacDecConfigurationPtr)));
248
 
        dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*,
249
 
                                     unsigned long, unsigned long*, unsigned char*)));
250
 
        dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*,
251
 
                                       unsigned long, unsigned long*,
252
 
                                       unsigned char*)));
253
 
        dfaac(Decode, (void *FAADAPI (*)(faacDecHandle, faacDecFrameInfo*,
254
 
                             unsigned char*, unsigned long)));
255
 
        dfaac(GetErrorMessage, (char* FAADAPI (*)(unsigned char)));
256
 
#endif
257
 
#undef dfacc
258
 
 
259
 
#ifdef CONFIG_LIBFAADBIN
260
 
        break;
261
 
    }
262
 
    if (err) {
263
 
        dlclose(s->handle);
264
 
        av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n",
265
 
                err, libfaadname);
266
 
        return -1;
267
 
    }
268
 
#endif
269
 
 
270
 
    s->faac_handle = s->faacDecOpen();
271
 
    if (!s->faac_handle) {
272
 
        av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n");
273
 
        faac_decode_end(avctx);
274
 
        return -1;
275
 
    }
276
 
 
277
 
 
278
 
    faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle);
279
 
 
280
 
    if (faac_cfg) {
281
 
        switch (avctx->bits_per_sample) {
282
 
        case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_sample); break;
283
 
        default:
284
 
        case 16:
285
 
#ifdef FAAD2_VERSION
286
 
            faac_cfg->outputFormat = FAAD_FMT_16BIT;
287
 
#endif
288
 
            s->sample_size = 2;
289
 
            break;
290
 
        case 24:
291
 
#ifdef FAAD2_VERSION
292
 
            faac_cfg->outputFormat = FAAD_FMT_24BIT;
293
 
#endif
294
 
            s->sample_size = 3;
295
 
            break;
296
 
        case 32:
297
 
#ifdef FAAD2_VERSION
298
 
            faac_cfg->outputFormat = FAAD_FMT_32BIT;
299
 
#endif
300
 
            s->sample_size = 4;
301
 
            break;
302
 
        }
303
 
 
304
 
        faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate;
305
 
        faac_cfg->defObjectType = LC;
306
 
    }
307
 
 
308
 
    s->faacDecSetConfiguration(s->faac_handle, faac_cfg);
309
 
 
310
 
    faac_init_mp4(avctx);
311
 
 
312
 
    return 0;
313
 
}
314
 
 
315
 
#define AAC_CODEC(id, name)     \
316
 
AVCodec name ## _decoder = {    \
317
 
    #name,                      \
318
 
    CODEC_TYPE_AUDIO,           \
319
 
    id,                         \
320
 
    sizeof(FAACContext),        \
321
 
    faac_decode_init,           \
322
 
    NULL,                       \
323
 
    faac_decode_end,            \
324
 
    faac_decode_frame,          \
325
 
}
326
 
 
327
 
// FIXME - raw AAC files - maybe just one entry will be enough
328
 
AAC_CODEC(CODEC_ID_AAC, aac);
329
 
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
330
 
// If it's mp4 file - usually embeded into Qt Mov
331
 
AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac);
332
 
#endif
333
 
 
334
 
#undef AAC_CODEC