| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |