Commit | Line | Data |
---|---|---|
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 | |
28 | * have to download the code separately. Two versions exists: One fixed-point | |
29 | * and one with floats. For some reason the float-encoder is significant faster | |
30 | * at least on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102). | |
31 | * Both float and fixed point are supported for AMR-NB, but only float for | |
32 | * AMR-WB. | |
33 | * | |
34 | * \section AMR-NB | |
35 | * | |
36 | * \subsection Float | |
37 | * The float version (default) can be downloaded from: | |
2c48a21c | 38 | * http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip |
e0b67c76 | 39 | * Extract the source into \c "ffmpeg/libavcodec/amr_float". |
7038fa61 | 40 | * Enable it by passing \c "--enable-amr-nb" to \c "./configure". |
e0b67c76 PI |
41 | * |
42 | * \subsection Fixed-point | |
43 | * The fixed-point (TS26.073) can be downloaded from: | |
44 | * http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip. | |
45 | * Extract the source into \c "ffmpeg/libavcodec/amr". | |
7038fa61 | 46 | * Enable it by passing \c "--enable-amr-nb-fixed" to \c "./configure". |
e0b67c76 PI |
47 | * |
48 | * \subsection Specification | |
49 | * The specification for AMR-NB can be found in TS 26.071 | |
50 | * (http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other | |
51 | * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm. | |
52 | * | |
53 | * \section AMR-WB | |
54 | * \subsection Float | |
55 | * The reference code can be downloaded from: | |
2c48a21c | 56 | * http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-600.zip |
7038fa61 DB |
57 | * It should be extracted to \c "ffmpeg/libavcodec/amrwb_float". |
58 | * Enable it by passing \c "--enable-amr-wb" to \c "./configure". | |
e0b67c76 PI |
59 | * |
60 | * \subsection Fixed-point | |
61 | * If someone wants to use the fixed point version it can be downloaded from: | |
62 | * http://www.3gpp.org/ftp/Specs/archive/26_series/26.173/26173-571.zip. | |
63 | * | |
64 | * \subsection Specification | |
2c48a21c RS |
65 | * The specification for AMR-WB can be found in TS 26.171 |
66 | * (http://www.3gpp.org/ftp/Specs/html-info/26171.htm) and some other | |
67 | * info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm. | |
e0b67c76 | 68 | * |
bc634f6f | 69 | */ |
d663a1fd | 70 | |
891f64b3 | 71 | #include "avcodec.h" |
72 | ||
6636b7e8 | 73 | #ifdef CONFIG_AMR_NB_FIXED |
bc634f6f ZK |
74 | |
75 | #define MMS_IO | |
76 | ||
891f64b3 | 77 | #include "amr/sp_dec.h" |
78 | #include "amr/d_homing.h" | |
79 | #include "amr/typedef.h" | |
bc634f6f ZK |
80 | #include "amr/sp_enc.h" |
81 | #include "amr/sid_sync.h" | |
82 | #include "amr/e_homing.h" | |
891f64b3 | 83 | |
bc634f6f ZK |
84 | #else |
85 | #include "amr_float/interf_dec.h" | |
86 | #include "amr_float/interf_enc.h" | |
87 | #endif | |
88 | ||
89 | /* Common code for fixed and float version*/ | |
90 | typedef struct AMR_bitrates | |
91 | { | |
db56acd4 | 92 | int rate; |
bc634f6f | 93 | enum Mode mode; |
bc634f6f ZK |
94 | } AMR_bitrates; |
95 | ||
db56acd4 BF |
96 | /* Match desired bitrate */ |
97 | static int getBitrateMode(int bitrate) | |
bc634f6f | 98 | { |
db56acd4 BF |
99 | /* make the correspondance between bitrate and mode */ |
100 | AMR_bitrates rates[]={ {4750,MR475}, | |
101 | {5150,MR515}, | |
102 | {5900,MR59}, | |
103 | {6700,MR67}, | |
104 | {7400,MR74}, | |
105 | {7950,MR795}, | |
106 | {10200,MR102}, | |
107 | {12200,MR122}, | |
bc634f6f ZK |
108 | }; |
109 | int i; | |
be6753c0 | 110 | |
d663a1fd | 111 | for(i=0;i<8;i++) |
bc634f6f | 112 | { |
db56acd4 | 113 | if(rates[i].rate==bitrate) |
bc634f6f ZK |
114 | { |
115 | return(rates[i].mode); | |
116 | } | |
117 | } | |
db56acd4 BF |
118 | /* no bitrate matching, return an error */ |
119 | return -1; | |
bc634f6f ZK |
120 | } |
121 | ||
b500cc2a AV |
122 | static void amr_decode_fix_avctx(AVCodecContext * avctx) |
123 | { | |
124 | const int is_amr_wb = 1 + (avctx->codec_id == CODEC_ID_AMR_WB); | |
125 | ||
126 | if(avctx->sample_rate == 0) | |
127 | { | |
128 | avctx->sample_rate = 8000 * is_amr_wb; | |
129 | } | |
130 | ||
131 | if(avctx->channels == 0) | |
132 | { | |
133 | avctx->channels = 1; | |
134 | } | |
135 | ||
136 | avctx->frame_size = 160 * is_amr_wb; | |
137 | } | |
138 | ||
6636b7e8 | 139 | #ifdef CONFIG_AMR_NB_FIXED |
bc634f6f | 140 | /* fixed point version*/ |
891f64b3 | 141 | /* frame size in serial bitstream file (frame type + serial stream + flags) */ |
142 | #define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5) | |
143 | ||
bc634f6f | 144 | typedef struct AMRContext { |
891f64b3 | 145 | int frameCount; |
146 | Speech_Decode_FrameState *speech_decoder_state; | |
147 | enum RXFrameType rx_type; | |
148 | enum Mode mode; | |
149 | Word16 reset_flag; | |
150 | Word16 reset_flag_old; | |
151 | ||
db56acd4 | 152 | int enc_bitrate; |
bc634f6f ZK |
153 | Speech_Encode_FrameState *enstate; |
154 | sid_syncState *sidstate; | |
155 | enum TXFrameType tx_frametype; | |
bc634f6f | 156 | } AMRContext; |
891f64b3 | 157 | |
158 | static int amr_nb_decode_init(AVCodecContext * avctx) | |
159 | { | |
bc634f6f | 160 | AMRContext *s = avctx->priv_data; |
be6753c0 | 161 | |
891f64b3 | 162 | s->frameCount=0; |
163 | s->speech_decoder_state=NULL; | |
164 | s->rx_type = (enum RXFrameType)0; | |
165 | s->mode= (enum Mode)0; | |
166 | s->reset_flag=0; | |
167 | s->reset_flag_old=1; | |
115329f1 | 168 | |
891f64b3 | 169 | if(Speech_Decode_Frame_init(&s->speech_decoder_state, "Decoder")) |
170 | { | |
560ff809 | 171 | av_log(avctx, AV_LOG_ERROR, "Speech_Decode_Frame_init error\n"); |
891f64b3 | 172 | return -1; |
173 | } | |
b500cc2a AV |
174 | |
175 | amr_decode_fix_avctx(avctx); | |
176 | ||
177 | if(avctx->channels > 1) | |
178 | { | |
179 | av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n"); | |
180 | return -1; | |
181 | } | |
182 | ||
891f64b3 | 183 | return 0; |
184 | } | |
185 | ||
bc634f6f | 186 | static int amr_nb_encode_init(AVCodecContext * avctx) |
891f64b3 | 187 | { |
bc634f6f | 188 | AMRContext *s = avctx->priv_data; |
be6753c0 | 189 | |
bc634f6f ZK |
190 | s->frameCount=0; |
191 | s->speech_decoder_state=NULL; | |
192 | s->rx_type = (enum RXFrameType)0; | |
193 | s->mode= (enum Mode)0; | |
194 | s->reset_flag=0; | |
195 | s->reset_flag_old=1; | |
115329f1 | 196 | |
bc634f6f ZK |
197 | if(avctx->sample_rate!=8000) |
198 | { | |
7910d134 | 199 | av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); |
bc634f6f ZK |
200 | return -1; |
201 | } | |
202 | ||
203 | if(avctx->channels!=1) | |
204 | { | |
7910d134 | 205 | av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); |
bc634f6f ZK |
206 | return -1; |
207 | } | |
208 | ||
209 | avctx->frame_size=160; | |
210 | avctx->coded_frame= avcodec_alloc_frame(); | |
211 | ||
212 | if(Speech_Encode_Frame_init(&s->enstate, 0, "encoder") || sid_sync_init (&s->sidstate)) | |
213 | { | |
7910d134 | 214 | av_log(avctx, AV_LOG_ERROR, "Speech_Encode_Frame_init error\n"); |
bc634f6f ZK |
215 | return -1; |
216 | } | |
217 | ||
db56acd4 BF |
218 | if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) |
219 | { | |
220 | av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); | |
221 | return -1; | |
222 | } | |
bc634f6f ZK |
223 | |
224 | return 0; | |
225 | } | |
226 | ||
227 | static int amr_nb_encode_close(AVCodecContext * avctx) | |
228 | { | |
229 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 230 | |
bc634f6f ZK |
231 | Speech_Encode_Frame_exit(&s->enstate); |
232 | sid_sync_exit (&s->sidstate); | |
233 | av_freep(&avctx->coded_frame); | |
234 | return 0; | |
235 | } | |
236 | ||
237 | static int amr_nb_decode_close(AVCodecContext * avctx) | |
238 | { | |
239 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 240 | |
891f64b3 | 241 | Speech_Decode_Frame_exit(&s->speech_decoder_state); |
bc634f6f | 242 | return 0; |
891f64b3 | 243 | } |
244 | ||
245 | static int amr_nb_decode_frame(AVCodecContext * avctx, | |
246 | void *data, int *data_size, | |
247 | uint8_t * buf, int buf_size) | |
248 | { | |
bc634f6f | 249 | AMRContext *s = avctx->priv_data; |
891f64b3 | 250 | uint8_t*amrData=buf; |
251 | int offset=0; | |
891f64b3 | 252 | UWord8 toc, q, ft; |
891f64b3 | 253 | Word16 serial[SERIAL_FRAMESIZE]; /* coded bits */ |
254 | Word16 *synth; | |
255 | UWord8 *packed_bits; | |
891f64b3 | 256 | static Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; |
257 | int i; | |
258 | ||
bc634f6f | 259 | //printf("amr_decode_frame data_size=%i buf=0x%X buf_size=%d frameCount=%d!!\n",*data_size,buf,buf_size,s->frameCount); |
891f64b3 | 260 | |
261 | synth=data; | |
262 | ||
bc634f6f | 263 | toc=amrData[offset]; |
891f64b3 | 264 | /* read rest of the frame based on ToC byte */ |
265 | q = (toc >> 2) & 0x01; | |
266 | ft = (toc >> 3) & 0x0F; | |
267 | ||
bc634f6f ZK |
268 | //printf("offset=%d, packet_size=%d amrData= 0x%X %X %X %X\n",offset,packed_size[ft],amrData[offset],amrData[offset+1],amrData[offset+2],amrData[offset+3]); |
269 | ||
270 | offset++; | |
271 | ||
891f64b3 | 272 | packed_bits=amrData+offset; |
273 | ||
274 | offset+=packed_size[ft]; | |
275 | ||
bc634f6f | 276 | //Unsort and unpack bits |
891f64b3 | 277 | s->rx_type = UnpackBits(q, ft, packed_bits, &s->mode, &serial[1]); |
278 | ||
bc634f6f | 279 | //We have a new frame |
891f64b3 | 280 | s->frameCount++; |
281 | ||
115329f1 | 282 | if (s->rx_type == RX_NO_DATA) |
891f64b3 | 283 | { |
284 | s->mode = s->speech_decoder_state->prev_mode; | |
285 | } | |
286 | else { | |
287 | s->speech_decoder_state->prev_mode = s->mode; | |
288 | } | |
115329f1 | 289 | |
891f64b3 | 290 | /* if homed: check if this frame is another homing frame */ |
291 | if (s->reset_flag_old == 1) | |
292 | { | |
293 | /* only check until end of first subframe */ | |
294 | s->reset_flag = decoder_homing_frame_test_first(&serial[1], s->mode); | |
295 | } | |
296 | /* produce encoder homing frame if homed & input=decoder homing frame */ | |
297 | if ((s->reset_flag != 0) && (s->reset_flag_old != 0)) | |
298 | { | |
299 | for (i = 0; i < L_FRAME; i++) | |
300 | { | |
301 | synth[i] = EHF_MASK; | |
302 | } | |
303 | } | |
304 | else | |
115329f1 | 305 | { |
891f64b3 | 306 | /* decode frame */ |
307 | Speech_Decode_Frame(s->speech_decoder_state, s->mode, &serial[1], s->rx_type, synth); | |
308 | } | |
309 | ||
bc634f6f | 310 | //Each AMR-frame results in 160 16-bit samples |
891f64b3 | 311 | *data_size+=160*2; |
312 | synth+=160; | |
115329f1 | 313 | |
891f64b3 | 314 | /* if not homed: check whether current frame is a homing frame */ |
315 | if (s->reset_flag_old == 0) | |
316 | { | |
317 | /* check whole frame */ | |
318 | s->reset_flag = decoder_homing_frame_test(&serial[1], s->mode); | |
319 | } | |
320 | /* reset decoder if current frame is a homing frame */ | |
321 | if (s->reset_flag != 0) | |
322 | { | |
323 | Speech_Decode_Frame_reset(s->speech_decoder_state); | |
324 | } | |
325 | s->reset_flag_old = s->reset_flag; | |
115329f1 | 326 | |
bc634f6f ZK |
327 | return offset; |
328 | } | |
329 | ||
330 | ||
331 | static int amr_nb_encode_frame(AVCodecContext *avctx, | |
bb270c08 | 332 | unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
bc634f6f ZK |
333 | { |
334 | short serial_data[250] = {0}; | |
bc634f6f ZK |
335 | AMRContext *s = avctx->priv_data; |
336 | int written; | |
115329f1 | 337 | |
bc634f6f | 338 | s->reset_flag = encoder_homing_frame_test(data); |
115329f1 DB |
339 | |
340 | Speech_Encode_Frame(s->enstate, s->enc_bitrate, data, &serial_data[1], &s->mode); | |
341 | ||
bc634f6f ZK |
342 | /* add frame type and mode */ |
343 | sid_sync (s->sidstate, s->mode, &s->tx_frametype); | |
115329f1 | 344 | |
bc634f6f | 345 | written = PackBits(s->mode, s->enc_bitrate, s->tx_frametype, &serial_data[1], frame); |
115329f1 | 346 | |
bc634f6f ZK |
347 | if (s->reset_flag != 0) |
348 | { | |
349 | Speech_Encode_Frame_reset(s->enstate); | |
350 | sid_sync_reset(s->sidstate); | |
351 | } | |
352 | return written; | |
353 | } | |
354 | ||
355 | ||
6636b7e8 | 356 | #elif defined(CONFIG_AMR_NB) /* Float point version*/ |
bc634f6f ZK |
357 | |
358 | typedef struct AMRContext { | |
359 | int frameCount; | |
360 | void * decState; | |
361 | int *enstate; | |
db56acd4 | 362 | int enc_bitrate; |
bc634f6f ZK |
363 | } AMRContext; |
364 | ||
365 | static int amr_nb_decode_init(AVCodecContext * avctx) | |
366 | { | |
367 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 368 | |
bc634f6f ZK |
369 | s->frameCount=0; |
370 | s->decState=Decoder_Interface_init(); | |
371 | if(!s->decState) | |
372 | { | |
560ff809 | 373 | av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n"); |
bc634f6f ZK |
374 | return -1; |
375 | } | |
b500cc2a AV |
376 | |
377 | amr_decode_fix_avctx(avctx); | |
378 | ||
379 | if(avctx->channels > 1) | |
380 | { | |
381 | av_log(avctx, AV_LOG_ERROR, "amr_nb: multichannel decoding not supported\n"); | |
382 | return -1; | |
383 | } | |
384 | ||
bc634f6f ZK |
385 | return 0; |
386 | } | |
387 | ||
388 | static int amr_nb_encode_init(AVCodecContext * avctx) | |
389 | { | |
390 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 391 | |
bc634f6f | 392 | s->frameCount=0; |
115329f1 | 393 | |
bc634f6f ZK |
394 | if(avctx->sample_rate!=8000) |
395 | { | |
7910d134 | 396 | av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); |
bc634f6f ZK |
397 | return -1; |
398 | } | |
399 | ||
400 | if(avctx->channels!=1) | |
401 | { | |
7910d134 | 402 | av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); |
bc634f6f ZK |
403 | return -1; |
404 | } | |
405 | ||
406 | avctx->frame_size=160; | |
407 | avctx->coded_frame= avcodec_alloc_frame(); | |
408 | ||
409 | s->enstate=Encoder_Interface_init(0); | |
410 | if(!s->enstate) | |
411 | { | |
7910d134 | 412 | av_log(avctx, AV_LOG_ERROR, "Encoder_Interface_init error\n"); |
bc634f6f ZK |
413 | return -1; |
414 | } | |
415 | ||
db56acd4 BF |
416 | if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) |
417 | { | |
418 | av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); | |
419 | return -1; | |
420 | } | |
bc634f6f ZK |
421 | |
422 | return 0; | |
423 | } | |
424 | ||
425 | static int amr_nb_decode_close(AVCodecContext * avctx) | |
426 | { | |
427 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 428 | |
bc634f6f ZK |
429 | Decoder_Interface_exit(s->decState); |
430 | return 0; | |
431 | } | |
432 | ||
433 | static int amr_nb_encode_close(AVCodecContext * avctx) | |
434 | { | |
435 | AMRContext *s = avctx->priv_data; | |
be6753c0 | 436 | |
bc634f6f ZK |
437 | Encoder_Interface_exit(s->enstate); |
438 | av_freep(&avctx->coded_frame); | |
439 | return 0; | |
440 | } | |
441 | ||
442 | static int amr_nb_decode_frame(AVCodecContext * avctx, | |
443 | void *data, int *data_size, | |
444 | uint8_t * buf, int buf_size) | |
445 | { | |
c4f452fd | 446 | AMRContext *s = avctx->priv_data; |
bc634f6f | 447 | uint8_t*amrData=buf; |
bc634f6f ZK |
448 | static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; |
449 | enum Mode dec_mode; | |
450 | int packet_size; | |
bc634f6f | 451 | |
a319bbac | 452 | /* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */ |
115329f1 | 453 | |
a319bbac RH |
454 | dec_mode = (buf[0] >> 3) & 0x000F; |
455 | packet_size = block_size[dec_mode]+1; | |
456 | ||
457 | if(packet_size > buf_size) { | |
458 | av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size); | |
459 | return -1; | |
460 | } | |
115329f1 | 461 | |
a319bbac RH |
462 | s->frameCount++; |
463 | /* av_log(NULL,AV_LOG_DEBUG,"packet_size=%d amrData= 0x%X %X %X %X\n",packet_size,amrData[0],amrData[1],amrData[2],amrData[3]); */ | |
464 | /* call decoder */ | |
465 | Decoder_Interface_Decode(s->decState, amrData, data, 0); | |
466 | *data_size=160*2; | |
115329f1 | 467 | |
a319bbac | 468 | return packet_size; |
891f64b3 | 469 | } |
470 | ||
bc634f6f | 471 | static int amr_nb_encode_frame(AVCodecContext *avctx, |
bb270c08 | 472 | unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
bc634f6f | 473 | { |
c4f452fd | 474 | AMRContext *s = avctx->priv_data; |
bc634f6f ZK |
475 | int written; |
476 | ||
db56acd4 BF |
477 | if((s->enc_bitrate=getBitrateMode(avctx->bit_rate))<0) |
478 | { | |
479 | av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); | |
480 | return -1; | |
481 | } | |
4ec0ccb1 | 482 | |
115329f1 DB |
483 | written = Encoder_Interface_Encode(s->enstate, |
484 | s->enc_bitrate, | |
485 | data, | |
486 | frame, | |
bc634f6f | 487 | 0); |
1ba02582 | 488 | /* av_log(NULL,AV_LOG_DEBUG,"amr_nb_encode_frame encoded %u bytes, bitrate %u, first byte was %#02x\n",written, s->enc_bitrate, frame[0] ); */ |
bc634f6f ZK |
489 | |
490 | return written; | |
491 | } | |
492 | ||
493 | #endif | |
494 | ||
6636b7e8 | 495 | #if defined(CONFIG_AMR_NB) || defined(CONFIG_AMR_NB_FIXED) |
399d8401 | 496 | |
891f64b3 | 497 | AVCodec amr_nb_decoder = |
498 | { | |
499 | "amr_nb", | |
500 | CODEC_TYPE_AUDIO, | |
501 | CODEC_ID_AMR_NB, | |
bc634f6f | 502 | sizeof(AMRContext), |
891f64b3 | 503 | amr_nb_decode_init, |
504 | NULL, | |
bc634f6f | 505 | amr_nb_decode_close, |
891f64b3 | 506 | amr_nb_decode_frame, |
507 | }; | |
508 | ||
bc634f6f ZK |
509 | AVCodec amr_nb_encoder = |
510 | { | |
511 | "amr_nb", | |
512 | CODEC_TYPE_AUDIO, | |
513 | CODEC_ID_AMR_NB, | |
514 | sizeof(AMRContext), | |
515 | amr_nb_encode_init, | |
516 | amr_nb_encode_frame, | |
517 | amr_nb_encode_close, | |
518 | NULL, | |
519 | }; | |
d663a1fd | 520 | |
399d8401 MB |
521 | #endif |
522 | ||
d663a1fd | 523 | /* -----------AMR wideband ------------*/ |
6636b7e8 | 524 | #ifdef CONFIG_AMR_WB |
d663a1fd MN |
525 | |
526 | #ifdef _TYPEDEF_H | |
527 | //To avoid duplicate typedefs from typdef in amr-nb | |
528 | #define typedef_h | |
529 | #endif | |
530 | ||
531 | #include "amrwb_float/enc_if.h" | |
532 | #include "amrwb_float/dec_if.h" | |
533 | ||
534 | /* Common code for fixed and float version*/ | |
535 | typedef struct AMRWB_bitrates | |
536 | { | |
db56acd4 | 537 | int rate; |
d663a1fd | 538 | int mode; |
d663a1fd MN |
539 | } AMRWB_bitrates; |
540 | ||
541 | static int getWBBitrateMode(int bitrate) | |
542 | { | |
db56acd4 BF |
543 | /* make the correspondance between bitrate and mode */ |
544 | AMRWB_bitrates rates[]={ {6600,0}, | |
545 | {8850,1}, | |
546 | {12650,2}, | |
547 | {14250,3}, | |
548 | {15850,4}, | |
549 | {18250,5}, | |
550 | {19850,6}, | |
551 | {23050,7}, | |
552 | {23850,8}, | |
d663a1fd MN |
553 | }; |
554 | int i; | |
555 | ||
556 | for(i=0;i<9;i++) | |
557 | { | |
db56acd4 | 558 | if(rates[i].rate==bitrate) |
d663a1fd MN |
559 | { |
560 | return(rates[i].mode); | |
561 | } | |
562 | } | |
db56acd4 BF |
563 | /* no bitrate matching, return an error */ |
564 | return -1; | |
d663a1fd MN |
565 | } |
566 | ||
567 | ||
568 | typedef struct AMRWBContext { | |
569 | int frameCount; | |
570 | void *state; | |
571 | int mode; | |
572 | Word16 allow_dtx; | |
573 | } AMRWBContext; | |
574 | ||
575 | static int amr_wb_encode_init(AVCodecContext * avctx) | |
576 | { | |
c4f452fd | 577 | AMRWBContext *s = avctx->priv_data; |
be6753c0 | 578 | |
d663a1fd | 579 | s->frameCount=0; |
115329f1 | 580 | |
d663a1fd MN |
581 | if(avctx->sample_rate!=16000) |
582 | { | |
7910d134 | 583 | av_log(avctx, AV_LOG_ERROR, "Only 16000Hz sample rate supported\n"); |
d663a1fd MN |
584 | return -1; |
585 | } | |
586 | ||
587 | if(avctx->channels!=1) | |
588 | { | |
7910d134 | 589 | av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); |
d663a1fd MN |
590 | return -1; |
591 | } | |
592 | ||
db56acd4 BF |
593 | if((s->mode=getWBBitrateMode(avctx->bit_rate))<0) |
594 | { | |
595 | av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); | |
596 | return -1; | |
597 | } | |
598 | ||
d663a1fd MN |
599 | avctx->frame_size=320; |
600 | avctx->coded_frame= avcodec_alloc_frame(); | |
601 | ||
602 | s->state = E_IF_init(); | |
d663a1fd MN |
603 | s->allow_dtx=0; |
604 | ||
605 | return 0; | |
606 | } | |
607 | ||
608 | static int amr_wb_encode_close(AVCodecContext * avctx) | |
609 | { | |
c4f452fd | 610 | AMRWBContext *s = avctx->priv_data; |
be6753c0 | 611 | |
d663a1fd MN |
612 | E_IF_exit(s->state); |
613 | av_freep(&avctx->coded_frame); | |
614 | s->frameCount++; | |
615 | return 0; | |
616 | } | |
617 | ||
618 | static int amr_wb_encode_frame(AVCodecContext *avctx, | |
bb270c08 | 619 | unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
d663a1fd | 620 | { |
c4f452fd | 621 | AMRWBContext *s = avctx->priv_data; |
4ec0ccb1 | 622 | int size; |
e7a5854d | 623 | |
db56acd4 BF |
624 | if((s->mode=getWBBitrateMode(avctx->bit_rate))<0) |
625 | { | |
626 | av_log(avctx, AV_LOG_ERROR, "bitrate not supported\n"); | |
627 | return -1; | |
628 | } | |
4ec0ccb1 | 629 | size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx); |
d663a1fd MN |
630 | return size; |
631 | } | |
632 | ||
633 | static int amr_wb_decode_init(AVCodecContext * avctx) | |
634 | { | |
c4f452fd | 635 | AMRWBContext *s = avctx->priv_data; |
be6753c0 | 636 | |
d663a1fd MN |
637 | s->frameCount=0; |
638 | s->state = D_IF_init(); | |
b500cc2a AV |
639 | |
640 | amr_decode_fix_avctx(avctx); | |
641 | ||
642 | if(avctx->channels > 1) | |
643 | { | |
644 | av_log(avctx, AV_LOG_ERROR, "amr_wb: multichannel decoding not supported\n"); | |
645 | return -1; | |
646 | } | |
647 | ||
d663a1fd MN |
648 | return 0; |
649 | } | |
650 | ||
651 | extern const UWord8 block_size[]; | |
652 | ||
653 | static int amr_wb_decode_frame(AVCodecContext * avctx, | |
654 | void *data, int *data_size, | |
655 | uint8_t * buf, int buf_size) | |
656 | { | |
c4f452fd | 657 | AMRWBContext *s = avctx->priv_data; |
d663a1fd | 658 | uint8_t*amrData=buf; |
d663a1fd MN |
659 | int mode; |
660 | int packet_size; | |
d663a1fd | 661 | |
a319bbac RH |
662 | if(buf_size==0) { |
663 | /* nothing to do */ | |
664 | return 0; | |
665 | } | |
666 | ||
667 | mode = (amrData[0] >> 3) & 0x000F; | |
668 | packet_size = block_size[mode]; | |
669 | ||
670 | if(packet_size > buf_size) { | |
671 | av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1); | |
672 | return -1; | |
d663a1fd | 673 | } |
115329f1 | 674 | |
a319bbac RH |
675 | s->frameCount++; |
676 | D_IF_decode( s->state, amrData, data, _good_frame); | |
677 | *data_size=320*2; | |
678 | return packet_size; | |
d663a1fd MN |
679 | } |
680 | ||
681 | static int amr_wb_decode_close(AVCodecContext * avctx) | |
682 | { | |
c4f452fd | 683 | AMRWBContext *s = avctx->priv_data; |
be6753c0 | 684 | |
d663a1fd MN |
685 | D_IF_exit(s->state); |
686 | return 0; | |
687 | } | |
688 | ||
689 | AVCodec amr_wb_decoder = | |
690 | { | |
691 | "amr_wb", | |
692 | CODEC_TYPE_AUDIO, | |
693 | CODEC_ID_AMR_WB, | |
694 | sizeof(AMRWBContext), | |
695 | amr_wb_decode_init, | |
696 | NULL, | |
697 | amr_wb_decode_close, | |
698 | amr_wb_decode_frame, | |
699 | }; | |
700 | ||
701 | AVCodec amr_wb_encoder = | |
702 | { | |
703 | "amr_wb", | |
704 | CODEC_TYPE_AUDIO, | |
705 | CODEC_ID_AMR_WB, | |
706 | sizeof(AMRWBContext), | |
707 | amr_wb_encode_init, | |
708 | amr_wb_encode_frame, | |
709 | amr_wb_encode_close, | |
710 | NULL, | |
711 | }; | |
712 | ||
6636b7e8 | 713 | #endif //CONFIG_AMR_WB |