diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/opus_decoder.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/opus_decoder.c | 259 |
1 files changed, 191 insertions, 68 deletions
diff --git a/lib/rbcodec/codecs/libopus/opus_decoder.c b/lib/rbcodec/codecs/libopus/opus_decoder.c index 3d42bb2e70..b430a4df07 100644 --- a/lib/rbcodec/codecs/libopus/opus_decoder.c +++ b/lib/rbcodec/codecs/libopus/opus_decoder.c | |||
@@ -26,11 +26,11 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | #ifdef HAVE_CONFIG_H | 28 | #ifdef HAVE_CONFIG_H |
29 | #include "opus_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 and you probably want a decent config.h, see README for more details." | 33 | #error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details." |
34 | #endif | 34 | #endif |
35 | 35 | ||
36 | #include <stdarg.h> | 36 | #include <stdarg.h> |
@@ -46,6 +46,7 @@ | |||
46 | #include "structs.h" | 46 | #include "structs.h" |
47 | #include "define.h" | 47 | #include "define.h" |
48 | #include "mathops.h" | 48 | #include "mathops.h" |
49 | #include "cpu_support.h" | ||
49 | 50 | ||
50 | struct OpusDecoder { | 51 | struct OpusDecoder { |
51 | int celt_dec_offset; | 52 | int celt_dec_offset; |
@@ -64,8 +65,13 @@ struct OpusDecoder { | |||
64 | int prev_mode; | 65 | int prev_mode; |
65 | int frame_size; | 66 | int frame_size; |
66 | int prev_redundancy; | 67 | int prev_redundancy; |
68 | int last_packet_duration; | ||
69 | #ifndef FIXED_POINT | ||
70 | opus_val16 softclip_mem[2]; | ||
71 | #endif | ||
67 | 72 | ||
68 | opus_uint32 rangeFinal; | 73 | opus_uint32 rangeFinal; |
74 | int arch; | ||
69 | }; | 75 | }; |
70 | 76 | ||
71 | #ifdef FIXED_POINT | 77 | #ifdef FIXED_POINT |
@@ -115,6 +121,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) | |||
115 | st->Fs = Fs; | 121 | st->Fs = Fs; |
116 | st->DecControl.API_sampleRate = st->Fs; | 122 | st->DecControl.API_sampleRate = st->Fs; |
117 | st->DecControl.nChannelsAPI = st->channels; | 123 | st->DecControl.nChannelsAPI = st->channels; |
124 | st->arch = opus_select_arch(); | ||
118 | 125 | ||
119 | /* Reset decoder */ | 126 | /* Reset decoder */ |
120 | ret = silk_InitDecoder( silk_dec ); | 127 | ret = silk_InitDecoder( silk_dec ); |
@@ -131,7 +138,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) | |||
131 | return OPUS_OK; | 138 | return OPUS_OK; |
132 | } | 139 | } |
133 | 140 | ||
134 | #define STATIC_DECODER_SIZE 26532 /* 26486 for 32bit, 26532 for 64bit environment */ | 141 | #define STATIC_DECODER_SIZE 26540 /* 26540 for 64bit environment */ |
135 | static char s_dec[STATIC_DECODER_SIZE] IBSS_ATTR MEM_ALIGN_ATTR; | 142 | static char s_dec[STATIC_DECODER_SIZE] IBSS_ATTR MEM_ALIGN_ATTR; |
136 | 143 | ||
137 | OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) | 144 | OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) |
@@ -208,8 +215,14 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
208 | int i, silk_ret=0, celt_ret=0; | 215 | int i, silk_ret=0, celt_ret=0; |
209 | ec_dec dec; | 216 | ec_dec dec; |
210 | opus_int32 silk_frame_size; | 217 | opus_int32 silk_frame_size; |
218 | int pcm_silk_size; | ||
211 | VARDECL(opus_int16, pcm_silk); | 219 | VARDECL(opus_int16, pcm_silk); |
212 | VARDECL(opus_val16, pcm_transition); | 220 | int pcm_transition_silk_size; |
221 | VARDECL(opus_val16, pcm_transition_silk); | ||
222 | int pcm_transition_celt_size; | ||
223 | VARDECL(opus_val16, pcm_transition_celt); | ||
224 | opus_val16 *pcm_transition = NULL; /* Silence false positive "may be used uninitialized" warning */ | ||
225 | int redundant_audio_size; | ||
213 | VARDECL(opus_val16, redundant_audio); | 226 | VARDECL(opus_val16, redundant_audio); |
214 | 227 | ||
215 | int audiosize; | 228 | int audiosize; |
@@ -265,33 +278,30 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
265 | } | 278 | } |
266 | } | 279 | } |
267 | 280 | ||
268 | /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */ | 281 | /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do |
269 | if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY) | 282 | multiple calls */ |
270 | { | 283 | if (data==NULL && mode != MODE_SILK_ONLY) |
271 | int nb_samples = 0; | 284 | frame_size = IMIN(frame_size, F20); |
272 | do { | ||
273 | int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0); | ||
274 | if (ret != F20) | ||
275 | { | ||
276 | RESTORE_STACK; | ||
277 | return OPUS_INTERNAL_ERROR; | ||
278 | } | ||
279 | pcm += F20*st->channels; | ||
280 | nb_samples += F20; | ||
281 | } while (nb_samples < frame_size); | ||
282 | RESTORE_STACK; | ||
283 | return frame_size; | ||
284 | } | ||
285 | ALLOC(pcm_transition, F5*st->channels, opus_val16); | ||
286 | 285 | ||
286 | pcm_transition_silk_size = 0; | ||
287 | pcm_transition_celt_size = 0; | ||
287 | if (data!=NULL && st->prev_mode > 0 && ( | 288 | if (data!=NULL && st->prev_mode > 0 && ( |
288 | (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) | 289 | (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) |
289 | || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) | 290 | || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) |
290 | ) | 291 | ) |
291 | { | 292 | { |
292 | transition = 1; | 293 | transition = 1; |
294 | /* Decide where to allocate the stack memory for pcm_transition */ | ||
293 | if (mode == MODE_CELT_ONLY) | 295 | if (mode == MODE_CELT_ONLY) |
294 | opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); | 296 | pcm_transition_celt_size = F5*st->channels; |
297 | else | ||
298 | pcm_transition_silk_size = F5*st->channels; | ||
299 | } | ||
300 | ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16); | ||
301 | if (transition && mode == MODE_CELT_ONLY) | ||
302 | { | ||
303 | pcm_transition = pcm_transition_celt; | ||
304 | opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); | ||
295 | } | 305 | } |
296 | if (audiosize > frame_size) | 306 | if (audiosize > frame_size) |
297 | { | 307 | { |
@@ -302,8 +312,9 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
302 | frame_size = audiosize; | 312 | frame_size = audiosize; |
303 | } | 313 | } |
304 | 314 | ||
305 | ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); | 315 | /* Don't allocate any memory when in CELT-only mode */ |
306 | ALLOC(redundant_audio, F5*st->channels, opus_val16); | 316 | pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : 0; |
317 | ALLOC(pcm_silk, pcm_silk_size, opus_int16); | ||
307 | 318 | ||
308 | /* SILK processing */ | 319 | /* SILK processing */ |
309 | if (mode != MODE_CELT_ONLY) | 320 | if (mode != MODE_CELT_ONLY) |
@@ -417,10 +428,22 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
417 | } | 428 | } |
418 | 429 | ||
419 | if (redundancy) | 430 | if (redundancy) |
431 | { | ||
420 | transition = 0; | 432 | transition = 0; |
433 | pcm_transition_silk_size=0; | ||
434 | } | ||
435 | |||
436 | ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); | ||
421 | 437 | ||
422 | if (transition && mode != MODE_CELT_ONLY) | 438 | if (transition && mode != MODE_CELT_ONLY) |
439 | { | ||
440 | pcm_transition = pcm_transition_silk; | ||
423 | opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); | 441 | opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); |
442 | } | ||
443 | |||
444 | /* Only allocation memory for redundancy if/when needed */ | ||
445 | redundant_audio_size = redundancy ? F5*st->channels : 0; | ||
446 | ALLOC(redundant_audio, redundant_audio_size, opus_val16); | ||
424 | 447 | ||
425 | /* 5 ms redundant frame for CELT->SILK*/ | 448 | /* 5 ms redundant frame for CELT->SILK*/ |
426 | if (redundancy && celt_to_silk) | 449 | if (redundancy && celt_to_silk) |
@@ -534,12 +557,19 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
534 | 557 | ||
535 | st->prev_mode = mode; | 558 | st->prev_mode = mode; |
536 | st->prev_redundancy = redundancy && !celt_to_silk; | 559 | st->prev_redundancy = redundancy && !celt_to_silk; |
560 | |||
561 | if (celt_ret>=0) | ||
562 | { | ||
563 | if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels)) | ||
564 | OPUS_PRINT_INT(audiosize); | ||
565 | } | ||
566 | |||
537 | RESTORE_STACK; | 567 | RESTORE_STACK; |
538 | return celt_ret < 0 ? celt_ret : audiosize; | 568 | return celt_ret < 0 ? celt_ret : audiosize; |
539 | 569 | ||
540 | } | 570 | } |
541 | 571 | ||
542 | static int parse_size(const unsigned char *data, opus_int32 len, short *size) | 572 | static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) |
543 | { | 573 | { |
544 | if (len<1) | 574 | if (len<1) |
545 | { | 575 | { |
@@ -561,14 +591,14 @@ static int parse_size(const unsigned char *data, opus_int32 len, short *size) | |||
561 | 591 | ||
562 | static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | 592 | static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, |
563 | int self_delimited, unsigned char *out_toc, | 593 | int self_delimited, unsigned char *out_toc, |
564 | const unsigned char *frames[48], short size[48], int *payload_offset) | 594 | const unsigned char *frames[48], opus_int16 size[48], int *payload_offset) |
565 | { | 595 | { |
566 | int i, bytes; | 596 | int i, bytes; |
567 | int count; | 597 | int count; |
568 | int cbr; | 598 | int cbr; |
569 | unsigned char ch, toc; | 599 | unsigned char ch, toc; |
570 | int framesize; | 600 | int framesize; |
571 | int last_size; | 601 | opus_int32 last_size; |
572 | const unsigned char *data0 = data; | 602 | const unsigned char *data0 = data; |
573 | 603 | ||
574 | if (size==NULL) | 604 | if (size==NULL) |
@@ -594,7 +624,9 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | |||
594 | { | 624 | { |
595 | if (len&0x1) | 625 | if (len&0x1) |
596 | return OPUS_INVALID_PACKET; | 626 | return OPUS_INVALID_PACKET; |
597 | size[0] = last_size = len/2; | 627 | last_size = len/2; |
628 | /* If last_size doesn't fit in size[0], we'll catch it later */ | ||
629 | size[0] = (opus_int16)last_size; | ||
598 | } | 630 | } |
599 | break; | 631 | break; |
600 | /* Two VBR frames */ | 632 | /* Two VBR frames */ |
@@ -620,16 +652,14 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | |||
620 | /* Padding flag is bit 6 */ | 652 | /* Padding flag is bit 6 */ |
621 | if (ch&0x40) | 653 | if (ch&0x40) |
622 | { | 654 | { |
623 | int padding=0; | ||
624 | int p; | 655 | int p; |
625 | do { | 656 | do { |
626 | if (len<=0) | 657 | if (len<=0) |
627 | return OPUS_INVALID_PACKET; | 658 | return OPUS_INVALID_PACKET; |
628 | p = *data++; | 659 | p = *data++; |
629 | len--; | 660 | len--; |
630 | padding += p==255 ? 254: p; | 661 | len -= p==255 ? 254: p; |
631 | } while (p==255); | 662 | } while (p==255); |
632 | len -= padding; | ||
633 | } | 663 | } |
634 | if (len<0) | 664 | if (len<0) |
635 | return OPUS_INVALID_PACKET; | 665 | return OPUS_INVALID_PACKET; |
@@ -657,7 +687,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | |||
657 | if (last_size*count!=len) | 687 | if (last_size*count!=len) |
658 | return OPUS_INVALID_PACKET; | 688 | return OPUS_INVALID_PACKET; |
659 | for (i=0;i<count-1;i++) | 689 | for (i=0;i<count-1;i++) |
660 | size[i] = last_size; | 690 | size[i] = (opus_int16)last_size; |
661 | } | 691 | } |
662 | break; | 692 | break; |
663 | } | 693 | } |
@@ -685,7 +715,7 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | |||
685 | 1275. Reject them here.*/ | 715 | 1275. Reject them here.*/ |
686 | if (last_size > 1275) | 716 | if (last_size > 1275) |
687 | return OPUS_INVALID_PACKET; | 717 | return OPUS_INVALID_PACKET; |
688 | size[count-1] = last_size; | 718 | size[count-1] = (opus_int16)last_size; |
689 | } | 719 | } |
690 | 720 | ||
691 | if (frames) | 721 | if (frames) |
@@ -701,14 +731,14 @@ static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | |||
701 | *out_toc = toc; | 731 | *out_toc = toc; |
702 | 732 | ||
703 | if (payload_offset) | 733 | if (payload_offset) |
704 | *payload_offset = data-data0; | 734 | *payload_offset = (int)(data-data0); |
705 | 735 | ||
706 | return count; | 736 | return count; |
707 | } | 737 | } |
708 | 738 | ||
709 | int opus_packet_parse(const unsigned char *data, opus_int32 len, | 739 | int opus_packet_parse(const unsigned char *data, opus_int32 len, |
710 | unsigned char *out_toc, const unsigned char *frames[48], | 740 | unsigned char *out_toc, const unsigned char *frames[48], |
711 | short size[48], int *payload_offset) | 741 | opus_int16 size[48], int *payload_offset) |
712 | { | 742 | { |
713 | return opus_packet_parse_impl(data, len, 0, out_toc, | 743 | return opus_packet_parse_impl(data, len, 0, out_toc, |
714 | frames, size, payload_offset); | 744 | frames, size, payload_offset); |
@@ -716,50 +746,120 @@ int opus_packet_parse(const unsigned char *data, opus_int32 len, | |||
716 | 746 | ||
717 | int opus_decode_native(OpusDecoder *st, const unsigned char *data, | 747 | int opus_decode_native(OpusDecoder *st, const unsigned char *data, |
718 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, | 748 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, |
719 | int self_delimited, int *packet_offset) | 749 | int self_delimited, int *packet_offset, int soft_clip) |
720 | { | 750 | { |
721 | int i, nb_samples; | 751 | int i, nb_samples; |
722 | int count, offset; | 752 | int count, offset; |
723 | unsigned char toc; | 753 | unsigned char toc; |
724 | int tot_offset; | 754 | int tot_offset; |
755 | int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; | ||
725 | /* 48 x 2.5 ms = 120 ms */ | 756 | /* 48 x 2.5 ms = 120 ms */ |
726 | short size[48]; | 757 | opus_int16 size[48]; |
727 | if (decode_fec<0 || decode_fec>1) | 758 | if (decode_fec<0 || decode_fec>1) |
728 | return OPUS_BAD_ARG; | 759 | return OPUS_BAD_ARG; |
760 | /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ | ||
761 | if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) | ||
762 | return OPUS_BAD_ARG; | ||
729 | if (len==0 || data==NULL) | 763 | if (len==0 || data==NULL) |
730 | return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); | 764 | { |
731 | else if (len<0) | 765 | int pcm_count=0; |
766 | do { | ||
767 | int ret; | ||
768 | ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0); | ||
769 | if (ret<0) | ||
770 | return ret; | ||
771 | pcm_count += ret; | ||
772 | } while (pcm_count < frame_size); | ||
773 | celt_assert(pcm_count == frame_size); | ||
774 | if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels)) | ||
775 | OPUS_PRINT_INT(pcm_count); | ||
776 | st->last_packet_duration = pcm_count; | ||
777 | return pcm_count; | ||
778 | } else if (len<0) | ||
732 | return OPUS_BAD_ARG; | 779 | return OPUS_BAD_ARG; |
733 | 780 | ||
734 | tot_offset = 0; | 781 | packet_mode = opus_packet_get_mode(data); |
735 | st->mode = opus_packet_get_mode(data); | 782 | packet_bandwidth = opus_packet_get_bandwidth(data); |
736 | st->bandwidth = opus_packet_get_bandwidth(data); | 783 | packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); |
737 | st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); | 784 | packet_stream_channels = opus_packet_get_nb_channels(data); |
738 | st->stream_channels = opus_packet_get_nb_channels(data); | ||
739 | 785 | ||
740 | count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); | 786 | count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); |
787 | |||
788 | data += offset; | ||
789 | |||
790 | if (decode_fec) | ||
791 | { | ||
792 | int duration_copy; | ||
793 | int ret; | ||
794 | /* If no FEC can be present, run the PLC (recursive call) */ | ||
795 | if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) | ||
796 | return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip); | ||
797 | /* Otherwise, run the PLC on everything except the size for which we might have FEC */ | ||
798 | duration_copy = st->last_packet_duration; | ||
799 | if (frame_size-packet_frame_size!=0) | ||
800 | { | ||
801 | ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip); | ||
802 | if (ret<0) | ||
803 | { | ||
804 | st->last_packet_duration = duration_copy; | ||
805 | return ret; | ||
806 | } | ||
807 | celt_assert(ret==frame_size-packet_frame_size); | ||
808 | } | ||
809 | /* Complete with FEC */ | ||
810 | st->mode = packet_mode; | ||
811 | st->bandwidth = packet_bandwidth; | ||
812 | st->frame_size = packet_frame_size; | ||
813 | st->stream_channels = packet_stream_channels; | ||
814 | ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size), | ||
815 | packet_frame_size, 1); | ||
816 | if (ret<0) | ||
817 | return ret; | ||
818 | else { | ||
819 | if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels)) | ||
820 | OPUS_PRINT_INT(frame_size); | ||
821 | st->last_packet_duration = frame_size; | ||
822 | return frame_size; | ||
823 | } | ||
824 | } | ||
825 | tot_offset = 0; | ||
741 | if (count < 0) | 826 | if (count < 0) |
742 | return count; | 827 | return count; |
743 | 828 | ||
744 | data += offset; | ||
745 | tot_offset += offset; | 829 | tot_offset += offset; |
746 | 830 | ||
747 | if (count*st->frame_size > frame_size) | 831 | if (count*packet_frame_size > frame_size) |
748 | return OPUS_BUFFER_TOO_SMALL; | 832 | return OPUS_BUFFER_TOO_SMALL; |
833 | |||
834 | /* Update the state as the last step to avoid updating it on an invalid packet */ | ||
835 | st->mode = packet_mode; | ||
836 | st->bandwidth = packet_bandwidth; | ||
837 | st->frame_size = packet_frame_size; | ||
838 | st->stream_channels = packet_stream_channels; | ||
839 | |||
749 | nb_samples=0; | 840 | nb_samples=0; |
750 | for (i=0;i<count;i++) | 841 | for (i=0;i<count;i++) |
751 | { | 842 | { |
752 | int ret; | 843 | int ret; |
753 | ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, decode_fec); | 844 | ret = opus_decode_frame(st, data, size[i], pcm+nb_samples*st->channels, frame_size-nb_samples, 0); |
754 | if (ret<0) | 845 | if (ret<0) |
755 | return ret; | 846 | return ret; |
847 | celt_assert(ret==packet_frame_size); | ||
756 | data += size[i]; | 848 | data += size[i]; |
757 | tot_offset += size[i]; | 849 | tot_offset += size[i]; |
758 | pcm += ret*st->channels; | ||
759 | nb_samples += ret; | 850 | nb_samples += ret; |
760 | } | 851 | } |
761 | if (packet_offset != NULL) | 852 | if (packet_offset != NULL) |
762 | *packet_offset = tot_offset; | 853 | *packet_offset = tot_offset; |
854 | st->last_packet_duration = nb_samples; | ||
855 | if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) | ||
856 | OPUS_PRINT_INT(nb_samples); | ||
857 | #ifndef FIXED_POINT | ||
858 | if (soft_clip) | ||
859 | opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem); | ||
860 | else | ||
861 | st->softclip_mem[0]=st->softclip_mem[1]=0; | ||
862 | #endif | ||
763 | return nb_samples; | 863 | return nb_samples; |
764 | } | 864 | } |
765 | 865 | ||
@@ -768,7 +868,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, | |||
768 | int opus_decode(OpusDecoder *st, const unsigned char *data, | 868 | int opus_decode(OpusDecoder *st, const unsigned char *data, |
769 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) | 869 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) |
770 | { | 870 | { |
771 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); | 871 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); |
772 | } | 872 | } |
773 | 873 | ||
774 | #ifndef DISABLE_FLOAT_API | 874 | #ifndef DISABLE_FLOAT_API |
@@ -781,7 +881,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, | |||
781 | 881 | ||
782 | ALLOC(out, frame_size*st->channels, opus_int16); | 882 | ALLOC(out, frame_size*st->channels, opus_int16); |
783 | 883 | ||
784 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); | 884 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); |
785 | if (ret > 0) | 885 | if (ret > 0) |
786 | { | 886 | { |
787 | for (i=0;i<ret*st->channels;i++) | 887 | for (i=0;i<ret*st->channels;i++) |
@@ -809,7 +909,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, | |||
809 | 909 | ||
810 | ALLOC(out, frame_size*st->channels, float); | 910 | ALLOC(out, frame_size*st->channels, float); |
811 | 911 | ||
812 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); | 912 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); |
813 | if (ret > 0) | 913 | if (ret > 0) |
814 | { | 914 | { |
815 | for (i=0;i<ret*st->channels;i++) | 915 | for (i=0;i<ret*st->channels;i++) |
@@ -822,7 +922,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, | |||
822 | int opus_decode_float(OpusDecoder *st, const unsigned char *data, | 922 | int opus_decode_float(OpusDecoder *st, const unsigned char *data, |
823 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) | 923 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) |
824 | { | 924 | { |
825 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); | 925 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); |
826 | } | 926 | } |
827 | 927 | ||
828 | #endif | 928 | #endif |
@@ -845,12 +945,20 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
845 | case OPUS_GET_BANDWIDTH_REQUEST: | 945 | case OPUS_GET_BANDWIDTH_REQUEST: |
846 | { | 946 | { |
847 | opus_int32 *value = va_arg(ap, opus_int32*); | 947 | opus_int32 *value = va_arg(ap, opus_int32*); |
948 | if (!value) | ||
949 | { | ||
950 | goto bad_arg; | ||
951 | } | ||
848 | *value = st->bandwidth; | 952 | *value = st->bandwidth; |
849 | } | 953 | } |
850 | break; | 954 | break; |
851 | case OPUS_GET_FINAL_RANGE_REQUEST: | 955 | case OPUS_GET_FINAL_RANGE_REQUEST: |
852 | { | 956 | { |
853 | opus_uint32 *value = va_arg(ap, opus_uint32*); | 957 | opus_uint32 *value = va_arg(ap, opus_uint32*); |
958 | if (!value) | ||
959 | { | ||
960 | goto bad_arg; | ||
961 | } | ||
854 | *value = st->rangeFinal; | 962 | *value = st->rangeFinal; |
855 | } | 963 | } |
856 | break; | 964 | break; |
@@ -869,10 +977,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
869 | case OPUS_GET_SAMPLE_RATE_REQUEST: | 977 | case OPUS_GET_SAMPLE_RATE_REQUEST: |
870 | { | 978 | { |
871 | opus_int32 *value = va_arg(ap, opus_int32*); | 979 | opus_int32 *value = va_arg(ap, opus_int32*); |
872 | if (value==NULL) | 980 | if (!value) |
873 | { | 981 | { |
874 | ret = OPUS_BAD_ARG; | 982 | goto bad_arg; |
875 | break; | ||
876 | } | 983 | } |
877 | *value = st->Fs; | 984 | *value = st->Fs; |
878 | } | 985 | } |
@@ -880,10 +987,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
880 | case OPUS_GET_PITCH_REQUEST: | 987 | case OPUS_GET_PITCH_REQUEST: |
881 | { | 988 | { |
882 | opus_int32 *value = va_arg(ap, opus_int32*); | 989 | opus_int32 *value = va_arg(ap, opus_int32*); |
883 | if (value==NULL) | 990 | if (!value) |
884 | { | 991 | { |
885 | ret = OPUS_BAD_ARG; | 992 | goto bad_arg; |
886 | break; | ||
887 | } | 993 | } |
888 | if (st->prev_mode == MODE_CELT_ONLY) | 994 | if (st->prev_mode == MODE_CELT_ONLY) |
889 | celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); | 995 | celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); |
@@ -894,10 +1000,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
894 | case OPUS_GET_GAIN_REQUEST: | 1000 | case OPUS_GET_GAIN_REQUEST: |
895 | { | 1001 | { |
896 | opus_int32 *value = va_arg(ap, opus_int32*); | 1002 | opus_int32 *value = va_arg(ap, opus_int32*); |
897 | if (value==NULL) | 1003 | if (!value) |
898 | { | 1004 | { |
899 | ret = OPUS_BAD_ARG; | 1005 | goto bad_arg; |
900 | break; | ||
901 | } | 1006 | } |
902 | *value = st->decode_gain; | 1007 | *value = st->decode_gain; |
903 | } | 1008 | } |
@@ -907,12 +1012,21 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
907 | opus_int32 value = va_arg(ap, opus_int32); | 1012 | opus_int32 value = va_arg(ap, opus_int32); |
908 | if (value<-32768 || value>32767) | 1013 | if (value<-32768 || value>32767) |
909 | { | 1014 | { |
910 | ret = OPUS_BAD_ARG; | 1015 | goto bad_arg; |
911 | break; | ||
912 | } | 1016 | } |
913 | st->decode_gain = value; | 1017 | st->decode_gain = value; |
914 | } | 1018 | } |
915 | break; | 1019 | break; |
1020 | case OPUS_GET_LAST_PACKET_DURATION_REQUEST: | ||
1021 | { | ||
1022 | opus_uint32 *value = va_arg(ap, opus_uint32*); | ||
1023 | if (!value) | ||
1024 | { | ||
1025 | goto bad_arg; | ||
1026 | } | ||
1027 | *value = st->last_packet_duration; | ||
1028 | } | ||
1029 | break; | ||
916 | default: | 1030 | default: |
917 | /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ | 1031 | /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ |
918 | ret = OPUS_UNIMPLEMENTED; | 1032 | ret = OPUS_UNIMPLEMENTED; |
@@ -921,6 +1035,9 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...) | |||
921 | 1035 | ||
922 | va_end(ap); | 1036 | va_end(ap); |
923 | return ret; | 1037 | return ret; |
1038 | bad_arg: | ||
1039 | va_end(ap); | ||
1040 | return OPUS_BAD_ARG; | ||
924 | } | 1041 | } |
925 | 1042 | ||
926 | void opus_decoder_destroy(OpusDecoder *st) | 1043 | void opus_decoder_destroy(OpusDecoder *st) |
@@ -989,8 +1106,8 @@ int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) | |||
989 | return packet[1]&0x3F; | 1106 | return packet[1]&0x3F; |
990 | } | 1107 | } |
991 | 1108 | ||
992 | int opus_decoder_get_nb_samples(const OpusDecoder *dec, | 1109 | int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, |
993 | const unsigned char packet[], opus_int32 len) | 1110 | opus_int32 Fs) |
994 | { | 1111 | { |
995 | int samples; | 1112 | int samples; |
996 | int count = opus_packet_get_nb_frames(packet, len); | 1113 | int count = opus_packet_get_nb_frames(packet, len); |
@@ -998,10 +1115,16 @@ int opus_decoder_get_nb_samples(const OpusDecoder *dec, | |||
998 | if (count<0) | 1115 | if (count<0) |
999 | return count; | 1116 | return count; |
1000 | 1117 | ||
1001 | samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); | 1118 | samples = count*opus_packet_get_samples_per_frame(packet, Fs); |
1002 | /* Can't have more than 120 ms */ | 1119 | /* Can't have more than 120 ms */ |
1003 | if (samples*25 > dec->Fs*3) | 1120 | if (samples*25 > Fs*3) |
1004 | return OPUS_INVALID_PACKET; | 1121 | return OPUS_INVALID_PACKET; |
1005 | else | 1122 | else |
1006 | return samples; | 1123 | return samples; |
1007 | } | 1124 | } |
1125 | |||
1126 | int opus_decoder_get_nb_samples(const OpusDecoder *dec, | ||
1127 | const unsigned char packet[], opus_int32 len) | ||
1128 | { | ||
1129 | return opus_packet_get_nb_samples(packet, len, dec->Fs); | ||
1130 | } | ||