summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/opus_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/opus_decoder.c')
-rw-r--r--lib/rbcodec/codecs/libopus/opus_decoder.c85
1 files changed, 47 insertions, 38 deletions
diff --git a/lib/rbcodec/codecs/libopus/opus_decoder.c b/lib/rbcodec/codecs/libopus/opus_decoder.c
index 198d168898..5d35ed2675 100644
--- a/lib/rbcodec/codecs/libopus/opus_decoder.c
+++ b/lib/rbcodec/codecs/libopus/opus_decoder.c
@@ -77,12 +77,6 @@ struct OpusDecoder {
77 opus_uint32 rangeFinal; 77 opus_uint32 rangeFinal;
78}; 78};
79 79
80#ifdef FIXED_POINT
81static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
82 return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x;
83}
84#endif
85
86 80
87int opus_decoder_get_size(int channels) 81int opus_decoder_get_size(int channels)
88{ 82{
@@ -222,7 +216,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
222 VARDECL(opus_val16, pcm_transition_silk); 216 VARDECL(opus_val16, pcm_transition_silk);
223 int pcm_transition_celt_size; 217 int pcm_transition_celt_size;
224 VARDECL(opus_val16, pcm_transition_celt); 218 VARDECL(opus_val16, pcm_transition_celt);
225 opus_val16 *pcm_transition = NULL; /* Silence false positive "may be used uninitialized" warning */ 219 opus_val16 *pcm_transition=NULL;
226 int redundant_audio_size; 220 int redundant_audio_size;
227 VARDECL(opus_val16, redundant_audio); 221 VARDECL(opus_val16, redundant_audio);
228 222
@@ -237,6 +231,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
237 int F2_5, F5, F10, F20; 231 int F2_5, F5, F10, F20;
238 const opus_val16 *window; 232 const opus_val16 *window;
239 opus_uint32 redundant_rng = 0; 233 opus_uint32 redundant_rng = 0;
234 int celt_accum;
240 ALLOC_STACK; 235 ALLOC_STACK;
241 236
242 silk_dec = (char*)st+st->silk_dec_offset; 237 silk_dec = (char*)st+st->silk_dec_offset;
@@ -302,6 +297,14 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
302 } 297 }
303 } 298 }
304 299
300 /* In fixed-point, we can tell CELT to do the accumulation on top of the
301 SILK PCM buffer. This saves some stack space. */
302#ifdef FIXED_POINT
303 celt_accum = (mode != MODE_CELT_ONLY) && (frame_size >= F10);
304#else
305 celt_accum = 0;
306#endif
307
305 pcm_transition_silk_size = ALLOC_NONE; 308 pcm_transition_silk_size = ALLOC_NONE;
306 pcm_transition_celt_size = ALLOC_NONE; 309 pcm_transition_celt_size = ALLOC_NONE;
307 if (data!=NULL && st->prev_mode > 0 && ( 310 if (data!=NULL && st->prev_mode > 0 && (
@@ -332,14 +335,20 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
332 } 335 }
333 336
334 /* Don't allocate any memory when in CELT-only mode */ 337 /* Don't allocate any memory when in CELT-only mode */
335 pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE; 338 pcm_silk_size = (mode != MODE_CELT_ONLY && !celt_accum) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE;
336 ALLOC(pcm_silk, pcm_silk_size, opus_int16); 339 ALLOC(pcm_silk, pcm_silk_size, opus_int16);
337 340
338 /* SILK processing */ 341 /* SILK processing */
339 if (mode != MODE_CELT_ONLY) 342 if (mode != MODE_CELT_ONLY)
340 { 343 {
341 int lost_flag, decoded_samples; 344 int lost_flag, decoded_samples;
342 opus_int16 *pcm_ptr = pcm_silk; 345 opus_int16 *pcm_ptr;
346#ifdef FIXED_POINT
347 if (celt_accum)
348 pcm_ptr = pcm;
349 else
350#endif
351 pcm_ptr = pcm_silk;
343 352
344 if (st->prev_mode==MODE_CELT_ONLY) 353 if (st->prev_mode==MODE_CELT_ONLY)
345 silk_InitDecoder( silk_dec ); 354 silk_InitDecoder( silk_dec );
@@ -469,7 +478,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
469 { 478 {
470 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 479 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
471 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, 480 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
472 redundant_audio, F5, NULL); 481 redundant_audio, F5, NULL, 0);
473 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 482 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
474 } 483 }
475 484
@@ -484,25 +493,28 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
484 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 493 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
485 /* Decode CELT */ 494 /* Decode CELT */
486 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, 495 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
487 len, pcm, celt_frame_size, &dec); 496 len, pcm, celt_frame_size, &dec, celt_accum);
488 } else { 497 } else {
489 unsigned char silence[2] = {0xFF, 0xFF}; 498 unsigned char silence[2] = {0xFF, 0xFF};
490 for (i=0;i<frame_size*st->channels;i++) 499 if (!celt_accum)
491 pcm[i] = 0; 500 {
501 for (i=0;i<frame_size*st->channels;i++)
502 pcm[i] = 0;
503 }
492 /* For hybrid -> SILK transitions, we let the CELT MDCT 504 /* For hybrid -> SILK transitions, we let the CELT MDCT
493 do a fade-out by decoding a silence frame */ 505 do a fade-out by decoding a silence frame */
494 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) ) 506 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
495 { 507 {
496 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 508 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
497 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); 509 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
498 } 510 }
499 } 511 }
500 512
501 if (mode != MODE_CELT_ONLY) 513 if (mode != MODE_CELT_ONLY && !celt_accum)
502 { 514 {
503#ifdef FIXED_POINT 515#ifdef FIXED_POINT
504 for (i=0;i<frame_size*st->channels;i++) 516 for (i=0;i<frame_size*st->channels;i++)
505 pcm[i] = SAT16(pcm[i] + pcm_silk[i]); 517 pcm[i] = SAT16(ADD32(pcm[i], pcm_silk[i]));
506#else 518#else
507 for (i=0;i<frame_size*st->channels;i++) 519 for (i=0;i<frame_size*st->channels;i++)
508 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); 520 pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]);
@@ -521,7 +533,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
521 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 533 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
522 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 534 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
523 535
524 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); 536 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
525 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 537 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
526 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, 538 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
527 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); 539 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
@@ -717,6 +729,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
717{ 729{
718 VARDECL(opus_int16, out); 730 VARDECL(opus_int16, out);
719 int ret, i; 731 int ret, i;
732 int nb_samples;
720 ALLOC_STACK; 733 ALLOC_STACK;
721 734
722 if(frame_size<=0) 735 if(frame_size<=0)
@@ -724,6 +737,14 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
724 RESTORE_STACK; 737 RESTORE_STACK;
725 return OPUS_BAD_ARG; 738 return OPUS_BAD_ARG;
726 } 739 }
740 if (data != NULL && len > 0 && !decode_fec)
741 {
742 nb_samples = opus_decoder_get_nb_samples(st, data, len);
743 if (nb_samples>0)
744 frame_size = IMIN(frame_size, nb_samples);
745 else
746 return OPUS_INVALID_PACKET;
747 }
727 ALLOC(out, frame_size*st->channels, opus_int16); 748 ALLOC(out, frame_size*st->channels, opus_int16);
728 749
729 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); 750 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
@@ -744,6 +765,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
744{ 765{
745 VARDECL(float, out); 766 VARDECL(float, out);
746 int ret, i; 767 int ret, i;
768 int nb_samples;
747 ALLOC_STACK; 769 ALLOC_STACK;
748 770
749 if(frame_size<=0) 771 if(frame_size<=0)
@@ -752,6 +774,14 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
752 return OPUS_BAD_ARG; 774 return OPUS_BAD_ARG;
753 } 775 }
754 776
777 if (data != NULL && len > 0 && !decode_fec)
778 {
779 nb_samples = opus_decoder_get_nb_samples(st, data, len);
780 if (nb_samples>0)
781 frame_size = IMIN(frame_size, nb_samples);
782 else
783 return OPUS_INVALID_PACKET;
784 }
755 ALLOC(out, frame_size*st->channels, float); 785 ALLOC(out, frame_size*st->channels, float);
756 786
757 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); 787 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
@@ -911,27 +941,6 @@ int opus_packet_get_bandwidth(const unsigned char *data)
911 return bandwidth; 941 return bandwidth;
912} 942}
913 943
914int opus_packet_get_samples_per_frame(const unsigned char *data,
915 opus_int32 Fs)
916{
917 int audiosize;
918 if (data[0]&0x80)
919 {
920 audiosize = ((data[0]>>3)&0x3);
921 audiosize = (Fs<<audiosize)/400;
922 } else if ((data[0]&0x60) == 0x60)
923 {
924 audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
925 } else {
926 audiosize = ((data[0]>>3)&0x3);
927 if (audiosize == 3)
928 audiosize = Fs*60/1000;
929 else
930 audiosize = (Fs<<audiosize)/100;
931 }
932 return audiosize;
933}
934
935int opus_packet_get_nb_channels(const unsigned char *data) 944int opus_packet_get_nb_channels(const unsigned char *data)
936{ 945{
937 return (data[0]&0x4) ? 2 : 1; 946 return (data[0]&0x4) ? 2 : 1;