Preventing NaNs from crashing surround_analysis()
authorJean-Marc Valin <jmvalin@jmvalin.ca>
Wed, 7 Oct 2015 13:17:50 +0000 (09:17 -0400)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Wed, 7 Oct 2015 13:23:33 +0000 (09:23 -0400)
src/opus_encoder.c
src/opus_multistream_encoder.c

index d94163f..d11e972 100644 (file)
@@ -1465,7 +1465,10 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
        /* This should filter out both NaNs and ridiculous signals that could
           cause NaNs further down. */
        if (!(sum < 1e9f) || celt_isnan(sum))
+       {
           OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels);
+          st->hp_mem[0] = st->hp_mem[1] = st->hp_mem[2] = st->hp_mem[3] = 0;
+       }
     }
 #endif
 
index 7163d14..b55ab7a 100644 (file)
@@ -41,6 +41,7 @@
 #include "modes.h"
 #include "bands.h"
 #include "quant_bands.h"
+#include "pitch.h"
 
 typedef struct {
    int nb_streams;
@@ -259,6 +260,19 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
       OPUS_COPY(in, mem+c*overlap, overlap);
       (*copy_channel_in)(x, 1, pcm, channels, c, len);
       celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
+#ifndef FIXED_POINT
+      {
+         opus_val32 sum;
+         sum = celt_inner_prod(in, in, frame_size+overlap, 0);
+         /* This should filter out both NaNs and ridiculous signals that could
+            cause NaNs further down. */
+         if (!(sum < 1e9f) || celt_isnan(sum))
+         {
+            OPUS_CLEAR(in, frame_size+overlap);
+            preemph_mem[c] = 0;
+         }
+      }
+#endif
       clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1);
       if (upsample != 1)
       {