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

Side by Side Diff: src/opus_decoder.c

Issue 12388030: Update Opus to 1.0.2. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/opus
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/opus_compare.c ('k') | src/opus_demo.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 12 matching lines...) Expand all
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 and you probably want a decen t 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 detai ls."
34 #endif 34 #endif
35 35
36 #include <stdarg.h> 36 #include <stdarg.h>
37 #include "celt.h" 37 #include "celt.h"
38 #include "opus.h" 38 #include "opus.h"
39 #include "entdec.h" 39 #include "entdec.h"
40 #include "modes.h" 40 #include "modes.h"
41 #include "API.h" 41 #include "API.h"
42 #include "stack_alloc.h" 42 #include "stack_alloc.h"
43 #include "float_cast.h" 43 #include "float_cast.h"
(...skipping 13 matching lines...) Expand all
57 57
58 /* Everything beyond this point gets cleared on a reset */ 58 /* Everything beyond this point gets cleared on a reset */
59 #define OPUS_DECODER_RESET_START stream_channels 59 #define OPUS_DECODER_RESET_START stream_channels
60 int stream_channels; 60 int stream_channels;
61 61
62 int bandwidth; 62 int bandwidth;
63 int mode; 63 int mode;
64 int prev_mode; 64 int prev_mode;
65 int frame_size; 65 int frame_size;
66 int prev_redundancy; 66 int prev_redundancy;
67 int last_packet_duration;
67 68
68 opus_uint32 rangeFinal; 69 opus_uint32 rangeFinal;
69 }; 70 };
70 71
71 #ifdef FIXED_POINT 72 #ifdef FIXED_POINT
72 static inline opus_int16 SAT16(opus_int32 x) { 73 static inline opus_int16 SAT16(opus_int32 x) {
73 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; 74 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
74 } 75 }
75 #endif 76 #endif
76 77
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 /* If we haven't got any packet yet, all we can do is return zeros */ 251 /* If we haven't got any packet yet, all we can do is return zeros */
251 for (i=0;i<audiosize*st->channels;i++) 252 for (i=0;i<audiosize*st->channels;i++)
252 pcm[i] = 0; 253 pcm[i] = 0;
253 RESTORE_STACK; 254 RESTORE_STACK;
254 return audiosize; 255 return audiosize;
255 } else { 256 } else {
256 mode = st->prev_mode; 257 mode = st->prev_mode;
257 } 258 }
258 } 259 }
259 260
260 /* For CELT/hybrid PLC of more than 20 ms, do multiple calls */ 261 /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do
261 if (data==NULL && frame_size > F20 && mode != MODE_SILK_ONLY) 262 multiple calls */
262 { 263 if (data==NULL && mode != MODE_SILK_ONLY)
263 int nb_samples = 0; 264 frame_size = IMIN(frame_size, F20);
264 do {
265 int ret = opus_decode_frame(st, NULL, 0, pcm, F20, 0);
266 if (ret != F20)
267 {
268 RESTORE_STACK;
269 return OPUS_INTERNAL_ERROR;
270 }
271 pcm += F20*st->channels;
272 nb_samples += F20;
273 } while (nb_samples < frame_size);
274 RESTORE_STACK;
275 return frame_size;
276 }
277 ALLOC(pcm_transition, F5*st->channels, opus_val16); 265 ALLOC(pcm_transition, F5*st->channels, opus_val16);
278 266
279 if (data!=NULL && st->prev_mode > 0 && ( 267 if (data!=NULL && st->prev_mode > 0 && (
280 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r edundancy) 268 (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_r edundancy)
281 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) 269 || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) )
282 ) 270 )
283 { 271 {
284 transition = 1; 272 transition = 1;
285 if (mode == MODE_CELT_ONLY) 273 if (mode == MODE_CELT_ONLY)
286 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); 274 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 541
554 static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, 542 static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
555 int self_delimited, unsigned char *out_toc, 543 int self_delimited, unsigned char *out_toc,
556 const unsigned char *frames[48], short size[48], int *payload_offset) 544 const unsigned char *frames[48], short size[48], int *payload_offset)
557 { 545 {
558 int i, bytes; 546 int i, bytes;
559 int count; 547 int count;
560 int cbr; 548 int cbr;
561 unsigned char ch, toc; 549 unsigned char ch, toc;
562 int framesize; 550 int framesize;
563 int last_size; 551 opus_int32 last_size;
564 const unsigned char *data0 = data; 552 const unsigned char *data0 = data;
565 553
566 if (size==NULL) 554 if (size==NULL)
567 return OPUS_BAD_ARG; 555 return OPUS_BAD_ARG;
568 556
569 framesize = opus_packet_get_samples_per_frame(data, 48000); 557 framesize = opus_packet_get_samples_per_frame(data, 48000);
570 558
571 cbr = 0; 559 cbr = 0;
572 toc = *data++; 560 toc = *data++;
573 len--; 561 len--;
574 last_size = len; 562 last_size = len;
575 switch (toc&0x3) 563 switch (toc&0x3)
576 { 564 {
577 /* One frame */ 565 /* One frame */
578 case 0: 566 case 0:
579 count=1; 567 count=1;
580 break; 568 break;
581 /* Two CBR frames */ 569 /* Two CBR frames */
582 case 1: 570 case 1:
583 count=2; 571 count=2;
584 cbr = 1; 572 cbr = 1;
585 if (!self_delimited) 573 if (!self_delimited)
586 { 574 {
587 if (len&0x1) 575 if (len&0x1)
588 return OPUS_INVALID_PACKET; 576 return OPUS_INVALID_PACKET;
589 size[0] = last_size = len/2; 577 last_size = len/2;
578 /* If last_size doesn't fit in size[0], we'll catch it later */
579 size[0] = (short)last_size;
590 } 580 }
591 break; 581 break;
592 /* Two VBR frames */ 582 /* Two VBR frames */
593 case 2: 583 case 2:
594 count = 2; 584 count = 2;
595 bytes = parse_size(data, len, size); 585 bytes = parse_size(data, len, size);
596 len -= bytes; 586 len -= bytes;
597 if (size[0]<0 || size[0] > len) 587 if (size[0]<0 || size[0] > len)
598 return OPUS_INVALID_PACKET; 588 return OPUS_INVALID_PACKET;
599 data += bytes; 589 data += bytes;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 } 630 }
641 if (last_size<0) 631 if (last_size<0)
642 return OPUS_INVALID_PACKET; 632 return OPUS_INVALID_PACKET;
643 } else if (!self_delimited) 633 } else if (!self_delimited)
644 { 634 {
645 /* CBR case */ 635 /* CBR case */
646 last_size = len/count; 636 last_size = len/count;
647 if (last_size*count!=len) 637 if (last_size*count!=len)
648 return OPUS_INVALID_PACKET; 638 return OPUS_INVALID_PACKET;
649 for (i=0;i<count-1;i++) 639 for (i=0;i<count-1;i++)
650 size[i] = last_size; 640 size[i] = (short)last_size;
651 } 641 }
652 break; 642 break;
653 } 643 }
654 /* Self-delimited framing has an extra size for the last frame. */ 644 /* Self-delimited framing has an extra size for the last frame. */
655 if (self_delimited) 645 if (self_delimited)
656 { 646 {
657 bytes = parse_size(data, len, size+count-1); 647 bytes = parse_size(data, len, size+count-1);
658 len -= bytes; 648 len -= bytes;
659 if (size[count-1]<0 || size[count-1] > len) 649 if (size[count-1]<0 || size[count-1] > len)
660 return OPUS_INVALID_PACKET; 650 return OPUS_INVALID_PACKET;
661 data += bytes; 651 data += bytes;
662 /* For CBR packets, apply the size to all the frames. */ 652 /* For CBR packets, apply the size to all the frames. */
663 if (cbr) 653 if (cbr)
664 { 654 {
665 if (size[count-1]*count > len) 655 if (size[count-1]*count > len)
666 return OPUS_INVALID_PACKET; 656 return OPUS_INVALID_PACKET;
667 for (i=0;i<count-1;i++) 657 for (i=0;i<count-1;i++)
668 size[i] = size[count-1]; 658 size[i] = size[count-1];
669 } else if(size[count-1] > last_size) 659 } else if(size[count-1] > last_size)
670 return OPUS_INVALID_PACKET; 660 return OPUS_INVALID_PACKET;
671 } else 661 } else
672 { 662 {
673 /* Because it's not encoded explicitly, it's possible the size of the 663 /* Because it's not encoded explicitly, it's possible the size of the
674 last packet (or all the packets, for the CBR case) is larger than 664 last packet (or all the packets, for the CBR case) is larger than
675 1275. Reject them here.*/ 665 1275. Reject them here.*/
676 if (last_size > 1275) 666 if (last_size > 1275)
677 return OPUS_INVALID_PACKET; 667 return OPUS_INVALID_PACKET;
678 size[count-1] = last_size; 668 size[count-1] = (short)last_size;
679 } 669 }
680 670
681 if (frames) 671 if (frames)
682 { 672 {
683 for (i=0;i<count;i++) 673 for (i=0;i<count;i++)
684 { 674 {
685 frames[i] = data; 675 frames[i] = data;
686 data += size[i]; 676 data += size[i];
687 } 677 }
688 } 678 }
(...skipping 16 matching lines...) Expand all
705 } 695 }
706 696
707 int opus_decode_native(OpusDecoder *st, const unsigned char *data, 697 int opus_decode_native(OpusDecoder *st, const unsigned char *data,
708 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, 698 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec,
709 int self_delimited, int *packet_offset) 699 int self_delimited, int *packet_offset)
710 { 700 {
711 int i, nb_samples; 701 int i, nb_samples;
712 int count, offset; 702 int count, offset;
713 unsigned char toc; 703 unsigned char toc;
714 int tot_offset; 704 int tot_offset;
705 int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
715 /* 48 x 2.5 ms = 120 ms */ 706 /* 48 x 2.5 ms = 120 ms */
716 short size[48]; 707 short size[48];
717 if (decode_fec<0 || decode_fec>1) 708 if (decode_fec<0 || decode_fec>1)
718 return OPUS_BAD_ARG; 709 return OPUS_BAD_ARG;
710 /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
711 if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0)
712 return OPUS_BAD_ARG;
719 if (len==0 || data==NULL) 713 if (len==0 || data==NULL)
720 return opus_decode_frame(st, NULL, 0, pcm, frame_size, 0); 714 {
721 else if (len<0) 715 int pcm_count=0;
716 do {
717 int ret;
718 ret = opus_decode_frame(st, NULL, 0, pcm, frame_size-pcm_count, 0);
719 if (ret<0)
720 return ret;
721 pcm += st->channels*ret;
722 pcm_count += ret;
723 } while (pcm_count < frame_size);
724 st->last_packet_duration = pcm_count;
725 return pcm_count;
726 } else if (len<0)
722 return OPUS_BAD_ARG; 727 return OPUS_BAD_ARG;
723 728
724 tot_offset = 0; 729 packet_mode = opus_packet_get_mode(data);
725 st->mode = opus_packet_get_mode(data); 730 packet_bandwidth = opus_packet_get_bandwidth(data);
726 st->bandwidth = opus_packet_get_bandwidth(data); 731 packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs);
727 st->frame_size = opus_packet_get_samples_per_frame(data, st->Fs); 732 packet_stream_channels = opus_packet_get_nb_channels(data);
728 st->stream_channels = opus_packet_get_nb_channels(data);
729 733
730 count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, & offset); 734 count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, & offset);
735
736 data += offset;
737
738 if (decode_fec)
739 {
740 int duration_copy;
741 int ret;
742 /* If no FEC can be present, run the PLC (recursive call) */
743 if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || st ->mode == MODE_CELT_ONLY)
744 return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL);
745 /* Otherwise, run the PLC on everything except the size for which we might have FEC */
746 duration_copy = st->last_packet_duration;
747 ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0 , 0, NULL);
748 if (ret<0)
749 {
750 st->last_packet_duration = duration_copy;
751 return ret;
752 }
753 /* Complete with FEC */
754 st->mode = packet_mode;
755 st->bandwidth = packet_bandwidth;
756 st->frame_size = packet_frame_size;
757 st->stream_channels = packet_stream_channels;
758 ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-pa cket_frame_size),
759 packet_frame_size, 1);
760 if (ret<0)
761 return ret;
762 st->last_packet_duration = frame_size;
763 return frame_size;
764 }
765 tot_offset = 0;
731 if (count < 0) 766 if (count < 0)
732 return count; 767 return count;
733 768
734 data += offset;
735 tot_offset += offset; 769 tot_offset += offset;
736 770
737 if (count*st->frame_size > frame_size) 771 if (count*packet_frame_size > frame_size)
738 return OPUS_BUFFER_TOO_SMALL; 772 return OPUS_BUFFER_TOO_SMALL;
773
774 /* Update the state as the last step to avoid updating it on an invalid packe t */
775 st->mode = packet_mode;
776 st->bandwidth = packet_bandwidth;
777 st->frame_size = packet_frame_size;
778 st->stream_channels = packet_stream_channels;
779
739 nb_samples=0; 780 nb_samples=0;
740 for (i=0;i<count;i++) 781 for (i=0;i<count;i++)
741 { 782 {
742 int ret; 783 int ret;
743 ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, dec ode_fec); 784 ret = opus_decode_frame(st, data, size[i], pcm, frame_size-nb_samples, dec ode_fec);
744 if (ret<0) 785 if (ret<0)
745 return ret; 786 return ret;
746 data += size[i]; 787 data += size[i];
747 tot_offset += size[i]; 788 tot_offset += size[i];
748 pcm += ret*st->channels; 789 pcm += ret*st->channels;
749 nb_samples += ret; 790 nb_samples += ret;
750 } 791 }
751 if (packet_offset != NULL) 792 if (packet_offset != NULL)
752 *packet_offset = tot_offset; 793 *packet_offset = tot_offset;
794 st->last_packet_duration = nb_samples;
753 return nb_samples; 795 return nb_samples;
754 } 796 }
755 797
756 #ifdef FIXED_POINT 798 #ifdef FIXED_POINT
757 799
758 int opus_decode(OpusDecoder *st, const unsigned char *data, 800 int opus_decode(OpusDecoder *st, const unsigned char *data,
759 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) 801 opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec)
760 { 802 {
761 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL ); 803 return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL );
762 } 804 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 { 938 {
897 opus_int32 value = va_arg(ap, opus_int32); 939 opus_int32 value = va_arg(ap, opus_int32);
898 if (value<-32768 || value>32767) 940 if (value<-32768 || value>32767)
899 { 941 {
900 ret = OPUS_BAD_ARG; 942 ret = OPUS_BAD_ARG;
901 break; 943 break;
902 } 944 }
903 st->decode_gain = value; 945 st->decode_gain = value;
904 } 946 }
905 break; 947 break;
948 case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
949 {
950 opus_uint32 *value = va_arg(ap, opus_uint32*);
951 *value = st->last_packet_duration;
952 }
953 break;
906 default: 954 default:
907 /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ 955 /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
908 ret = OPUS_UNIMPLEMENTED; 956 ret = OPUS_UNIMPLEMENTED;
909 break; 957 break;
910 } 958 }
911 959
912 va_end(ap); 960 va_end(ap);
913 return ret; 961 return ret;
914 } 962 }
915 963
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 if (count==0) 1020 if (count==0)
973 return 1; 1021 return 1;
974 else if (count!=3) 1022 else if (count!=3)
975 return 2; 1023 return 2;
976 else if (len<2) 1024 else if (len<2)
977 return OPUS_INVALID_PACKET; 1025 return OPUS_INVALID_PACKET;
978 else 1026 else
979 return packet[1]&0x3F; 1027 return packet[1]&0x3F;
980 } 1028 }
981 1029
982 int opus_decoder_get_nb_samples(const OpusDecoder *dec, 1030 int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len,
983 const unsigned char packet[], opus_int32 len) 1031 opus_int32 Fs)
984 { 1032 {
985 int samples; 1033 int samples;
986 int count = opus_packet_get_nb_frames(packet, len); 1034 int count = opus_packet_get_nb_frames(packet, len);
987 1035
988 if (count<0) 1036 if (count<0)
989 return count; 1037 return count;
990 1038
991 samples = count*opus_packet_get_samples_per_frame(packet, dec->Fs); 1039 samples = count*opus_packet_get_samples_per_frame(packet, Fs);
992 /* Can't have more than 120 ms */ 1040 /* Can't have more than 120 ms */
993 if (samples*25 > dec->Fs*3) 1041 if (samples*25 > Fs*3)
994 return OPUS_INVALID_PACKET; 1042 return OPUS_INVALID_PACKET;
995 else 1043 else
996 return samples; 1044 return samples;
997 } 1045 }
1046
1047 int opus_decoder_get_nb_samples(const OpusDecoder *dec,
1048 const unsigned char packet[], opus_int32 len)
1049 {
1050 return opus_packet_get_nb_samples(packet, len, dec->Fs);
1051 }
OLDNEW
« no previous file with comments | « src/opus_compare.c ('k') | src/opus_demo.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698