Browse code

Merge OpenCORE AMR support from trunk.

Originally committed as revision 19133 to svn://svn.ffmpeg.org/ffmpeg/branches/0.5

Diego Biurrun authored on 2009/06/08 05:14:56
Showing 7 changed files
... ...
@@ -9,6 +9,7 @@ version 0.5.1:
9 9
 - fix for GPL code in libswscale that was erroneously activated
10 10
 - AltiVec code in libswscale is now LGPL
11 11
 - remaining GPL parts in AC-3 decoder converted to LGPL
12
+- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
12 13
 
13 14
 
14 15
 
... ...
@@ -39,6 +39,11 @@ Some external libraries, e.g. libx264, are under GPL and can be used in
39 39
 conjunction with FFmpeg. They require --enable-gpl to be passed to configure
40 40
 as well.
41 41
 
42
+The OpenCORE external libraries are under the Apache License 2.0. That license
43
+is incompatible with the LGPL v2.1 and the GPL v2, but not with version 3 of
44
+those licenses. So to combine the OpenCORE libraries with FFmpeg, the license
45
+version needs to be upgraded by passing --enable-version3 to configure.
46
+
42 47
 The nonfree external libraries libamrnb, libamrwb and libfaac can be hooked up
43 48
 in FFmpeg. You need to pass --enable-nonfree to configure to enable them. Employ
44 49
 this option with care as FFmpeg then becomes nonfree and unredistributable.
... ...
@@ -149,6 +149,8 @@ show_help(){
149 149
   echo "  --enable-bzlib           enable bzlib [autodetect]"
150 150
   echo "  --enable-libamr-nb       enable libamr-nb floating point audio codec [no]"
151 151
   echo "  --enable-libamr-wb       enable libamr-wb floating point audio codec [no]"
152
+  echo "  --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]"
153
+  echo "  --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]"
152 154
   echo "  --enable-libdc1394       enable IIDC-1394 grabbing using libdc1394"
153 155
   echo "                           and libraw1394 [no]"
154 156
   echo "  --enable-libdirac        enable Dirac support via libdirac [no]"
... ...
@@ -780,6 +782,8 @@ CONFIG_LIST="
780 780
     libgsm
781 781
     libmp3lame
782 782
     libnut
783
+    libopencore_amrnb
784
+    libopencore_amrwb
783 785
     libopenjpeg
784 786
     libschroedinger
785 787
     libspeex
... ...
@@ -1079,6 +1083,9 @@ libgsm_encoder_deps="libgsm"
1079 1079
 libgsm_ms_decoder_deps="libgsm"
1080 1080
 libgsm_ms_encoder_deps="libgsm"
1081 1081
 libmp3lame_encoder_deps="libmp3lame"
1082
+libopencore_amrnb_decoder_deps="libopencore_amrnb"
1083
+libopencore_amrnb_encoder_deps="libopencore_amrnb"
1084
+libopencore_amrwb_decoder_deps="libopencore_amrwb"
1082 1085
 libopenjpeg_decoder_deps="libopenjpeg"
1083 1086
 libschroedinger_decoder_deps="libschroedinger"
1084 1087
 libschroedinger_encoder_deps="libschroedinger"
... ...
@@ -1699,6 +1706,9 @@ die_license_disabled nonfree libamr_nb
1699 1699
 die_license_disabled nonfree libamr_wb
1700 1700
 die_license_disabled nonfree libfaac
1701 1701
 
1702
+die_license_disabled version3 libopencore_amrnb
1703
+die_license_disabled version3 libopencore_amrwb
1704
+
1702 1705
 enabled version3 && { enabled gpl && enable gplv3 || enable lgplv3; }
1703 1706
 
1704 1707
 check_deps $ARCH_EXT_LIST
... ...
@@ -1990,6 +2000,8 @@ enabled libfaad    && require2 libfaad faad.h faacDecOpen -lfaad
1990 1990
 enabled libgsm     && require  libgsm gsm.h gsm_create -lgsm
1991 1991
 enabled libmp3lame && require  libmp3lame lame/lame.h lame_init -lmp3lame -lm
1992 1992
 enabled libnut     && require  libnut libnut.h nut_demuxer_init -lnut
1993
+enabled libopencore_amrnb  && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb -lm
1994
+enabled libopencore_amrwb  && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb -lm
1993 1995
 enabled libopenjpeg && require libopenjpeg openjpeg.h opj_version -lopenjpeg
1994 1996
 enabled libschroedinger && add_cflags $(pkg-config --cflags schroedinger-1.0) &&
1995 1997
                            require libschroedinger schroedinger/schro.h schro_init $(pkg-config --libs schroedinger-1.0)
... ...
@@ -2317,6 +2329,8 @@ echo "libfaad dlopened          ${libfaadbin-no}"
2317 2317
 echo "libgsm enabled            ${libgsm-no}"
2318 2318
 echo "libmp3lame enabled        ${libmp3lame-no}"
2319 2319
 echo "libnut enabled            ${libnut-no}"
2320
+echo "libopencore-amrnb support ${libopencore_amrnb-no}"
2321
+echo "libopencore-amrwb support ${libopencore_amrwb-no}"
2320 2322
 echo "libopenjpeg enabled       ${libopenjpeg-no}"
2321 2323
 echo "libschroedinger enabled   ${libschroedinger-no}"
2322 2324
 echo "libspeex enabled          ${libspeex-no}"
... ...
@@ -18,7 +18,22 @@ explicitly requested by passing the appropriate flags to @file{./configure}.
18 18
 
19 19
 AMR comes in two different flavors, wideband and narrowband. FFmpeg can make
20 20
 use of the AMR wideband (floating-point mode) and the AMR narrowband
21
-(floating-point mode) reference decoders and encoders.
21
+(floating-point mode) reference decoders and encoders (libamr) as well as
22
+the OpenCORE libraries for AMR-NB decoding/encoding and AMR-WB decoding.
23
+
24
+@subsection OpenCORE
25
+
26
+Go to @url{http://gitorious.org/opencore-amr/} and follow the instructions for
27
+installing the libraries. Then pass @code{--enable-libopencore-amrnb} and/or
28
+@code{--enable-libopencore-amrwb} to configure to enable the libraries.
29
+
30
+Note that OpenCORE is under the Apache License 2.0 (see
31
+@url{http://www.apache.org/licenses/LICENSE-2.0} for details), which is
32
+incompatible with the LGPL version 2.1 and GPL version 2. You have to
33
+upgrade FFmpeg's license to LGPL version 3 (or if you have enabled
34
+GPL components, GPL version 3) to use it.
35
+
36
+@subsection libamr
22 37
 
23 38
 Go to @url{http://www.penguin.cz/~utx/amr} and follow the instructions for
24 39
 installing the libraries. Then pass @code{--enable-libamr-nb} and/or
... ...
@@ -511,9 +526,10 @@ following image formats are supported:
511 511
     @tab Used in Westwood Studios games like Command and Conquer.
512 512
 @item ADPCM Yamaha           @tab  X  @tab  X
513 513
 @item AMR-NB                 @tab  E  @tab  E
514
-    @tab supported through external library libamrnb
514
+    @tab supported through external libraries libamrnb and libopencore-amrnb
515 515
 @item AMR-WB                 @tab  E  @tab  E
516
-    @tab supported through external library libamrwb
516
+    @tab decoding supported through external libraries libamrwb and libopencore-amrwb,
517
+         encoding supported through external library libamrwb
517 518
 @item Apple lossless audio   @tab  X  @tab  X
518 519
     @tab QuickTime fourcc 'alac'
519 520
 @item Atrac 3                @tab     @tab  X
... ...
@@ -366,6 +366,8 @@ OBJS-$(CONFIG_LIBFAAC)                 += libfaac.o
366 366
 OBJS-$(CONFIG_LIBFAAD)                 += libfaad.o
367 367
 OBJS-$(CONFIG_LIBGSM)                  += libgsm.o
368 368
 OBJS-$(CONFIG_LIBMP3LAME)              += libmp3lame.o
369
+OBJS-$(CONFIG_LIBOPENCORE_AMRNB)       += libopencore-amr.o
370
+OBJS-$(CONFIG_LIBOPENCORE_AMRWB)       += libopencore-amr.o
369 371
 OBJS-$(CONFIG_LIBOPENJPEG)             += libopenjpeg.o
370 372
 OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o libschroedinger.o libdirac_libschro.o
371 373
 OBJS-$(CONFIG_LIBSCHROEDINGER_ENCODER) += libschroedingerenc.o libschroedinger.o libdirac_libschro.o
... ...
@@ -294,6 +294,8 @@ void avcodec_register_all(void)
294 294
     REGISTER_ENCDEC  (LIBGSM, libgsm);
295 295
     REGISTER_ENCDEC  (LIBGSM_MS, libgsm_ms);
296 296
     REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
297
+    REGISTER_ENCDEC  (LIBOPENCORE_AMRNB, libopencore_amrnb);
298
+    REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb);
297 299
     REGISTER_DECODER (LIBOPENJPEG, libopenjpeg);
298 300
     REGISTER_ENCDEC  (LIBSCHROEDINGER, libschroedinger);
299 301
     REGISTER_DECODER (LIBSPEEX, libspeex);
300 302
new file mode 100644
... ...
@@ -0,0 +1,325 @@
0
+/*
1
+ * AMR Audio decoder stub
2
+ * Copyright (c) 2003 the ffmpeg project
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+#include "avcodec.h"
22
+
23
+static void amr_decode_fix_avctx(AVCodecContext *avctx)
24
+{
25
+    const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB);
26
+
27
+    if (!avctx->sample_rate)
28
+        avctx->sample_rate = 8000 * is_amr_wb;
29
+
30
+    if (!avctx->channels)
31
+        avctx->channels = 1;
32
+
33
+    avctx->frame_size = 160 * is_amr_wb;
34
+    avctx->sample_fmt = SAMPLE_FMT_S16;
35
+}
36
+
37
+#if CONFIG_LIBOPENCORE_AMRNB
38
+
39
+#include <opencore-amrnb/interf_dec.h>
40
+#include <opencore-amrnb/interf_enc.h>
41
+
42
+static const char nb_bitrate_unsupported[] =
43
+    "bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n";
44
+
45
+/* Common code for fixed and float version*/
46
+typedef struct AMR_bitrates {
47
+    int       rate;
48
+    enum Mode mode;
49
+} AMR_bitrates;
50
+
51
+/* Match desired bitrate */
52
+static int getBitrateMode(int bitrate)
53
+{
54
+    /* make the correspondance between bitrate and mode */
55
+    AMR_bitrates rates[] = { { 4750, MR475},
56
+                             { 5150, MR515},
57
+                             { 5900, MR59},
58
+                             { 6700, MR67},
59
+                             { 7400, MR74},
60
+                             { 7950, MR795},
61
+                             {10200, MR102},
62
+                             {12200, MR122}, };
63
+    int i;
64
+
65
+    for (i = 0; i < 8; i++)
66
+        if (rates[i].rate == bitrate)
67
+            return rates[i].mode;
68
+    /* no bitrate matching, return an error */
69
+    return -1;
70
+}
71
+
72
+typedef struct AMRContext {
73
+    int   frameCount;
74
+    void *decState;
75
+    int  *enstate;
76
+    int   enc_bitrate;
77
+} AMRContext;
78
+
79
+static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
80
+{
81
+    AMRContext *s = avctx->priv_data;
82
+
83
+    s->frameCount = 0;
84
+    s->decState   = Decoder_Interface_init();
85
+    if (!s->decState) {
86
+        av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n");
87
+        return -1;
88
+    }
89
+
90
+    amr_decode_fix_avctx(avctx);
91
+
92
+    if (avctx->channels > 1) {
93
+        av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n");
94
+        return -1;
95
+    }
96
+
97
+    return 0;
98
+}
99
+
100
+static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
101
+{
102
+    AMRContext *s = avctx->priv_data;
103
+
104
+    Decoder_Interface_exit(s->decState);
105
+    return 0;
106
+}
107
+
108
+static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
109
+                               int *data_size, AVPacket *avpkt)
110
+{
111
+    const uint8_t *buf = avpkt->data;
112
+    int buf_size       = avpkt->size;
113
+    AMRContext *s = avctx->priv_data;
114
+    const uint8_t *amrData = buf;
115
+    static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
116
+    enum Mode dec_mode;
117
+    int packet_size;
118
+
119
+    /* av_log(NULL, AV_LOG_DEBUG, "amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",
120
+              buf, buf_size, s->frameCount); */
121
+
122
+    dec_mode = (buf[0] >> 3) & 0x000F;
123
+    packet_size = block_size[dec_mode] + 1;
124
+
125
+    if (packet_size > buf_size) {
126
+        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
127
+               buf_size, packet_size);
128
+        return -1;
129
+    }
130
+
131
+    s->frameCount++;
132
+    /* av_log(NULL, AV_LOG_DEBUG, "packet_size=%d amrData= 0x%X %X %X %X\n",
133
+              packet_size, amrData[0], amrData[1], amrData[2], amrData[3]); */
134
+    /* call decoder */
135
+    Decoder_Interface_Decode(s->decState, amrData, data, 0);
136
+    *data_size = 160 * 2;
137
+
138
+    return packet_size;
139
+}
140
+
141
+AVCodec libopencore_amrnb_decoder = {
142
+    "libopencore_amrnb",
143
+    CODEC_TYPE_AUDIO,
144
+    CODEC_ID_AMR_NB,
145
+    sizeof(AMRContext),
146
+    amr_nb_decode_init,
147
+    NULL,
148
+    amr_nb_decode_close,
149
+    amr_nb_decode_frame,
150
+    .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
151
+};
152
+
153
+static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
154
+{
155
+    AMRContext *s = avctx->priv_data;
156
+
157
+    s->frameCount = 0;
158
+
159
+    if (avctx->sample_rate != 8000) {
160
+        av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
161
+        return -1;
162
+    }
163
+
164
+    if (avctx->channels != 1) {
165
+        av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
166
+        return -1;
167
+    }
168
+
169
+    avctx->frame_size  = 160;
170
+    avctx->coded_frame = avcodec_alloc_frame();
171
+
172
+    s->enstate=Encoder_Interface_init(0);
173
+    if (!s->enstate) {
174
+        av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
175
+        return -1;
176
+    }
177
+
178
+    if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) {
179
+        av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
180
+        return -1;
181
+    }
182
+
183
+    return 0;
184
+}
185
+
186
+static av_cold int amr_nb_encode_close(AVCodecContext *avctx)
187
+{
188
+    AMRContext *s = avctx->priv_data;
189
+
190
+    Encoder_Interface_exit(s->enstate);
191
+    av_freep(&avctx->coded_frame);
192
+    return 0;
193
+}
194
+
195
+static int amr_nb_encode_frame(AVCodecContext *avctx,
196
+                               unsigned char *frame/*out*/,
197
+                               int buf_size, void *data/*in*/)
198
+{
199
+    AMRContext *s = avctx->priv_data;
200
+    int written;
201
+
202
+    if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) {
203
+        av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
204
+        return -1;
205
+    }
206
+
207
+    written = Encoder_Interface_Encode(s->enstate, s->enc_bitrate, data,
208
+                                       frame, 0);
209
+    /* av_log(NULL, AV_LOG_DEBUG, "amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",
210
+              written, s->enc_bitrate, frame[0] ); */
211
+
212
+    return written;
213
+}
214
+
215
+AVCodec libopencore_amrnb_encoder = {
216
+    "libopencore_amrnb",
217
+    CODEC_TYPE_AUDIO,
218
+    CODEC_ID_AMR_NB,
219
+    sizeof(AMRContext),
220
+    amr_nb_encode_init,
221
+    amr_nb_encode_frame,
222
+    amr_nb_encode_close,
223
+    NULL,
224
+    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
225
+    .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Narrow-Band"),
226
+};
227
+
228
+#endif
229
+
230
+/* -----------AMR wideband ------------*/
231
+#if CONFIG_LIBOPENCORE_AMRWB
232
+
233
+#ifdef _TYPEDEF_H
234
+//To avoid duplicate typedefs from typedef in amr-nb
235
+#define typedef_h
236
+#endif
237
+
238
+#include <opencore-amrwb/dec_if.h>
239
+#include <opencore-amrwb/if_rom.h>
240
+
241
+static const char wb_bitrate_unsupported[] =
242
+    "bitrate not supported: use one of 6.6k, 8.85k, 12.65k, 14.25k, 15.85k, 18.25k, 19.85k, 23.05k, or 23.85k\n";
243
+
244
+/* Common code for fixed and float version*/
245
+typedef struct AMRWB_bitrates {
246
+    int rate;
247
+    int mode;
248
+} AMRWB_bitrates;
249
+
250
+typedef struct AMRWBContext {
251
+    int    frameCount;
252
+    void  *state;
253
+    int    mode;
254
+    Word16 allow_dtx;
255
+} AMRWBContext;
256
+
257
+static av_cold int amr_wb_decode_init(AVCodecContext *avctx)
258
+{
259
+    AMRWBContext *s = avctx->priv_data;
260
+
261
+    s->frameCount = 0;
262
+    s->state      = D_IF_init();
263
+
264
+    amr_decode_fix_avctx(avctx);
265
+
266
+    if (avctx->channels > 1) {
267
+        av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n");
268
+        return -1;
269
+    }
270
+
271
+    return 0;
272
+}
273
+
274
+static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
275
+                               int *data_size, AVPacket *avpkt)
276
+{
277
+    const uint8_t *buf = avpkt->data;
278
+    int buf_size       = avpkt->size;
279
+    AMRWBContext *s = avctx->priv_data;
280
+    const uint8_t *amrData = buf;
281
+    int mode;
282
+    int packet_size;
283
+    static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
284
+
285
+    if (!buf_size)
286
+        /* nothing to do */
287
+        return 0;
288
+
289
+    mode = (amrData[0] >> 3) & 0x000F;
290
+    packet_size = block_size[mode];
291
+
292
+    if (packet_size > buf_size) {
293
+        av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
294
+               buf_size, packet_size + 1);
295
+        return -1;
296
+    }
297
+
298
+    s->frameCount++;
299
+    D_IF_decode(s->state, amrData, data, _good_frame);
300
+    *data_size = 320 * 2;
301
+    return packet_size;
302
+}
303
+
304
+static int amr_wb_decode_close(AVCodecContext *avctx)
305
+{
306
+    AMRWBContext *s = avctx->priv_data;
307
+
308
+    D_IF_exit(s->state);
309
+    return 0;
310
+}
311
+
312
+AVCodec libopencore_amrwb_decoder = {
313
+    "libopencore_amrwb",
314
+    CODEC_TYPE_AUDIO,
315
+    CODEC_ID_AMR_WB,
316
+    sizeof(AMRWBContext),
317
+    amr_wb_decode_init,
318
+    NULL,
319
+    amr_wb_decode_close,
320
+    amr_wb_decode_frame,
321
+    .long_name = NULL_IF_CONFIG_SMALL("OpenCORE Adaptive Multi-Rate (AMR) Wide-Band"),
322
+};
323
+
324
+#endif /* CONFIG_LIBOPENCORE_AMRWB */