flvdec: expose metadata through the generic metadata API
[libav.git] / libavcodec / libamr.c
CommitLineData
891f64b3 1/*
2 * AMR Audio decoder stub
3 * Copyright (c) 2003 the ffmpeg project
4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
891f64b3 8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
891f64b3 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
891f64b3 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
891f64b3 20 */
115329f1 21
e0b67c76
PI
22 /** @file
23 * Adaptive Multi-Rate (AMR) Audio decoder stub.
24 *
25 * This code implements both an AMR-NarrowBand (AMR-NB) and an AMR-WideBand
26 * (AMR-WB) audio encoder/decoder through external reference code from
27 * http://www.3gpp.org/. The license of the code from 3gpp is unclear so you
1e15e536 28 * have to download the code separately.
e0b67c76
PI
29 *
30 * \section AMR-NB
31 *
e0b67c76 32 * The float version (default) can be downloaded from:
2c48a21c 33 * http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip
e0b67c76 34 *
e0b67c76
PI
35 * \subsection Specification
36 * The specification for AMR-NB can be found in TS 26.071
37 * (http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other
38 * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm.
39 *
40 * \section AMR-WB
9a79101f 41 *
e0b67c76 42 * The reference code can be downloaded from:
2c48a21c 43 * http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-600.zip
e0b67c76 44 *
e0b67c76 45 * \subsection Specification
2c48a21c
RS
46 * The specification for AMR-WB can be found in TS 26.171
47 * (http://www.3gpp.org/ftp/Specs/html-info/26171.htm) and some other
48 * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm.
e0b67c76 49 *
bc634f6f 50 */
d663a1fd 51
891f64b3 52#include "avcodec.h"
53
6532cd55
DB
54static void amr_decode_fix_avctx(AVCodecContext *avctx)
55{
56 const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB);
57
58 if (!avctx->sample_rate)
59 avctx->sample_rate = 8000 * is_amr_wb;
60
61 if (!avctx->channels)
62 avctx->channels = 1;
63
64 avctx->frame_size = 160 * is_amr_wb;
65 avctx->sample_fmt = SAMPLE_FMT_S16;
66}
67
68#if CONFIG_LIBAMR_NB
69
91024272
SB
70#include <amrnb/interf_dec.h>
71#include <amrnb/interf_enc.h>
bc634f6f 72
7d2cc552 73static const char nb_bitrate_unsupported[] =
414425e0 74 "bitrate not supported: use one of 4.75k, 5.15k, 5.9k, 6.7k, 7.4k, 7.95k, 10.2k or 12.2k\n";
414425e0 75
d8ed5bae
DB
76typedef struct AMR_bitrates {
77 int rate;
bc634f6f 78 enum Mode mode;
bc634f6f
ZK
79} AMR_bitrates;
80
db56acd4
BF
81/* Match desired bitrate */
82static int getBitrateMode(int bitrate)
bc634f6f 83{
db56acd4 84 /* make the correspondance between bitrate and mode */
d8ed5bae
DB
85 AMR_bitrates rates[] = { { 4750, MR475},
86 { 5150, MR515},
87 { 5900, MR59},
88 { 6700, MR67},
89 { 7400, MR74},
90 { 7950, MR795},
91 {10200, MR102},
92 {12200, MR122}, };
bc634f6f 93 int i;
be6753c0 94
d8ed5bae
DB
95 for (i = 0; i < 8; i++)
96 if (rates[i].rate == bitrate)
ccd425e7 97 return rates[i].mode;
db56acd4
BF
98 /* no bitrate matching, return an error */
99 return -1;
bc634f6f
ZK
100}
101
bc634f6f 102typedef struct AMRContext {
d8ed5bae
DB
103 int frameCount;
104 void *decState;
105 int *enstate;
106 int enc_bitrate;
bc634f6f
ZK
107} AMRContext;
108
d8ed5bae 109static av_cold int amr_nb_decode_init(AVCodecContext *avctx)
bc634f6f
ZK
110{
111 AMRContext *s = avctx->priv_data;
be6753c0 112
d8ed5bae
DB
113 s->frameCount = 0;
114 s->decState = Decoder_Interface_init();
115 if (!s->decState) {
560ff809 116 av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n");
bc634f6f
ZK
117 return -1;
118 }
b500cc2a
AV
119
120 amr_decode_fix_avctx(avctx);
121
d8ed5bae 122 if (avctx->channels > 1) {
b500cc2a
AV
123 av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n");
124 return -1;
125 }
126
bc634f6f
ZK
127 return 0;
128}
129
d8ed5bae 130static av_cold int amr_nb_decode_close(AVCodecContext *avctx)
c005a3ba
DB
131{
132 AMRContext *s = avctx->priv_data;
133
134 Decoder_Interface_exit(s->decState);
135 return 0;
136}
137
d8ed5bae
DB
138static int amr_nb_decode_frame(AVCodecContext *avctx, void *data,
139 int *data_size, AVPacket *avpkt)
c005a3ba
DB
140{
141 const uint8_t *buf = avpkt->data;
d8ed5bae 142 int buf_size = avpkt->size;
c005a3ba 143 AMRContext *s = avctx->priv_data;
d8ed5bae
DB
144 const uint8_t *amrData = buf;
145 static const uint8_t block_size[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
c005a3ba
DB
146 enum Mode dec_mode;
147 int packet_size;
148
d8ed5bae
DB
149 /* av_log(NULL, AV_LOG_DEBUG, "amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",
150 buf, buf_size, s->frameCount); */
c005a3ba
DB
151
152 dec_mode = (buf[0] >> 3) & 0x000F;
d8ed5bae 153 packet_size = block_size[dec_mode] + 1;
c005a3ba 154
d8ed5bae
DB
155 if (packet_size > buf_size) {
156 av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
157 buf_size, packet_size);
c005a3ba
DB
158 return -1;
159 }
160
161 s->frameCount++;
d8ed5bae
DB
162 /* av_log(NULL, AV_LOG_DEBUG, "packet_size=%d amrData= 0x%X %X %X %X\n",
163 packet_size, amrData[0], amrData[1], amrData[2], amrData[3]); */
c005a3ba
DB
164 /* call decoder */
165 Decoder_Interface_Decode(s->decState, amrData, data, 0);
d8ed5bae 166 *data_size = 160 * 2;
c005a3ba
DB
167
168 return packet_size;
169}
170
d8ed5bae 171AVCodec libamr_nb_decoder = {
c005a3ba
DB
172 "libamr_nb",
173 CODEC_TYPE_AUDIO,
174 CODEC_ID_AMR_NB,
175 sizeof(AMRContext),
176 amr_nb_decode_init,
177 NULL,
178 amr_nb_decode_close,
179 amr_nb_decode_frame,
180 .long_name = NULL_IF_CONFIG_SMALL("libamr-nb Adaptive Multi-Rate (AMR) Narrow-Band"),
181};
182
d8ed5bae 183static av_cold int amr_nb_encode_init(AVCodecContext *avctx)
bc634f6f
ZK
184{
185 AMRContext *s = avctx->priv_data;
be6753c0 186
d8ed5bae 187 s->frameCount = 0;
115329f1 188
d8ed5bae 189 if (avctx->sample_rate != 8000) {
7910d134 190 av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n");
bc634f6f
ZK
191 return -1;
192 }
193
d8ed5bae 194 if (avctx->channels != 1) {
7910d134 195 av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
bc634f6f
ZK
196 return -1;
197 }
198
d8ed5bae
DB
199 avctx->frame_size = 160;
200 avctx->coded_frame = avcodec_alloc_frame();
bc634f6f
ZK
201
202 s->enstate=Encoder_Interface_init(0);
d8ed5bae 203 if (!s->enstate) {
7910d134 204 av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n");
bc634f6f
ZK
205 return -1;
206 }
207
d8ed5bae 208 if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) {
414425e0 209 av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
db56acd4
BF
210 return -1;
211 }
bc634f6f
ZK
212
213 return 0;
214}
215
d8ed5bae 216static av_cold int amr_nb_encode_close(AVCodecContext *avctx)
bc634f6f
ZK
217{
218 AMRContext *s = avctx->priv_data;
be6753c0 219
bc634f6f
ZK
220 Encoder_Interface_exit(s->enstate);
221 av_freep(&avctx->coded_frame);
222 return 0;
223}
224
bc634f6f 225static int amr_nb_encode_frame(AVCodecContext *avctx,
d8ed5bae
DB
226 unsigned char *frame/*out*/,
227 int buf_size, void *data/*in*/)
bc634f6f 228{
c4f452fd 229 AMRContext *s = avctx->priv_data;
bc634f6f
ZK
230 int written;
231
d8ed5bae 232 if ((s->enc_bitrate = getBitrateMode(avctx->bit_rate)) < 0) {
414425e0 233 av_log(avctx, AV_LOG_ERROR, nb_bitrate_unsupported);
db56acd4
BF
234 return -1;
235 }
4ec0ccb1 236
d8ed5bae
DB
237 written = Encoder_Interface_Encode(s->enstate, s->enc_bitrate, data,
238 frame, 0);
239 /* av_log(NULL, AV_LOG_DEBUG, "amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",
240 written, s->enc_bitrate, frame[0] ); */
bc634f6f
ZK
241
242 return written;
243}
244
d8ed5bae 245AVCodec libamr_nb_encoder = {
f5a756ef 246 "libamr_nb",
bc634f6f
ZK
247 CODEC_TYPE_AUDIO,
248 CODEC_ID_AMR_NB,
249 sizeof(AMRContext),
250 amr_nb_encode_init,
251 amr_nb_encode_frame,
252 amr_nb_encode_close,
253 NULL,
fd76c37f 254 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
fe4bf374 255 .long_name = NULL_IF_CONFIG_SMALL("libamr-nb Adaptive Multi-Rate (AMR) Narrow-Band"),
bc634f6f 256};
d663a1fd 257
399d8401
MB
258#endif
259
d663a1fd 260/* -----------AMR wideband ------------*/
b250f9c6 261#if CONFIG_LIBAMR_WB
d663a1fd
MN
262
263#ifdef _TYPEDEF_H
cf6cb7c5 264//To avoid duplicate typedefs from typedef in amr-nb
d663a1fd
MN
265#define typedef_h
266#endif
267
91024272
SB
268#include <amrwb/dec_if.h>
269#include <amrwb/if_rom.h>
d663a1fd 270
4e1424fd
DB
271static const char wb_bitrate_unsupported[] =
272 "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";
273
d8ed5bae 274typedef struct AMRWB_bitrates {
db56acd4 275 int rate;
d663a1fd 276 int mode;
d663a1fd
MN
277} AMRWB_bitrates;
278
9c0ef69a 279typedef struct AMRWBContext {
d8ed5bae
DB
280 int frameCount;
281 void *state;
282 int mode;
9c0ef69a
DB
283 Word16 allow_dtx;
284} AMRWBContext;
285
e09989be
DB
286#if CONFIG_LIBAMR_WB_ENCODER
287
9c0ef69a
DB
288#include <amrwb/enc_if.h>
289
d663a1fd
MN
290static int getWBBitrateMode(int bitrate)
291{
db56acd4 292 /* make the correspondance between bitrate and mode */
d8ed5bae
DB
293 AMRWB_bitrates rates[] = { { 6600, 0},
294 { 8850, 1},
295 {12650, 2},
296 {14250, 3},
297 {15850, 4},
298 {18250, 5},
299 {19850, 6},
300 {23050, 7},
301 {23850, 8}, };
d663a1fd
MN
302 int i;
303
d8ed5bae
DB
304 for (i = 0; i < 9; i++)
305 if (rates[i].rate == bitrate)
ccd425e7 306 return rates[i].mode;
db56acd4
BF
307 /* no bitrate matching, return an error */
308 return -1;
d663a1fd
MN
309}
310
d8ed5bae 311static av_cold int amr_wb_encode_init(AVCodecContext *avctx)
d663a1fd 312{
c4f452fd 313 AMRWBContext *s = avctx->priv_data;
be6753c0 314
d8ed5bae 315 s->frameCount = 0;
115329f1 316
d8ed5bae 317 if (avctx->sample_rate != 16000) {
7910d134 318 av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n");
d663a1fd
MN
319 return -1;
320 }
321
d8ed5bae 322 if (avctx->channels != 1) {
7910d134 323 av_log(avctx, AV_LOG_ERROR, "Only mono supported\n");
d663a1fd
MN
324 return -1;
325 }
326
d8ed5bae 327 if ((s->mode = getWBBitrateMode(avctx->bit_rate)) < 0) {
414425e0 328 av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
db56acd4
BF
329 return -1;
330 }
331
d8ed5bae
DB
332 avctx->frame_size = 320;
333 avctx->coded_frame = avcodec_alloc_frame();
d663a1fd 334
d8ed5bae
DB
335 s->state = E_IF_init();
336 s->allow_dtx = 0;
d663a1fd
MN
337
338 return 0;
339}
340
d8ed5bae 341static int amr_wb_encode_close(AVCodecContext *avctx)
d663a1fd 342{
c4f452fd 343 AMRWBContext *s = avctx->priv_data;
be6753c0 344
d663a1fd
MN
345 E_IF_exit(s->state);
346 av_freep(&avctx->coded_frame);
347 s->frameCount++;
348 return 0;
349}
350
351static int amr_wb_encode_frame(AVCodecContext *avctx,
d8ed5bae
DB
352 unsigned char *frame/*out*/,
353 int buf_size, void *data/*in*/)
d663a1fd 354{
c4f452fd 355 AMRWBContext *s = avctx->priv_data;
4ec0ccb1 356 int size;
e7a5854d 357
d8ed5bae 358 if ((s->mode = getWBBitrateMode(avctx->bit_rate)) < 0) {
414425e0 359 av_log(avctx, AV_LOG_ERROR, wb_bitrate_unsupported);
db56acd4
BF
360 return -1;
361 }
4ec0ccb1 362 size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx);
d663a1fd
MN
363 return size;
364}
365
d8ed5bae 366AVCodec libamr_wb_encoder = {
c005a3ba
DB
367 "libamr_wb",
368 CODEC_TYPE_AUDIO,
369 CODEC_ID_AMR_WB,
370 sizeof(AMRWBContext),
371 amr_wb_encode_init,
372 amr_wb_encode_frame,
373 amr_wb_encode_close,
374 NULL,
375 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
376 .long_name = NULL_IF_CONFIG_SMALL("libamr-wb Adaptive Multi-Rate (AMR) Wide-Band"),
377};
378
e09989be
DB
379#endif
380
d8ed5bae 381static av_cold int amr_wb_decode_init(AVCodecContext *avctx)
d663a1fd 382{
c4f452fd 383 AMRWBContext *s = avctx->priv_data;
be6753c0 384
d8ed5bae
DB
385 s->frameCount = 0;
386 s->state = D_IF_init();
b500cc2a
AV
387
388 amr_decode_fix_avctx(avctx);
389
d8ed5bae 390 if (avctx->channels > 1) {
b500cc2a
AV
391 av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n");
392 return -1;
393 }
394
d663a1fd
MN
395 return 0;
396}
397
d8ed5bae
DB
398static int amr_wb_decode_frame(AVCodecContext *avctx, void *data,
399 int *data_size, AVPacket *avpkt)
d663a1fd 400{
7a00bbad 401 const uint8_t *buf = avpkt->data;
d8ed5bae 402 int buf_size = avpkt->size;
c4f452fd 403 AMRWBContext *s = avctx->priv_data;
d8ed5bae 404 const uint8_t *amrData = buf;
d663a1fd
MN
405 int mode;
406 int packet_size;
a2ce9a99 407 static const uint8_t block_size[16] = {18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1};
d663a1fd 408
d8ed5bae 409 if (!buf_size)
a319bbac
RH
410 /* nothing to do */
411 return 0;
a319bbac
RH
412
413 mode = (amrData[0] >> 3) & 0x000F;
414 packet_size = block_size[mode];
415
d8ed5bae
DB
416 if (packet_size > buf_size) {
417 av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n",
418 buf_size, packet_size + 1);
a319bbac 419 return -1;
d663a1fd 420 }
115329f1 421
a319bbac 422 s->frameCount++;
d8ed5bae
DB
423 D_IF_decode(s->state, amrData, data, _good_frame);
424 *data_size = 320 * 2;
a319bbac 425 return packet_size;
d663a1fd
MN
426}
427
d8ed5bae 428static int amr_wb_decode_close(AVCodecContext *avctx)
d663a1fd 429{
c4f452fd 430 AMRWBContext *s = avctx->priv_data;
be6753c0 431
d663a1fd
MN
432 D_IF_exit(s->state);
433 return 0;
434}
435
d8ed5bae 436AVCodec libamr_wb_decoder = {
f5a756ef 437 "libamr_wb",
d663a1fd
MN
438 CODEC_TYPE_AUDIO,
439 CODEC_ID_AMR_WB,
440 sizeof(AMRWBContext),
441 amr_wb_decode_init,
442 NULL,
443 amr_wb_decode_close,
444 amr_wb_decode_frame,
fe4bf374 445 .long_name = NULL_IF_CONFIG_SMALL("libamr-wb Adaptive Multi-Rate (AMR) Wide-Band"),
d663a1fd
MN
446};
447
f5a756ef 448#endif //CONFIG_LIBAMR_WB