diff --git a/celt/arch.h b/celt/arch.h index 6693408f4836b201638ce5812362d97f2f6f5245..25cc0b7792475231ebb0f996c28132eef60656f6 100644 --- a/celt/arch.h +++ b/celt/arch.h @@ -140,7 +140,7 @@ typedef float celt_ener; #ifdef FLOAT_APPROX /* This code should reliably detect NaN/inf even when -ffast-math is used. Assumes IEEE 754 format. */ -static inline int celt_isnan(float x) +static OPUS_INLINE int celt_isnan(float x) { union {float f; opus_uint32 i;} in; in.f = x; diff --git a/src/analysis.c b/src/analysis.c index 778a62aabfc29470c5c6b4f51b6ef97852ca3d8e..2ee853376a3e13ddcb1ffaed64f549bf858477bb 100644 --- a/src/analysis.c +++ b/src/analysis.c @@ -189,7 +189,7 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int info_out->music_prob = psum; } -void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix) +static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix) { int i, b; const kiss_fft_state *kfft; @@ -263,6 +263,15 @@ void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, con downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C); tonal->mem_fill = 240 + remaining; opus_fft(kfft, in, out); +#ifndef FIXED_POINT + /* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */ + if (celt_isnan(out[0].r)) + { + info->valid = 0; + RESTORE_STACK; + return; + } +#endif for (i=1;i<N2;i++) { @@ -334,6 +343,16 @@ void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, con tE += binE*tonality[i]; nE += binE*2.f*(.5f-noisiness[i]); } +#ifndef FIXED_POINT + /* Check for extreme band energies that could cause NaNs later. */ + if (!(E<1e9f) || celt_isnan(E)) + { + info->valid = 0; + RESTORE_STACK; + return; + } +#endif + tonal->E[tonal->E_count][b] = E; frame_noisiness += nE/(1e-15f+E); @@ -611,8 +630,6 @@ void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, con /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/ info->noisiness = frame_noisiness; info->valid = 1; - if (info_out!=NULL) - OPUS_COPY(info_out, info, 1); RESTORE_STACK; } @@ -631,7 +648,7 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co pcm_len = analysis_frame_size - analysis->analysis_offset; offset = analysis->analysis_offset; do { - tonality_analysis(analysis, NULL, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix); + tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix); offset += 480; pcm_len -= 480; } while (pcm_len>0); diff --git a/src/analysis.h b/src/analysis.h index be0388faa390cac1a258519baae900b5821c1899..85a73d75522f92bdb7c3a6c817345fd36615e87f 100644 --- a/src/analysis.h +++ b/src/analysis.h @@ -78,9 +78,6 @@ typedef struct { AnalysisInfo info[DETECT_SIZE]; } TonalityAnalysisState; -void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info, - const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix); - void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len); void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, diff --git a/src/opus_encoder.c b/src/opus_encoder.c index 411e3d24f9c6b62cb1654b25e238dbfd0cdba6d1..2162121a5595eb7eeff674b207da9001d8db4db9 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -1452,7 +1452,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_ sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels); /* This should filter out both NaNs and ridiculous signals that could cause NaNs further down. */ - if (!(sum < 1e9) || celt_isnan(sum)) + if (!(sum < 1e9f) || celt_isnan(sum)) OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels); } #endif