diff --git a/configure.ac b/configure.ac index 9b10e8a3a90922a8617e0306be7478bbd1c8fa92..609b4f13287812d83007696094d20cafdd51f7d6 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,13 @@ AC_ARG_ENABLE(assertions, [ --enable-assertions enable additional software AC_DEFINE([ENABLE_ASSERTIONS], , [Assertions]) fi]) +ac_enable_fuzzing="no" +AC_ARG_ENABLE(fuzzing, [ --enable-fuzzing causes the encoder to make random decisions], +[if test "$enableval" = yes; then + ac_enable_fuzzing="yes" + AC_DEFINE([FUZZING], , [Fuzzing]) +fi]) + if test "$OPUS_BUILD" != "true" ; then saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -fvisibility=hidden" @@ -219,6 +226,7 @@ AC_MSG_RESULT([ Fixed point debugging: ......... ${ac_enable_fixed_debug} Custom modes: .................. ${ac_enable_custom_modes} Assertion checking: ............ ${ac_enable_assertions} + Fuzzing: .. .......... ${ac_enable_fuzzing} ------------------------------------------------------------------------ ]) diff --git a/libcelt/bands.c b/libcelt/bands.c index a522b5040aa7e69c95747e3222c3af5e6f091bd5..68193a6d81a50faac466884048dd9f3463ec68d7 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -477,6 +477,10 @@ int spreading_decision(const CELTMode *m, celt_norm *X, int *average, } else { decision = SPREAD_NONE; } +#ifdef FUZZING + decision = rand()&0x3; + *tapset_decision=rand()%3; +#endif return decision; } diff --git a/libcelt/celt.c b/libcelt/celt.c index 77301a11f5941ffae78659b3245a9c54ab7ba7cb..bbd8ca10d210dfa8a0fa024cd66ab4d855082c23 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -387,6 +387,9 @@ static int transient_analysis(const opus_val32 * restrict in, int len, int C, is_transient=1; } RESTORE_STACK; +#ifdef FUZZING + is_transient = rand()&0x1; +#endif return is_transient; } @@ -709,6 +712,12 @@ static int tf_analysis(const CELTMode *m, int len, int C, int isTransient, tf_res[i] = path0[i+1]; } RESTORE_STACK; +#ifdef FUZZING + tf_select = rand()&0x1; + tf_res[0] = rand()&0x1; + for (i=1;i<len;i++) + tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0); +#endif return tf_select; } @@ -857,6 +866,9 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, trim_index = 0; if (trim_index>10) trim_index = 10; +#ifdef FUZZING + trim_index = rand()%11; +#endif return trim_index; } @@ -1102,6 +1114,10 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i CELT_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); } while (++c<CC); +#ifdef FUZZING + if ((rand()&0x3F)==0) + silence = 1; +#endif if (tell==1) ec_enc_bit_logp(enc, silence, 15); else @@ -1332,10 +1348,19 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i if (C==2) d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]- bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]); +#ifdef FUZZING + if((rand()&0xF)==0) + { + offsets[i] += 1; + if((rand()&0x3)==0) + offsets[i] += 1+(rand()&0x3); + } +#else if (d2 > SHL16(t1,DB_SHIFT)) offsets[i] += 1; if (d2 > SHL16(t2,DB_SHIFT)) offsets[i] += 1; +#endif } } dynalloc_logp = 6; @@ -1527,6 +1552,9 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i if (anti_collapse_rsv > 0) { anti_collapse_on = st->consec_transient<2; +#ifdef FUZZING + anti_collapse_on = rand()&0x1; +#endif ec_enc_bits(enc, anti_collapse_on, 1); } quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); diff --git a/libcelt/cwrs.c b/libcelt/cwrs.c index dfc943e4b8f45c7d6f3b330ee5076b0df5b82fe2..0c090f85ecbc0df5da337da5f067d6b6e3d77bd9 100644 --- a/libcelt/cwrs.c +++ b/libcelt/cwrs.c @@ -38,6 +38,8 @@ #include "mathops.h" #include "arch.h" +#ifdef CUSTOM_MODES + /*Guaranteed to return a conservatively large estimate of the binary logarithm with frac bits of fractional precision. Tested for all possible 32-bit inputs with frac=4, where the maximum @@ -68,6 +70,7 @@ int log2_frac(opus_uint32 val, int frac) /*Exact powers of two require no rounding.*/ else return l-1<<frac; } +#endif #ifndef SMALL_FOOTPRINT diff --git a/libcelt/cwrs.h b/libcelt/cwrs.h index 515a4a3c0a4c2954c8dcffd52ab14a18e27628ca..7712394361da5b27adb2d78c1f0dbe37f70762a8 100644 --- a/libcelt/cwrs.h +++ b/libcelt/cwrs.h @@ -35,7 +35,9 @@ #include "entenc.h" #include "entdec.h" +#ifdef CUSTOM_MODES int log2_frac(opus_uint32 val, int frac); +#endif void get_required_bits(opus_int16 *bits, int N, int K, int frac); diff --git a/libcelt/rate.c b/libcelt/rate.c index ecbd9ceb5defa873da30ae610c8a8308bcdb82d7..e196d6a75292116ae472f8928c457cf1542c9014 100644 --- a/libcelt/rate.c +++ b/libcelt/rate.c @@ -351,7 +351,11 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip here must be explicitly signaled.*/ /*Choose a threshold with some hysteresis to keep bands from fluctuating in and out.*/ +#ifdef FUZZING + if ((rand()&0x1) == 0) +#else if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4) +#endif { ec_enc_bit_logp(ec, 1, 1); break; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index b348d5ebb7d7ad503be85abedc2d6b53a51c779e..908022d258102d5b51a01bc476e9dc0321ae10d3 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -217,6 +217,12 @@ int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, } else { st->stream_channels = st->channels; } + +#ifdef FUZZING + if (st->channels == 2 && (rand()&0x1F)==0) + st->stream_channels = 3-st->stream_channels; +#endif + /* Equivalent bit-rate for mono */ mono_rate = st->bitrate_bps; if (st->stream_channels==2) @@ -225,6 +231,20 @@ int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, of 60 bits/frame */ mono_rate -= 60*(st->Fs/frame_size - 50); +#ifdef FUZZING + if ((rand()&0xF)==0) + { + if ((rand()&0x1)==0) + st->mode = MODE_CELT_ONLY; + else + st->mode = MODE_SILK_ONLY; + } else { + if (st->prev_mode==MODE_CELT_ONLY) + st->mode = MODE_CELT_ONLY; + else + st->mode = MODE_SILK_ONLY; + } +#else /* Mode selection depending on application and signal type */ if (st->user_mode==OPUS_APPLICATION_VOIP) { @@ -260,6 +280,7 @@ int opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, else st->mode = MODE_SILK_ONLY; } +#endif /* Automatic (rate-dependent) bandwidth selection */ if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) {