ffmpeg / libavcodec / amr.c @ 5509bffa
History | View | Annotate | Download (16.9 KB)
1 |
/*
|
---|---|
2 |
* AMR Audio decoder stub
|
3 |
* Copyright (c) 2003 the ffmpeg project
|
4 |
*
|
5 |
* This library is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU Lesser General Public
|
7 |
* License as published by the Free Software Foundation; either
|
8 |
* version 2 of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This library is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13 |
* Lesser General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU Lesser General Public
|
16 |
* License along with this library; if not, write to the Free Software
|
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18 |
*/
|
19 |
/*
|
20 |
This code implements amr-nb and amr-wb audio encoder/decoder through external reference
|
21 |
code from www.3gpp.org. The licence of the code from 3gpp is unclear so you
|
22 |
have to download the code separately. Two versions exists: One fixed-point
|
23 |
and one with floats. For some reason the float-encoder is significant faster
|
24 |
atleast on a P4 1.5GHz (0.9s instead of 9.9s on a 30s audio clip at MR102).
|
25 |
Both float and fixed point is supported for amr-nb, but only float for
|
26 |
amr-wb.
|
27 |
|
28 |
--AMR-NB--
|
29 |
The fixed-point (TS26.073) can be downloaded from:
|
30 |
http://www.3gpp.org/ftp/Specs/archive/26_series/26.073/26073-510.zip
|
31 |
Extract the soure into ffmpeg/libavcodec/amr
|
32 |
To use the fixed version run "./configure" with "--enable-amr_nb-fixed"
|
33 |
|
34 |
The float version (default) can be downloaded from:
|
35 |
http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-510.zip
|
36 |
Extract the soure into ffmpeg/libavcodec/amr_float
|
37 |
|
38 |
The specification for amr-nb can be found in TS 26.071
|
39 |
(http://www.3gpp.org/ftp/Specs/html-info/26071.htm) and some other
|
40 |
info at http://www.3gpp.org/ftp/Specs/html-info/26-series.htm
|
41 |
|
42 |
--AMR-WB--
|
43 |
The reference code can be downloaded from:
|
44 |
http://www.3gpp.org/ftp/Specs/archive/26_series/26.204/26204-510.zip
|
45 |
It should be extracted to "libavcodec/amrwb_float". Enable it with
|
46 |
"--enable-amr_wb".
|
47 |
|
48 |
The specification for amr-wb can be downloaded from:
|
49 |
http://www.3gpp.org/ftp/Specs/archive/26_series/26.171/26171-500.zip
|
50 |
|
51 |
If someone want to use the fixed point version it can be downloaded
|
52 |
from: http://www.3gpp.org/ftp/Specs/archive/26_series/26.173/26173-571.zip
|
53 |
|
54 |
*/
|
55 |
|
56 |
#include "avcodec.h" |
57 |
|
58 |
#ifdef AMR_NB_FIXED
|
59 |
|
60 |
#define MMS_IO
|
61 |
|
62 |
#include "amr/sp_dec.h" |
63 |
#include "amr/d_homing.h" |
64 |
#include "amr/typedef.h" |
65 |
#include "amr/sp_enc.h" |
66 |
#include "amr/sid_sync.h" |
67 |
#include "amr/e_homing.h" |
68 |
|
69 |
#else
|
70 |
#include "amr_float/interf_dec.h" |
71 |
#include "amr_float/interf_enc.h" |
72 |
#endif
|
73 |
|
74 |
/* Common code for fixed and float version*/
|
75 |
typedef struct AMR_bitrates |
76 |
{ |
77 |
int startrate;
|
78 |
int stoprate;
|
79 |
enum Mode mode;
|
80 |
|
81 |
} AMR_bitrates; |
82 |
|
83 |
/* Match desired bitrate with closest one*/
|
84 |
static enum Mode getBitrateMode(int bitrate) |
85 |
{ |
86 |
/* Adjusted so that all bitrates can be used from commandline where
|
87 |
only a multiple of 1000 can be specified*/
|
88 |
AMR_bitrates rates[]={ {0,4999,MR475}, //4 |
89 |
{5000,5899,MR515},//5 |
90 |
{5900,6699,MR59},//6 |
91 |
{6700,7000,MR67},//7 |
92 |
{7001,7949,MR74},//8 |
93 |
{7950,9999,MR795},//9 |
94 |
{10000,11999,MR102},//10 |
95 |
{12000,64000,MR122},//12 |
96 |
|
97 |
}; |
98 |
int i;
|
99 |
for(i=0;i<8;i++) |
100 |
{ |
101 |
if(rates[i].startrate<=bitrate && rates[i].stoprate>=bitrate)
|
102 |
{ |
103 |
return(rates[i].mode);
|
104 |
} |
105 |
} |
106 |
/*Return highest possible*/
|
107 |
return(MR122);
|
108 |
} |
109 |
|
110 |
#ifdef AMR_NB_FIXED
|
111 |
/* fixed point version*/
|
112 |
/* frame size in serial bitstream file (frame type + serial stream + flags) */
|
113 |
#define SERIAL_FRAMESIZE (1+MAX_SERIAL_SIZE+5) |
114 |
|
115 |
typedef struct AMRContext { |
116 |
int frameCount;
|
117 |
Speech_Decode_FrameState *speech_decoder_state; |
118 |
enum RXFrameType rx_type;
|
119 |
enum Mode mode;
|
120 |
Word16 reset_flag; |
121 |
Word16 reset_flag_old; |
122 |
|
123 |
enum Mode enc_bitrate;
|
124 |
Speech_Encode_FrameState *enstate; |
125 |
sid_syncState *sidstate; |
126 |
enum TXFrameType tx_frametype;
|
127 |
|
128 |
|
129 |
} AMRContext; |
130 |
|
131 |
static int amr_nb_decode_init(AVCodecContext * avctx) |
132 |
{ |
133 |
AMRContext *s = avctx->priv_data; |
134 |
s->frameCount=0;
|
135 |
s->speech_decoder_state=NULL;
|
136 |
s->rx_type = (enum RXFrameType)0; |
137 |
s->mode= (enum Mode)0; |
138 |
s->reset_flag=0;
|
139 |
s->reset_flag_old=1;
|
140 |
|
141 |
if(Speech_Decode_Frame_init(&s->speech_decoder_state, "Decoder")) |
142 |
{ |
143 |
av_log(avctx, AV_LOG_ERROR, "Speech_Decode_Frame_init error\n");
|
144 |
return -1; |
145 |
} |
146 |
return 0; |
147 |
} |
148 |
|
149 |
static int amr_nb_encode_init(AVCodecContext * avctx) |
150 |
{ |
151 |
AMRContext *s = avctx->priv_data; |
152 |
s->frameCount=0;
|
153 |
s->speech_decoder_state=NULL;
|
154 |
s->rx_type = (enum RXFrameType)0; |
155 |
s->mode= (enum Mode)0; |
156 |
s->reset_flag=0;
|
157 |
s->reset_flag_old=1;
|
158 |
|
159 |
if(avctx->sample_rate!=8000) |
160 |
{ |
161 |
if(avctx->debug)
|
162 |
{ |
163 |
av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n");
|
164 |
} |
165 |
return -1; |
166 |
} |
167 |
|
168 |
if(avctx->channels!=1) |
169 |
{ |
170 |
if(avctx->debug)
|
171 |
{ |
172 |
av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n");
|
173 |
} |
174 |
return -1; |
175 |
} |
176 |
|
177 |
avctx->frame_size=160;
|
178 |
avctx->coded_frame= avcodec_alloc_frame(); |
179 |
|
180 |
if(Speech_Encode_Frame_init(&s->enstate, 0, "encoder") || sid_sync_init (&s->sidstate)) |
181 |
{ |
182 |
if(avctx->debug)
|
183 |
{ |
184 |
av_log(avctx, AV_LOG_DEBUG, "Speech_Encode_Frame_init error\n");
|
185 |
} |
186 |
return -1; |
187 |
} |
188 |
|
189 |
s->enc_bitrate=getBitrateMode(avctx->bit_rate); |
190 |
|
191 |
return 0; |
192 |
} |
193 |
|
194 |
static int amr_nb_encode_close(AVCodecContext * avctx) |
195 |
{ |
196 |
AMRContext *s = avctx->priv_data; |
197 |
Speech_Encode_Frame_exit(&s->enstate); |
198 |
sid_sync_exit (&s->sidstate); |
199 |
av_freep(&avctx->coded_frame); |
200 |
return 0; |
201 |
} |
202 |
|
203 |
static int amr_nb_decode_close(AVCodecContext * avctx) |
204 |
{ |
205 |
AMRContext *s = avctx->priv_data; |
206 |
Speech_Decode_Frame_exit(&s->speech_decoder_state); |
207 |
return 0; |
208 |
} |
209 |
|
210 |
static int amr_nb_decode_frame(AVCodecContext * avctx, |
211 |
void *data, int *data_size, |
212 |
uint8_t * buf, int buf_size)
|
213 |
{ |
214 |
AMRContext *s = avctx->priv_data; |
215 |
|
216 |
uint8_t*amrData=buf; |
217 |
int offset=0; |
218 |
|
219 |
UWord8 toc, q, ft; |
220 |
|
221 |
Word16 serial[SERIAL_FRAMESIZE]; /* coded bits */
|
222 |
Word16 *synth; |
223 |
UWord8 *packed_bits; |
224 |
|
225 |
static Word16 packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0}; |
226 |
int i;
|
227 |
|
228 |
//printf("amr_decode_frame data_size=%i buf=0x%X buf_size=%d frameCount=%d!!\n",*data_size,buf,buf_size,s->frameCount);
|
229 |
|
230 |
synth=data; |
231 |
|
232 |
// while(offset<buf_size)
|
233 |
{ |
234 |
toc=amrData[offset]; |
235 |
/* read rest of the frame based on ToC byte */
|
236 |
q = (toc >> 2) & 0x01; |
237 |
ft = (toc >> 3) & 0x0F; |
238 |
|
239 |
//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]);
|
240 |
|
241 |
offset++; |
242 |
|
243 |
packed_bits=amrData+offset; |
244 |
|
245 |
offset+=packed_size[ft]; |
246 |
|
247 |
//Unsort and unpack bits
|
248 |
s->rx_type = UnpackBits(q, ft, packed_bits, &s->mode, &serial[1]);
|
249 |
|
250 |
//We have a new frame
|
251 |
s->frameCount++; |
252 |
|
253 |
if (s->rx_type == RX_NO_DATA)
|
254 |
{ |
255 |
s->mode = s->speech_decoder_state->prev_mode; |
256 |
} |
257 |
else {
|
258 |
s->speech_decoder_state->prev_mode = s->mode; |
259 |
} |
260 |
|
261 |
/* if homed: check if this frame is another homing frame */
|
262 |
if (s->reset_flag_old == 1) |
263 |
{ |
264 |
/* only check until end of first subframe */
|
265 |
s->reset_flag = decoder_homing_frame_test_first(&serial[1], s->mode);
|
266 |
} |
267 |
/* produce encoder homing frame if homed & input=decoder homing frame */
|
268 |
if ((s->reset_flag != 0) && (s->reset_flag_old != 0)) |
269 |
{ |
270 |
for (i = 0; i < L_FRAME; i++) |
271 |
{ |
272 |
synth[i] = EHF_MASK; |
273 |
} |
274 |
} |
275 |
else
|
276 |
{ |
277 |
/* decode frame */
|
278 |
Speech_Decode_Frame(s->speech_decoder_state, s->mode, &serial[1], s->rx_type, synth);
|
279 |
} |
280 |
|
281 |
//Each AMR-frame results in 160 16-bit samples
|
282 |
*data_size+=160*2; |
283 |
synth+=160;
|
284 |
|
285 |
/* if not homed: check whether current frame is a homing frame */
|
286 |
if (s->reset_flag_old == 0) |
287 |
{ |
288 |
/* check whole frame */
|
289 |
s->reset_flag = decoder_homing_frame_test(&serial[1], s->mode);
|
290 |
} |
291 |
/* reset decoder if current frame is a homing frame */
|
292 |
if (s->reset_flag != 0) |
293 |
{ |
294 |
Speech_Decode_Frame_reset(s->speech_decoder_state); |
295 |
} |
296 |
s->reset_flag_old = s->reset_flag; |
297 |
|
298 |
} |
299 |
return offset;
|
300 |
} |
301 |
|
302 |
|
303 |
static int amr_nb_encode_frame(AVCodecContext *avctx, |
304 |
unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
305 |
{ |
306 |
short serial_data[250] = {0}; |
307 |
|
308 |
AMRContext *s = avctx->priv_data; |
309 |
int written;
|
310 |
|
311 |
s->reset_flag = encoder_homing_frame_test(data); |
312 |
|
313 |
Speech_Encode_Frame(s->enstate, s->enc_bitrate, data, &serial_data[1], &s->mode);
|
314 |
|
315 |
/* add frame type and mode */
|
316 |
sid_sync (s->sidstate, s->mode, &s->tx_frametype); |
317 |
|
318 |
written = PackBits(s->mode, s->enc_bitrate, s->tx_frametype, &serial_data[1], frame);
|
319 |
|
320 |
if (s->reset_flag != 0) |
321 |
{ |
322 |
Speech_Encode_Frame_reset(s->enstate); |
323 |
sid_sync_reset(s->sidstate); |
324 |
} |
325 |
return written;
|
326 |
} |
327 |
|
328 |
|
329 |
#elif defined(AMR_NB) /* Float point version*/ |
330 |
|
331 |
typedef struct AMRContext { |
332 |
int frameCount;
|
333 |
void * decState;
|
334 |
int *enstate;
|
335 |
enum Mode enc_bitrate;
|
336 |
} AMRContext; |
337 |
|
338 |
static int amr_nb_decode_init(AVCodecContext * avctx) |
339 |
{ |
340 |
AMRContext *s = avctx->priv_data; |
341 |
s->frameCount=0;
|
342 |
s->decState=Decoder_Interface_init(); |
343 |
if(!s->decState)
|
344 |
{ |
345 |
av_log(avctx, AV_LOG_ERROR, "Decoder_Interface_init error\r\n");
|
346 |
return -1; |
347 |
} |
348 |
return 0; |
349 |
} |
350 |
|
351 |
static int amr_nb_encode_init(AVCodecContext * avctx) |
352 |
{ |
353 |
AMRContext *s = avctx->priv_data; |
354 |
s->frameCount=0;
|
355 |
|
356 |
if(avctx->sample_rate!=8000) |
357 |
{ |
358 |
if(avctx->debug)
|
359 |
{ |
360 |
av_log(avctx, AV_LOG_DEBUG, "Only 8000Hz sample rate supported\n");
|
361 |
} |
362 |
return -1; |
363 |
} |
364 |
|
365 |
if(avctx->channels!=1) |
366 |
{ |
367 |
if(avctx->debug)
|
368 |
{ |
369 |
av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n");
|
370 |
} |
371 |
return -1; |
372 |
} |
373 |
|
374 |
avctx->frame_size=160;
|
375 |
avctx->coded_frame= avcodec_alloc_frame(); |
376 |
|
377 |
s->enstate=Encoder_Interface_init(0);
|
378 |
if(!s->enstate)
|
379 |
{ |
380 |
if(avctx->debug)
|
381 |
{ |
382 |
av_log(avctx, AV_LOG_DEBUG, "Encoder_Interface_init error\n");
|
383 |
} |
384 |
return -1; |
385 |
} |
386 |
|
387 |
s->enc_bitrate=getBitrateMode(avctx->bit_rate); |
388 |
|
389 |
return 0; |
390 |
} |
391 |
|
392 |
static int amr_nb_decode_close(AVCodecContext * avctx) |
393 |
{ |
394 |
AMRContext *s = avctx->priv_data; |
395 |
Decoder_Interface_exit(s->decState); |
396 |
return 0; |
397 |
} |
398 |
|
399 |
static int amr_nb_encode_close(AVCodecContext * avctx) |
400 |
{ |
401 |
AMRContext *s = avctx->priv_data; |
402 |
Encoder_Interface_exit(s->enstate); |
403 |
av_freep(&avctx->coded_frame); |
404 |
return 0; |
405 |
} |
406 |
|
407 |
static int amr_nb_decode_frame(AVCodecContext * avctx, |
408 |
void *data, int *data_size, |
409 |
uint8_t * buf, int buf_size)
|
410 |
{ |
411 |
AMRContext *s = (AMRContext*)avctx->priv_data; |
412 |
|
413 |
uint8_t*amrData=buf; |
414 |
static short block_size[16]={ 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 }; |
415 |
enum Mode dec_mode;
|
416 |
int packet_size;
|
417 |
|
418 |
/* av_log(NULL,AV_LOG_DEBUG,"amr_decode_frame buf=%p buf_size=%d frameCount=%d!!\n",buf,buf_size,s->frameCount); */
|
419 |
|
420 |
if(buf_size==0) { |
421 |
/* nothing to do */
|
422 |
return 0; |
423 |
} |
424 |
|
425 |
dec_mode = (buf[0] >> 3) & 0x000F; |
426 |
packet_size = block_size[dec_mode]+1;
|
427 |
|
428 |
if(packet_size > buf_size) {
|
429 |
av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size);
|
430 |
return -1; |
431 |
} |
432 |
|
433 |
s->frameCount++; |
434 |
/* 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]); */
|
435 |
/* call decoder */
|
436 |
Decoder_Interface_Decode(s->decState, amrData, data, 0);
|
437 |
*data_size=160*2; |
438 |
|
439 |
return packet_size;
|
440 |
} |
441 |
|
442 |
static int amr_nb_encode_frame(AVCodecContext *avctx, |
443 |
unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
444 |
{ |
445 |
AMRContext *s = (AMRContext*)avctx->priv_data; |
446 |
int written;
|
447 |
|
448 |
written = Encoder_Interface_Encode(s->enstate, |
449 |
s->enc_bitrate, |
450 |
data, |
451 |
frame, |
452 |
0);
|
453 |
/* 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] ); */
|
454 |
|
455 |
return written;
|
456 |
} |
457 |
|
458 |
#endif
|
459 |
|
460 |
#if defined(AMR_NB) || defined(AMR_NB_FIXED)
|
461 |
|
462 |
AVCodec amr_nb_decoder = |
463 |
{ |
464 |
"amr_nb",
|
465 |
CODEC_TYPE_AUDIO, |
466 |
CODEC_ID_AMR_NB, |
467 |
sizeof(AMRContext),
|
468 |
amr_nb_decode_init, |
469 |
NULL,
|
470 |
amr_nb_decode_close, |
471 |
amr_nb_decode_frame, |
472 |
}; |
473 |
|
474 |
AVCodec amr_nb_encoder = |
475 |
{ |
476 |
"amr_nb",
|
477 |
CODEC_TYPE_AUDIO, |
478 |
CODEC_ID_AMR_NB, |
479 |
sizeof(AMRContext),
|
480 |
amr_nb_encode_init, |
481 |
amr_nb_encode_frame, |
482 |
amr_nb_encode_close, |
483 |
NULL,
|
484 |
}; |
485 |
|
486 |
#endif
|
487 |
|
488 |
/* -----------AMR wideband ------------*/
|
489 |
#ifdef AMR_WB
|
490 |
|
491 |
#ifdef _TYPEDEF_H
|
492 |
//To avoid duplicate typedefs from typdef in amr-nb
|
493 |
#define typedef_h
|
494 |
#endif
|
495 |
|
496 |
#include "amrwb_float/enc_if.h" |
497 |
#include "amrwb_float/dec_if.h" |
498 |
|
499 |
/* Common code for fixed and float version*/
|
500 |
typedef struct AMRWB_bitrates |
501 |
{ |
502 |
int startrate;
|
503 |
int stoprate;
|
504 |
int mode;
|
505 |
|
506 |
} AMRWB_bitrates; |
507 |
|
508 |
static int getWBBitrateMode(int bitrate) |
509 |
{ |
510 |
/* Adjusted so that all bitrates can be used from commandline where
|
511 |
only a multiple of 1000 can be specified*/
|
512 |
AMRWB_bitrates rates[]={ {0,7999,0}, //6.6kHz |
513 |
{8000,9999,1},//8.85 |
514 |
{10000,13000,2},//12.65 |
515 |
{13001,14999,3},//14.25 |
516 |
{15000,17000,4},//15.85 |
517 |
{17001,18000,5},//18.25 |
518 |
{18001,22000,6},//19.85 |
519 |
{22001,23000,7},//23.05 |
520 |
{23001,24000,8},//23.85 |
521 |
|
522 |
}; |
523 |
int i;
|
524 |
|
525 |
for(i=0;i<9;i++) |
526 |
{ |
527 |
if(rates[i].startrate<=bitrate && rates[i].stoprate>=bitrate)
|
528 |
{ |
529 |
return(rates[i].mode);
|
530 |
} |
531 |
} |
532 |
/*Return highest possible*/
|
533 |
return(8); |
534 |
} |
535 |
|
536 |
|
537 |
typedef struct AMRWBContext { |
538 |
int frameCount;
|
539 |
void *state;
|
540 |
int mode;
|
541 |
Word16 allow_dtx; |
542 |
} AMRWBContext; |
543 |
|
544 |
static int amr_wb_encode_init(AVCodecContext * avctx) |
545 |
{ |
546 |
AMRWBContext *s = (AMRWBContext*)avctx->priv_data; |
547 |
s->frameCount=0;
|
548 |
|
549 |
if(avctx->sample_rate!=16000) |
550 |
{ |
551 |
if(avctx->debug)
|
552 |
{ |
553 |
av_log(avctx, AV_LOG_DEBUG, "Only 16000Hz sample rate supported\n");
|
554 |
} |
555 |
return -1; |
556 |
} |
557 |
|
558 |
if(avctx->channels!=1) |
559 |
{ |
560 |
if(avctx->debug)
|
561 |
{ |
562 |
av_log(avctx, AV_LOG_DEBUG, "Only mono supported\n");
|
563 |
} |
564 |
return -1; |
565 |
} |
566 |
|
567 |
avctx->frame_size=320;
|
568 |
avctx->coded_frame= avcodec_alloc_frame(); |
569 |
|
570 |
s->state = E_IF_init(); |
571 |
s->mode=getWBBitrateMode(avctx->bit_rate); |
572 |
s->allow_dtx=0;
|
573 |
|
574 |
return 0; |
575 |
} |
576 |
|
577 |
static int amr_wb_encode_close(AVCodecContext * avctx) |
578 |
{ |
579 |
AMRWBContext *s = (AMRWBContext*) avctx->priv_data; |
580 |
E_IF_exit(s->state); |
581 |
av_freep(&avctx->coded_frame); |
582 |
s->frameCount++; |
583 |
return 0; |
584 |
} |
585 |
|
586 |
static int amr_wb_encode_frame(AVCodecContext *avctx, |
587 |
unsigned char *frame/*out*/, int buf_size, void *data/*in*/) |
588 |
{ |
589 |
AMRWBContext *s = (AMRWBContext*) avctx->priv_data; |
590 |
int size = E_IF_encode(s->state, s->mode, data, frame, s->allow_dtx);
|
591 |
return size;
|
592 |
} |
593 |
|
594 |
static int amr_wb_decode_init(AVCodecContext * avctx) |
595 |
{ |
596 |
AMRWBContext *s = (AMRWBContext *)avctx->priv_data; |
597 |
s->frameCount=0;
|
598 |
s->state = D_IF_init(); |
599 |
return 0; |
600 |
} |
601 |
|
602 |
extern const UWord8 block_size[]; |
603 |
|
604 |
static int amr_wb_decode_frame(AVCodecContext * avctx, |
605 |
void *data, int *data_size, |
606 |
uint8_t * buf, int buf_size)
|
607 |
{ |
608 |
AMRWBContext *s = (AMRWBContext*)avctx->priv_data; |
609 |
|
610 |
uint8_t*amrData=buf; |
611 |
int mode;
|
612 |
int packet_size;
|
613 |
|
614 |
if(buf_size==0) { |
615 |
/* nothing to do */
|
616 |
return 0; |
617 |
} |
618 |
|
619 |
mode = (amrData[0] >> 3) & 0x000F; |
620 |
packet_size = block_size[mode]; |
621 |
|
622 |
if(packet_size > buf_size) {
|
623 |
av_log(avctx, AV_LOG_ERROR, "amr frame too short (%u, should be %u)\n", buf_size, packet_size+1); |
624 |
return -1; |
625 |
} |
626 |
|
627 |
s->frameCount++; |
628 |
D_IF_decode( s->state, amrData, data, _good_frame); |
629 |
*data_size=320*2; |
630 |
return packet_size;
|
631 |
} |
632 |
|
633 |
static int amr_wb_decode_close(AVCodecContext * avctx) |
634 |
{ |
635 |
AMRWBContext *s = (AMRWBContext *)avctx->priv_data; |
636 |
D_IF_exit(s->state); |
637 |
return 0; |
638 |
} |
639 |
|
640 |
AVCodec amr_wb_decoder = |
641 |
{ |
642 |
"amr_wb",
|
643 |
CODEC_TYPE_AUDIO, |
644 |
CODEC_ID_AMR_WB, |
645 |
sizeof(AMRWBContext),
|
646 |
amr_wb_decode_init, |
647 |
NULL,
|
648 |
amr_wb_decode_close, |
649 |
amr_wb_decode_frame, |
650 |
}; |
651 |
|
652 |
AVCodec amr_wb_encoder = |
653 |
{ |
654 |
"amr_wb",
|
655 |
CODEC_TYPE_AUDIO, |
656 |
CODEC_ID_AMR_WB, |
657 |
sizeof(AMRWBContext),
|
658 |
amr_wb_encode_init, |
659 |
amr_wb_encode_frame, |
660 |
amr_wb_encode_close, |
661 |
NULL,
|
662 |
}; |
663 |
|
664 |
#endif //AMR_WB |