diff options
author | Nils Wallménius <nils@rockbox.org> | 2013-12-11 22:59:14 +0100 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2013-12-16 21:13:23 +0100 |
commit | e3c2ed7a71f65dc721c7210f120259ecd4ff65cb (patch) | |
tree | de593c1e927dcc036f1b6656f1f881995491b3b9 /lib/rbcodec/codecs/libopus/opus_decoder.c | |
parent | d0918b98fa0cfba21208a4fb5ed153687b8f02c3 (diff) | |
download | rockbox-e3c2ed7a71f65dc721c7210f120259ecd4ff65cb.tar.gz rockbox-e3c2ed7a71f65dc721c7210f120259ecd4ff65cb.zip |
Sync libopus to upstream release 1.1
Change-Id: I9fea7460fc33f60faff961b3389dd97b5191463c
Diffstat (limited to 'lib/rbcodec/codecs/libopus/opus_decoder.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/opus_decoder.c | 261 |
1 files changed, 54 insertions, 207 deletions
diff --git a/lib/rbcodec/codecs/libopus/opus_decoder.c b/lib/rbcodec/codecs/libopus/opus_decoder.c index b430a4df07..198d168898 100644 --- a/lib/rbcodec/codecs/libopus/opus_decoder.c +++ b/lib/rbcodec/codecs/libopus/opus_decoder.c | |||
@@ -26,11 +26,15 @@ | |||
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 need other defines as well, as in a config.h. See the included build files for 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 | ||
35 | |||
36 | #if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) | ||
37 | # pragma message "You appear to be compiling without optimization, if so opus will be very slow." | ||
34 | #endif | 38 | #endif |
35 | 39 | ||
36 | #include <stdarg.h> | 40 | #include <stdarg.h> |
@@ -71,11 +75,10 @@ struct OpusDecoder { | |||
71 | #endif | 75 | #endif |
72 | 76 | ||
73 | opus_uint32 rangeFinal; | 77 | opus_uint32 rangeFinal; |
74 | int arch; | ||
75 | }; | 78 | }; |
76 | 79 | ||
77 | #ifdef FIXED_POINT | 80 | #ifdef FIXED_POINT |
78 | static inline opus_int16 SAT16(opus_int32 x) { | 81 | static OPUS_INLINE opus_int16 SAT16(opus_int32 x) { |
79 | return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; | 82 | return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; |
80 | } | 83 | } |
81 | #endif | 84 | #endif |
@@ -121,7 +124,6 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) | |||
121 | st->Fs = Fs; | 124 | st->Fs = Fs; |
122 | st->DecControl.API_sampleRate = st->Fs; | 125 | st->DecControl.API_sampleRate = st->Fs; |
123 | st->DecControl.nChannelsAPI = st->channels; | 126 | st->DecControl.nChannelsAPI = st->channels; |
124 | st->arch = opus_select_arch(); | ||
125 | 127 | ||
126 | /* Reset decoder */ | 128 | /* Reset decoder */ |
127 | ret = silk_InitDecoder( silk_dec ); | 129 | ret = silk_InitDecoder( silk_dec ); |
@@ -152,7 +154,6 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) | |||
152 | *error = OPUS_BAD_ARG; | 154 | *error = OPUS_BAD_ARG; |
153 | return NULL; | 155 | return NULL; |
154 | } | 156 | } |
155 | |||
156 | if (STATIC_DECODER_SIZE >= opus_decoder_get_size(channels)) | 157 | if (STATIC_DECODER_SIZE >= opus_decoder_get_size(channels)) |
157 | st = (OpusDecoder *)s_dec; | 158 | st = (OpusDecoder *)s_dec; |
158 | else | 159 | else |
@@ -265,26 +266,44 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
265 | ec_dec_init(&dec,(unsigned char*)data,len); | 266 | ec_dec_init(&dec,(unsigned char*)data,len); |
266 | } else { | 267 | } else { |
267 | audiosize = frame_size; | 268 | audiosize = frame_size; |
269 | mode = st->prev_mode; | ||
268 | 270 | ||
269 | if (st->prev_mode == 0) | 271 | if (mode == 0) |
270 | { | 272 | { |
271 | /* If we haven't got any packet yet, all we can do is return zeros */ | 273 | /* If we haven't got any packet yet, all we can do is return zeros */ |
272 | for (i=0;i<audiosize*st->channels;i++) | 274 | for (i=0;i<audiosize*st->channels;i++) |
273 | pcm[i] = 0; | 275 | pcm[i] = 0; |
274 | RESTORE_STACK; | 276 | RESTORE_STACK; |
275 | return audiosize; | 277 | return audiosize; |
276 | } else { | ||
277 | mode = st->prev_mode; | ||
278 | } | 278 | } |
279 | } | ||
280 | 279 | ||
281 | /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do | 280 | /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT), |
282 | multiple calls */ | 281 | 10, or 20 (e.g. 12.5 or 30 ms). */ |
283 | if (data==NULL && mode != MODE_SILK_ONLY) | 282 | if (audiosize > F20) |
284 | frame_size = IMIN(frame_size, F20); | 283 | { |
284 | do { | ||
285 | int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0); | ||
286 | if (ret<0) | ||
287 | { | ||
288 | RESTORE_STACK; | ||
289 | return ret; | ||
290 | } | ||
291 | pcm += ret*st->channels; | ||
292 | audiosize -= ret; | ||
293 | } while (audiosize > 0); | ||
294 | RESTORE_STACK; | ||
295 | return frame_size; | ||
296 | } else if (audiosize < F20) | ||
297 | { | ||
298 | if (audiosize > F10) | ||
299 | audiosize = F10; | ||
300 | else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) | ||
301 | audiosize = F5; | ||
302 | } | ||
303 | } | ||
285 | 304 | ||
286 | pcm_transition_silk_size = 0; | 305 | pcm_transition_silk_size = ALLOC_NONE; |
287 | pcm_transition_celt_size = 0; | 306 | pcm_transition_celt_size = ALLOC_NONE; |
288 | if (data!=NULL && st->prev_mode > 0 && ( | 307 | if (data!=NULL && st->prev_mode > 0 && ( |
289 | (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) | 308 | (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) |
290 | || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) | 309 | || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) |
@@ -313,7 +332,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
313 | } | 332 | } |
314 | 333 | ||
315 | /* Don't allocate any memory when in CELT-only mode */ | 334 | /* Don't allocate any memory when in CELT-only mode */ |
316 | pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : 0; | 335 | pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE; |
317 | ALLOC(pcm_silk, pcm_silk_size, opus_int16); | 336 | ALLOC(pcm_silk, pcm_silk_size, opus_int16); |
318 | 337 | ||
319 | /* SILK processing */ | 338 | /* SILK processing */ |
@@ -363,7 +382,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
363 | pcm_ptr[i] = 0; | 382 | pcm_ptr[i] = 0; |
364 | } else { | 383 | } else { |
365 | RESTORE_STACK; | 384 | RESTORE_STACK; |
366 | return OPUS_INVALID_PACKET; | 385 | return OPUS_INTERNAL_ERROR; |
367 | } | 386 | } |
368 | } | 387 | } |
369 | pcm_ptr += silk_frame_size * st->channels; | 388 | pcm_ptr += silk_frame_size * st->channels; |
@@ -430,7 +449,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
430 | if (redundancy) | 449 | if (redundancy) |
431 | { | 450 | { |
432 | transition = 0; | 451 | transition = 0; |
433 | pcm_transition_silk_size=0; | 452 | pcm_transition_silk_size=ALLOC_NONE; |
434 | } | 453 | } |
435 | 454 | ||
436 | ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); | 455 | ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); |
@@ -442,7 +461,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
442 | } | 461 | } |
443 | 462 | ||
444 | /* Only allocation memory for redundancy if/when needed */ | 463 | /* Only allocation memory for redundancy if/when needed */ |
445 | redundant_audio_size = redundancy ? F5*st->channels : 0; | 464 | redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; |
446 | ALLOC(redundant_audio, redundant_audio_size, opus_val16); | 465 | ALLOC(redundant_audio, redundant_audio_size, opus_val16); |
447 | 466 | ||
448 | /* 5 ms redundant frame for CELT->SILK*/ | 467 | /* 5 ms redundant frame for CELT->SILK*/ |
@@ -569,189 +588,13 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, | |||
569 | 588 | ||
570 | } | 589 | } |
571 | 590 | ||
572 | static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) | ||
573 | { | ||
574 | if (len<1) | ||
575 | { | ||
576 | *size = -1; | ||
577 | return -1; | ||
578 | } else if (data[0]<252) | ||
579 | { | ||
580 | *size = data[0]; | ||
581 | return 1; | ||
582 | } else if (len<2) | ||
583 | { | ||
584 | *size = -1; | ||
585 | return -1; | ||
586 | } else { | ||
587 | *size = 4*data[1] + data[0]; | ||
588 | return 2; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, | ||
593 | int self_delimited, unsigned char *out_toc, | ||
594 | const unsigned char *frames[48], opus_int16 size[48], int *payload_offset) | ||
595 | { | ||
596 | int i, bytes; | ||
597 | int count; | ||
598 | int cbr; | ||
599 | unsigned char ch, toc; | ||
600 | int framesize; | ||
601 | opus_int32 last_size; | ||
602 | const unsigned char *data0 = data; | ||
603 | |||
604 | if (size==NULL) | ||
605 | return OPUS_BAD_ARG; | ||
606 | |||
607 | framesize = opus_packet_get_samples_per_frame(data, 48000); | ||
608 | |||
609 | cbr = 0; | ||
610 | toc = *data++; | ||
611 | len--; | ||
612 | last_size = len; | ||
613 | switch (toc&0x3) | ||
614 | { | ||
615 | /* One frame */ | ||
616 | case 0: | ||
617 | count=1; | ||
618 | break; | ||
619 | /* Two CBR frames */ | ||
620 | case 1: | ||
621 | count=2; | ||
622 | cbr = 1; | ||
623 | if (!self_delimited) | ||
624 | { | ||
625 | if (len&0x1) | ||
626 | return OPUS_INVALID_PACKET; | ||
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; | ||
630 | } | ||
631 | break; | ||
632 | /* Two VBR frames */ | ||
633 | case 2: | ||
634 | count = 2; | ||
635 | bytes = parse_size(data, len, size); | ||
636 | len -= bytes; | ||
637 | if (size[0]<0 || size[0] > len) | ||
638 | return OPUS_INVALID_PACKET; | ||
639 | data += bytes; | ||
640 | last_size = len-size[0]; | ||
641 | break; | ||
642 | /* Multiple CBR/VBR frames (from 0 to 120 ms) */ | ||
643 | default: /*case 3:*/ | ||
644 | if (len<1) | ||
645 | return OPUS_INVALID_PACKET; | ||
646 | /* Number of frames encoded in bits 0 to 5 */ | ||
647 | ch = *data++; | ||
648 | count = ch&0x3F; | ||
649 | if (count <= 0 || framesize*count > 5760) | ||
650 | return OPUS_INVALID_PACKET; | ||
651 | len--; | ||
652 | /* Padding flag is bit 6 */ | ||
653 | if (ch&0x40) | ||
654 | { | ||
655 | int p; | ||
656 | do { | ||
657 | if (len<=0) | ||
658 | return OPUS_INVALID_PACKET; | ||
659 | p = *data++; | ||
660 | len--; | ||
661 | len -= p==255 ? 254: p; | ||
662 | } while (p==255); | ||
663 | } | ||
664 | if (len<0) | ||
665 | return OPUS_INVALID_PACKET; | ||
666 | /* VBR flag is bit 7 */ | ||
667 | cbr = !(ch&0x80); | ||
668 | if (!cbr) | ||
669 | { | ||
670 | /* VBR case */ | ||
671 | last_size = len; | ||
672 | for (i=0;i<count-1;i++) | ||
673 | { | ||
674 | bytes = parse_size(data, len, size+i); | ||
675 | len -= bytes; | ||
676 | if (size[i]<0 || size[i] > len) | ||
677 | return OPUS_INVALID_PACKET; | ||
678 | data += bytes; | ||
679 | last_size -= bytes+size[i]; | ||
680 | } | ||
681 | if (last_size<0) | ||
682 | return OPUS_INVALID_PACKET; | ||
683 | } else if (!self_delimited) | ||
684 | { | ||
685 | /* CBR case */ | ||
686 | last_size = len/count; | ||
687 | if (last_size*count!=len) | ||
688 | return OPUS_INVALID_PACKET; | ||
689 | for (i=0;i<count-1;i++) | ||
690 | size[i] = (opus_int16)last_size; | ||
691 | } | ||
692 | break; | ||
693 | } | ||
694 | /* Self-delimited framing has an extra size for the last frame. */ | ||
695 | if (self_delimited) | ||
696 | { | ||
697 | bytes = parse_size(data, len, size+count-1); | ||
698 | len -= bytes; | ||
699 | if (size[count-1]<0 || size[count-1] > len) | ||
700 | return OPUS_INVALID_PACKET; | ||
701 | data += bytes; | ||
702 | /* For CBR packets, apply the size to all the frames. */ | ||
703 | if (cbr) | ||
704 | { | ||
705 | if (size[count-1]*count > len) | ||
706 | return OPUS_INVALID_PACKET; | ||
707 | for (i=0;i<count-1;i++) | ||
708 | size[i] = size[count-1]; | ||
709 | } else if(size[count-1] > last_size) | ||
710 | return OPUS_INVALID_PACKET; | ||
711 | } else | ||
712 | { | ||
713 | /* Because it's not encoded explicitly, it's possible the size of the | ||
714 | last packet (or all the packets, for the CBR case) is larger than | ||
715 | 1275. Reject them here.*/ | ||
716 | if (last_size > 1275) | ||
717 | return OPUS_INVALID_PACKET; | ||
718 | size[count-1] = (opus_int16)last_size; | ||
719 | } | ||
720 | |||
721 | if (frames) | ||
722 | { | ||
723 | for (i=0;i<count;i++) | ||
724 | { | ||
725 | frames[i] = data; | ||
726 | data += size[i]; | ||
727 | } | ||
728 | } | ||
729 | |||
730 | if (out_toc) | ||
731 | *out_toc = toc; | ||
732 | |||
733 | if (payload_offset) | ||
734 | *payload_offset = (int)(data-data0); | ||
735 | |||
736 | return count; | ||
737 | } | ||
738 | |||
739 | int opus_packet_parse(const unsigned char *data, opus_int32 len, | ||
740 | unsigned char *out_toc, const unsigned char *frames[48], | ||
741 | opus_int16 size[48], int *payload_offset) | ||
742 | { | ||
743 | return opus_packet_parse_impl(data, len, 0, out_toc, | ||
744 | frames, size, payload_offset); | ||
745 | } | ||
746 | |||
747 | int opus_decode_native(OpusDecoder *st, const unsigned char *data, | 591 | int opus_decode_native(OpusDecoder *st, const unsigned char *data, |
748 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, | 592 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, |
749 | int self_delimited, int *packet_offset, int soft_clip) | 593 | int self_delimited, opus_int32 *packet_offset, int soft_clip) |
750 | { | 594 | { |
751 | int i, nb_samples; | 595 | int i, nb_samples; |
752 | int count, offset; | 596 | int count, offset; |
753 | unsigned char toc; | 597 | unsigned char toc; |
754 | int tot_offset; | ||
755 | int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; | 598 | int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; |
756 | /* 48 x 2.5 ms = 120 ms */ | 599 | /* 48 x 2.5 ms = 120 ms */ |
757 | opus_int16 size[48]; | 600 | opus_int16 size[48]; |
@@ -783,7 +626,10 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, | |||
783 | packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); | 626 | packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); |
784 | packet_stream_channels = opus_packet_get_nb_channels(data); | 627 | packet_stream_channels = opus_packet_get_nb_channels(data); |
785 | 628 | ||
786 | count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); | 629 | count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, |
630 | size, &offset, packet_offset); | ||
631 | if (count<0) | ||
632 | return count; | ||
787 | 633 | ||
788 | data += offset; | 634 | data += offset; |
789 | 635 | ||
@@ -822,11 +668,6 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, | |||
822 | return frame_size; | 668 | return frame_size; |
823 | } | 669 | } |
824 | } | 670 | } |
825 | tot_offset = 0; | ||
826 | if (count < 0) | ||
827 | return count; | ||
828 | |||
829 | tot_offset += offset; | ||
830 | 671 | ||
831 | if (count*packet_frame_size > frame_size) | 672 | if (count*packet_frame_size > frame_size) |
832 | return OPUS_BUFFER_TOO_SMALL; | 673 | return OPUS_BUFFER_TOO_SMALL; |
@@ -846,11 +687,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, | |||
846 | return ret; | 687 | return ret; |
847 | celt_assert(ret==packet_frame_size); | 688 | celt_assert(ret==packet_frame_size); |
848 | data += size[i]; | 689 | data += size[i]; |
849 | tot_offset += size[i]; | ||
850 | nb_samples += ret; | 690 | nb_samples += ret; |
851 | } | 691 | } |
852 | if (packet_offset != NULL) | ||
853 | *packet_offset = tot_offset; | ||
854 | st->last_packet_duration = nb_samples; | 692 | st->last_packet_duration = nb_samples; |
855 | if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) | 693 | if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) |
856 | OPUS_PRINT_INT(nb_samples); | 694 | OPUS_PRINT_INT(nb_samples); |
@@ -868,6 +706,8 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, | |||
868 | int opus_decode(OpusDecoder *st, const unsigned char *data, | 706 | int opus_decode(OpusDecoder *st, const unsigned char *data, |
869 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) | 707 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) |
870 | { | 708 | { |
709 | if(frame_size<=0) | ||
710 | return OPUS_BAD_ARG; | ||
871 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); | 711 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); |
872 | } | 712 | } |
873 | 713 | ||
@@ -879,6 +719,11 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data, | |||
879 | int ret, i; | 719 | int ret, i; |
880 | ALLOC_STACK; | 720 | ALLOC_STACK; |
881 | 721 | ||
722 | if(frame_size<=0) | ||
723 | { | ||
724 | RESTORE_STACK; | ||
725 | return OPUS_BAD_ARG; | ||
726 | } | ||
882 | ALLOC(out, frame_size*st->channels, opus_int16); | 727 | ALLOC(out, frame_size*st->channels, opus_int16); |
883 | 728 | ||
884 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); | 729 | ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); |
@@ -901,7 +746,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, | |||
901 | int ret, i; | 746 | int ret, i; |
902 | ALLOC_STACK; | 747 | ALLOC_STACK; |
903 | 748 | ||
904 | if(frame_size<0) | 749 | if(frame_size<=0) |
905 | { | 750 | { |
906 | RESTORE_STACK; | 751 | RESTORE_STACK; |
907 | return OPUS_BAD_ARG; | 752 | return OPUS_BAD_ARG; |
@@ -922,6 +767,8 @@ int opus_decode(OpusDecoder *st, const unsigned char *data, | |||
922 | int opus_decode_float(OpusDecoder *st, const unsigned char *data, | 767 | int opus_decode_float(OpusDecoder *st, const unsigned char *data, |
923 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) | 768 | opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) |
924 | { | 769 | { |
770 | if(frame_size<=0) | ||
771 | return OPUS_BAD_ARG; | ||
925 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); | 772 | return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); |
926 | } | 773 | } |
927 | 774 | ||