Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Side by Side Diff: src/opus_decoder.c

Issue 882843002: Update to opus-HEAD-66611f1. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/opus.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited 1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
2 Written by Jean-Marc Valin and Koen Vos */ 2 Written by Jean-Marc Valin and Koen Vos */
3 /* 3 /*
4 Redistribution and use in source and binary forms, with or without 4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions 5 modification, are permitted provided that the following conditions
6 are met: 6 are met:
7 7
8 - Redistributions of source code must retain the above copyright 8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer. 9 notice, this list of conditions and the following disclaimer.
10 10
(...skipping 15 matching lines...) Expand all
26 */ 26 */
27 27
28 #ifdef HAVE_CONFIG_H 28 #ifdef HAVE_CONFIG_H
29 # include "config.h" 29 # include "config.h"
30 #endif 30 #endif
31 31
32 #ifndef OPUS_BUILD 32 #ifndef OPUS_BUILD
33 # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you nee d other defines as well, as in a config.h. See the included build files for deta ils." 33 # error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you nee d other defines as well, as in a config.h. See the included build files for deta ils."
34 #endif 34 #endif
35 35
36 #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) 36 #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(O PUS_WILL_BE_SLOW)
37 # pragma message "You appear to be compiling without optimization, if so opus wi ll be very slow." 37 # pragma message "You appear to be compiling without optimization, if so opus wi ll be very slow."
38 #endif 38 #endif
39 39
40 #include <stdarg.h> 40 #include <stdarg.h>
41 #include "celt.h" 41 #include "celt.h"
42 #include "opus.h" 42 #include "opus.h"
43 #include "entdec.h" 43 #include "entdec.h"
44 #include "modes.h" 44 #include "modes.h"
45 #include "API.h" 45 #include "API.h"
46 #include "stack_alloc.h" 46 #include "stack_alloc.h"
(...skipping 21 matching lines...) Expand all
68 int mode; 68 int mode;
69 int prev_mode; 69 int prev_mode;
70 int frame_size; 70 int frame_size;
71 int prev_redundancy; 71 int prev_redundancy;
72 int last_packet_duration; 72 int last_packet_duration;
73 #ifndef FIXED_POINT 73 #ifndef FIXED_POINT
74 opus_val16 softclip_mem[2]; 74 opus_val16 softclip_mem[2];
75 #endif 75 #endif
76 76
77 opus_uint32 rangeFinal; 77 opus_uint32 rangeFinal;
78 int arch;
78 }; 79 };
79 80
80 #ifdef FIXED_POINT
81 static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
82 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
83 }
84 #endif
85
86 81
87 int opus_decoder_get_size(int channels) 82 int opus_decoder_get_size(int channels)
88 { 83 {
89 int silkDecSizeBytes, celtDecSizeBytes; 84 int silkDecSizeBytes, celtDecSizeBytes;
90 int ret; 85 int ret;
91 if (channels<1 || channels > 2) 86 if (channels<1 || channels > 2)
92 return 0; 87 return 0;
93 ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); 88 ret = silk_Get_Decoder_Size( &silkDecSizeBytes );
94 if(ret) 89 if(ret)
95 return 0; 90 return 0;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 if(ret)return OPUS_INTERNAL_ERROR; 125 if(ret)return OPUS_INTERNAL_ERROR;
131 126
132 /* Initialize CELT decoder */ 127 /* Initialize CELT decoder */
133 ret = celt_decoder_init(celt_dec, Fs, channels); 128 ret = celt_decoder_init(celt_dec, Fs, channels);
134 if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; 129 if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR;
135 130
136 celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); 131 celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
137 132
138 st->prev_mode = 0; 133 st->prev_mode = 0;
139 st->frame_size = Fs/400; 134 st->frame_size = Fs/400;
135 st->arch = opus_select_arch();
140 return OPUS_OK; 136 return OPUS_OK;
141 } 137 }
142 138
143 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) 139 OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
144 { 140 {
145 int ret; 141 int ret;
146 OpusDecoder *st; 142 OpusDecoder *st;
147 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) 143 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
148 || (channels!=1&&channels!=2)) 144 || (channels!=1&&channels!=2))
149 { 145 {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 CELTDecoder *celt_dec; 204 CELTDecoder *celt_dec;
209 int i, silk_ret=0, celt_ret=0; 205 int i, silk_ret=0, celt_ret=0;
210 ec_dec dec; 206 ec_dec dec;
211 opus_int32 silk_frame_size; 207 opus_int32 silk_frame_size;
212 int pcm_silk_size; 208 int pcm_silk_size;
213 VARDECL(opus_int16, pcm_silk); 209 VARDECL(opus_int16, pcm_silk);
214 int pcm_transition_silk_size; 210 int pcm_transition_silk_size;
215 VARDECL(opus_val16, pcm_transition_silk); 211 VARDECL(opus_val16, pcm_transition_silk);
216 int pcm_transition_celt_size; 212 int pcm_transition_celt_size;
217 VARDECL(opus_val16, pcm_transition_celt); 213 VARDECL(opus_val16, pcm_transition_celt);
218 opus_val16 *pcm_transition; 214 opus_val16 *pcm_transition=NULL;
219 int redundant_audio_size; 215 int redundant_audio_size;
220 VARDECL(opus_val16, redundant_audio); 216 VARDECL(opus_val16, redundant_audio);
221 217
222 int audiosize; 218 int audiosize;
223 int mode; 219 int mode;
224 int transition=0; 220 int transition=0;
225 int start_band; 221 int start_band;
226 int redundancy=0; 222 int redundancy=0;
227 int redundancy_bytes = 0; 223 int redundancy_bytes = 0;
228 int celt_to_silk=0; 224 int celt_to_silk=0;
229 int c; 225 int c;
230 int F2_5, F5, F10, F20; 226 int F2_5, F5, F10, F20;
231 const opus_val16 *window; 227 const opus_val16 *window;
232 opus_uint32 redundant_rng = 0; 228 opus_uint32 redundant_rng = 0;
229 int celt_accum;
233 ALLOC_STACK; 230 ALLOC_STACK;
234 231
235 silk_dec = (char*)st+st->silk_dec_offset; 232 silk_dec = (char*)st+st->silk_dec_offset;
236 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); 233 celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
237 F20 = st->Fs/50; 234 F20 = st->Fs/50;
238 F10 = F20>>1; 235 F10 = F20>>1;
239 F5 = F10>>1; 236 F5 = F10>>1;
240 F2_5 = F5>>1; 237 F2_5 = F5>>1;
241 if (frame_size < F2_5) 238 if (frame_size < F2_5)
242 { 239 {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 return frame_size; 285 return frame_size;
289 } else if (audiosize < F20) 286 } else if (audiosize < F20)
290 { 287 {
291 if (audiosize > F10) 288 if (audiosize > F10)
292 audiosize = F10; 289 audiosize = F10;
293 else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) 290 else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10)
294 audiosize = F5; 291 audiosize = F5;
295 } 292 }
296 } 293 }
297 294
295 /* In fixed-point, we can tell CELT to do the accumulation on top of the
296 SILK PCM buffer. This saves some stack space. */
297 #ifdef FIXED_POINT
298 celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
299 #else
300 celt_accum = 0;
301 #endif
302
298 pcm_transition_silk_size = ALLOC_NONE; 303 pcm_transition_silk_size = ALLOC_NONE;
299 pcm_transition_celt_size = ALLOC_NONE; 304 pcm_transition_celt_size = ALLOC_NONE;
300 if (data!=NULL && st->prev_mode > 0 && ( 305 if (data!=NULL && st->prev_mode > 0 && (
301 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r edundancy) 306 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r edundancy)
302 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) 307 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
303 ) 308 )
304 { 309 {
305 transition = 1; 310 transition = 1;
306 /* Decide where to allocate the stack memory for pcm_transition */ 311 /* Decide where to allocate the stack memory for pcm_transition */
307 if (mode == MODE_CELT_ONLY) 312 if (mode == MODE_CELT_ONLY)
(...skipping 10 matching lines...) Expand all
318 if (audiosize > frame_size) 323 if (audiosize > frame_size)
319 { 324 {
320 /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosiz e, frame_size, mode);*/ 325 /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosiz e, frame_size, mode);*/
321 RESTORE_STACK; 326 RESTORE_STACK;
322 return OPUS_BAD_ARG; 327 return OPUS_BAD_ARG;
323 } else { 328 } else {
324 frame_size = audiosize; 329 frame_size = audiosize;
325 } 330 }
326 331
327 /* Don't allocate any memory when in CELT-only mode */ 332 /* Don't allocate any memory when in CELT-only mode */
328 pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE; 333 pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_siz e)*st->channels : ALLOC_NONE;
329 ALLOC(pcm_silk, pcm_silk_size, opus_int16); 334 ALLOC(pcm_silk, pcm_silk_size, opus_int16);
330 335
331 /* SILK processing */ 336 /* SILK processing */
332 if (mode != MODE_CELT_ONLY) 337 if (mode != MODE_CELT_ONLY)
333 { 338 {
334 int lost_flag, decoded_samples; 339 int lost_flag, decoded_samples;
335 opus_int16 *pcm_ptr = pcm_silk; 340 opus_int16 *pcm_ptr;
341 #ifdef FIXED_POINT
342 if (celt_accum)
343 pcm_ptr = pcm;
344 else
345 #endif
346 pcm_ptr = pcm_silk;
336 347
337 if (st->prev_mode==MODE_CELT_ONLY) 348 if (st->prev_mode==MODE_CELT_ONLY)
338 silk_InitDecoder( silk_dec ); 349 silk_InitDecoder( silk_dec );
339 350
340 /* The SILK PLC cannot produce frames of less than 10 ms */ 351 /* The SILK PLC cannot produce frames of less than 10 ms */
341 st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); 352 st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs);
342 353
343 if (data != NULL) 354 if (data != NULL)
344 { 355 {
345 st->DecControl.nChannelsInternal = st->stream_channels; 356 st->DecControl.nChannelsInternal = st->stream_channels;
(...skipping 13 matching lines...) Expand all
359 st->DecControl.internalSampleRate = 16000; 370 st->DecControl.internalSampleRate = 16000;
360 } 371 }
361 } 372 }
362 373
363 lost_flag = data == NULL ? 1 : 2 * decode_fec; 374 lost_flag = data == NULL ? 1 : 2 * decode_fec;
364 decoded_samples = 0; 375 decoded_samples = 0;
365 do { 376 do {
366 /* Call SILK decoder */ 377 /* Call SILK decoder */
367 int first_frame = decoded_samples == 0; 378 int first_frame = decoded_samples == 0;
368 silk_ret = silk_Decode( silk_dec, &st->DecControl, 379 silk_ret = silk_Decode( silk_dec, &st->DecControl,
369 lost_flag, first_frame, &dec, pcm_ptr, &silk_fra me_size ); 380 lost_flag, first_frame, &dec, pcm_ptr, &silk_fra me_size, st->arch );
370 if( silk_ret ) { 381 if( silk_ret ) {
371 if (lost_flag) { 382 if (lost_flag) {
372 /* PLC failure should not be fatal */ 383 /* PLC failure should not be fatal */
373 silk_frame_size = frame_size; 384 silk_frame_size = frame_size;
374 for (i=0;i<frame_size*st->channels;i++) 385 for (i=0;i<frame_size*st->channels;i++)
375 pcm_ptr[i] = 0; 386 pcm_ptr[i] = 0;
376 } else { 387 } else {
377 RESTORE_STACK; 388 RESTORE_STACK;
378 return OPUS_INTERNAL_ERROR; 389 return OPUS_INTERNAL_ERROR;
379 } 390 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 466
456 /* Only allocation memory for redundancy if/when needed */ 467 /* Only allocation memory for redundancy if/when needed */
457 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; 468 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
458 ALLOC(redundant_audio, redundant_audio_size, opus_val16); 469 ALLOC(redundant_audio, redundant_audio_size, opus_val16);
459 470
460 /* 5 ms redundant frame for CELT->SILK*/ 471 /* 5 ms redundant frame for CELT->SILK*/
461 if (redundancy && celt_to_silk) 472 if (redundancy && celt_to_silk)
462 { 473 {
463 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 474 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
464 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, 475 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
465 redundant_audio, F5, NULL); 476 redundant_audio, F5, NULL, 0);
466 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 477 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
467 } 478 }
468 479
469 /* MUST be after PLC */ 480 /* MUST be after PLC */
470 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); 481 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
471 482
472 if (mode != MODE_SILK_ONLY) 483 if (mode != MODE_SILK_ONLY)
473 { 484 {
474 int celt_frame_size = IMIN(F20, frame_size); 485 int celt_frame_size = IMIN(F20, frame_size);
475 /* Make sure to discard any previous CELT state */ 486 /* Make sure to discard any previous CELT state */
476 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) 487 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
477 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 488 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
478 /* Decode CELT */ 489 /* Decode CELT */
479 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, 490 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
480 len, pcm, celt_frame_size, &dec); 491 len, pcm, celt_frame_size, &dec, celt_accum );
481 } else { 492 } else {
482 unsigned char silence[2] = {0xFF, 0xFF}; 493 unsigned char silence[2] = {0xFF, 0xFF};
483 for (i=0;i<frame_size*st->channels;i++) 494 if (!celt_accum)
484 pcm[i] = 0; 495 {
496 for (i=0;i<frame_size*st->channels;i++)
497 pcm[i] = 0;
498 }
485 /* For hybrid -> SILK transitions, we let the CELT MDCT 499 /* For hybrid -> SILK transitions, we let the CELT MDCT
486 do a fade-out by decoding a silence frame */ 500 do a fade-out by decoding a silence frame */
487 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->pr ev_redundancy) ) 501 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->pr ev_redundancy) )
488 { 502 {
489 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 503 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
490 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); 504 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
491 } 505 }
492 } 506 }
493 507
494 if (mode != MODE_CELT_ONLY) 508 if (mode != MODE_CELT_ONLY && !celt_accum)
495 { 509 {
496 #ifdef FIXED_POINT 510 #ifdef FIXED_POINT
497 for (i=0;i<frame_size*st->channels;i++) 511 for (i=0;i<frame_size*st->channels;i++)
498 pcm[i] = SAT16(pcm[i] + pcm_silk[i]); 512 pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
499 #else 513 #else
500 for (i=0;i<frame_size*st->channels;i++) 514 for (i=0;i<frame_size*st->channels;i++)
501 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); 515 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
502 #endif 516 #endif
503 } 517 }
504 518
505 { 519 {
506 const CELTMode *celt_mode; 520 const CELTMode *celt_mode;
507 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); 521 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
508 window = celt_mode->window; 522 window = celt_mode->window;
509 } 523 }
510 524
511 /* 5 ms redundant frame for SILK->CELT */ 525 /* 5 ms redundant frame for SILK->CELT */
512 if (redundancy && !celt_to_silk) 526 if (redundancy && !celt_to_silk)
513 { 527 {
514 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 528 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
515 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 529 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
516 530
517 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); 531 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
518 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 532 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
519 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channe ls*F2_5, 533 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channe ls*F2_5,
520 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window , st->Fs); 534 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window , st->Fs);
521 } 535 }
522 if (redundancy && celt_to_silk) 536 if (redundancy && celt_to_silk)
523 { 537 {
524 for (c=0;c<st->channels;c++) 538 for (c=0;c<st->channels;c++)
525 { 539 {
526 for (i=0;i<F2_5;i++) 540 for (i=0;i<F2_5;i++)
527 pcm[st->channels*i+c] = redundant_audio[st->channels*i+c]; 541 pcm[st->channels*i+c] = redundant_audio[st->channels*i+c];
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 return OPUS_BAD_ARG; 717 return OPUS_BAD_ARG;
704 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL , 0); 718 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL , 0);
705 } 719 }
706 720
707 #ifndef DISABLE_FLOAT_API 721 #ifndef DISABLE_FLOAT_API
708 int opus_decode_float(OpusDecoder *st, const unsigned char *data, 722 int opus_decode_float(OpusDecoder *st, const unsigned char *data,
709 opus_int32 len, float *pcm, int frame_size, int decode_fec) 723 opus_int32 len, float *pcm, int frame_size, int decode_fec)
710 { 724 {
711 VARDECL(opus_int16, out); 725 VARDECL(opus_int16, out);
712 int ret, i; 726 int ret, i;
727 int nb_samples;
713 ALLOC_STACK; 728 ALLOC_STACK;
714 729
715 if(frame_size<=0) 730 if(frame_size<=0)
716 { 731 {
717 RESTORE_STACK; 732 RESTORE_STACK;
718 return OPUS_BAD_ARG; 733 return OPUS_BAD_ARG;
719 } 734 }
735 if (data != NULL && len > 0 && !decode_fec)
736 {
737 nb_samples = opus_decoder_get_nb_samples(st, data, len);
738 if (nb_samples>0)
739 frame_size = IMIN(frame_size, nb_samples);
740 else
741 return OPUS_INVALID_PACKET;
742 }
720 ALLOC(out, frame_size*st->channels, opus_int16); 743 ALLOC(out, frame_size*st->channels, opus_int16);
721 744
722 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); 745 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
723 if (ret > 0) 746 if (ret > 0)
724 { 747 {
725 for (i=0;i<ret*st->channels;i++) 748 for (i=0;i<ret*st->channels;i++)
726 pcm[i] = (1.f/32768.f)*(out[i]); 749 pcm[i] = (1.f/32768.f)*(out[i]);
727 } 750 }
728 RESTORE_STACK; 751 RESTORE_STACK;
729 return ret; 752 return ret;
730 } 753 }
731 #endif 754 #endif
732 755
733 756
734 #else 757 #else
735 int opus_decode(OpusDecoder *st, const unsigned char *data, 758 int opus_decode(OpusDecoder *st, const unsigned char *data,
736 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) 759 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
737 { 760 {
738 VARDECL(float, out); 761 VARDECL(float, out);
739 int ret, i; 762 int ret, i;
763 int nb_samples;
740 ALLOC_STACK; 764 ALLOC_STACK;
741 765
742 if(frame_size<=0) 766 if(frame_size<=0)
743 { 767 {
744 RESTORE_STACK; 768 RESTORE_STACK;
745 return OPUS_BAD_ARG; 769 return OPUS_BAD_ARG;
746 } 770 }
747 771
772 if (data != NULL && len > 0 && !decode_fec)
773 {
774 nb_samples = opus_decoder_get_nb_samples(st, data, len);
775 if (nb_samples>0)
776 frame_size = IMIN(frame_size, nb_samples);
777 else
778 return OPUS_INVALID_PACKET;
779 }
748 ALLOC(out, frame_size*st->channels, float); 780 ALLOC(out, frame_size*st->channels, float);
749 781
750 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); 782 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
751 if (ret > 0) 783 if (ret > 0)
752 { 784 {
753 for (i=0;i<ret*st->channels;i++) 785 for (i=0;i<ret*st->channels;i++)
754 pcm[i] = FLOAT2INT16(out[i]); 786 pcm[i] = FLOAT2INT16(out[i]);
755 } 787 }
756 RESTORE_STACK; 788 RESTORE_STACK;
757 return ret; 789 return ret;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } else if ((data[0]&0x60) == 0x60) 929 } else if ((data[0]&0x60) == 0x60)
898 { 930 {
899 bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : 931 bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND :
900 OPUS_BANDWIDTH_SUPERWIDEBAND; 932 OPUS_BANDWIDTH_SUPERWIDEBAND;
901 } else { 933 } else {
902 bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); 934 bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
903 } 935 }
904 return bandwidth; 936 return bandwidth;
905 } 937 }
906 938
907 int opus_packet_get_samples_per_frame(const unsigned char *data,
908 opus_int32 Fs)
909 {
910 int audiosize;
911 if (data[0]&0x80)
912 {
913 audiosize = ((data[0]>>3)&0x3);
914 audiosize = (Fs<<audiosize)/400;
915 } else if ((data[0]&0x60) == 0x60)
916 {
917 audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
918 } else {
919 audiosize = ((data[0]>>3)&0x3);
920 if (audiosize == 3)
921 audiosize = Fs*60/1000;
922 else
923 audiosize = (Fs<<audiosize)/100;
924 }
925 return audiosize;
926 }
927
928 int opus_packet_get_nb_channels(const unsigned char *data) 939 int opus_packet_get_nb_channels(const unsigned char *data)
929 { 940 {
930 return (data[0]&0x4) ? 2 : 1; 941 return (data[0]&0x4) ? 2 : 1;
931 } 942 }
932 943
933 int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) 944 int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len)
934 { 945 {
935 int count; 946 int count;
936 if (len<1) 947 if (len<1)
937 return OPUS_BAD_ARG; 948 return OPUS_BAD_ARG;
(...skipping 23 matching lines...) Expand all
961 return OPUS_INVALID_PACKET; 972 return OPUS_INVALID_PACKET;
962 else 973 else
963 return samples; 974 return samples;
964 } 975 }
965 976
966 int opus_decoder_get_nb_samples(const OpusDecoder *dec, 977 int opus_decoder_get_nb_samples(const OpusDecoder *dec,
967 const unsigned char packet[], opus_int32 len) 978 const unsigned char packet[], opus_int32 len)
968 { 979 {
969 return opus_packet_get_nb_samples(packet, len, dec->Fs); 980 return opus_packet_get_nb_samples(packet, len, dec->Fs);
970 } 981 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698