ref: 68545565568bdc3573c580499e3d964ede4da8d3
parent: f334c82ec3535bb39964424a2ed199d4e349598d
author: Jean-Marc Valin <[email protected]>
date: Thu Aug 11 20:30:47 EDT 2011
Fixes a mode transition bug found by fuzzing During SILK->CELT transitions, we were delaying the mode change by one frame, but only after having ensured that bandwidth and mode were consistent. We now do the delaying earlier.
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -281,6 +281,31 @@
st->mode = MODE_SILK_ONLY;
}
#endif
+ if (st->prev_mode > 0 &&
+ ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
+ (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
+ {
+ redundancy = 1;
+ celt_to_silk = (st->mode != MODE_CELT_ONLY);
+ if (!celt_to_silk)
+ {
+ /* Switch to SILK/hybrid if frame size is 10 ms or more*/
+ if (frame_size >= st->Fs/100)
+ {
+ st->mode = st->prev_mode;
+ to_celt = 1;
+ } else {
+ redundancy=0;
+ }
+ }
+ }
+ if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
+ {
+ silk_EncControlStruct dummy;
+ silk_InitEncoder( silk_enc, &dummy);
+ prefill=1;
+ }
+
/* Automatic (rate-dependent) bandwidth selection */
if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
{
@@ -345,30 +370,6 @@
bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
data += 1;
- if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
- {
- silk_EncControlStruct dummy;
- silk_InitEncoder( silk_enc, &dummy);
- prefill=1;
- }
- if (st->prev_mode > 0 &&
- ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
- (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
- {
- redundancy = 1;
- celt_to_silk = (st->mode != MODE_CELT_ONLY);
- if (!celt_to_silk)
- {
- /* Switch to SILK/hybrid if frame size is 10 ms or more*/
- if (frame_size >= st->Fs/100)
- {
- st->mode = st->prev_mode;
- to_celt = 1;
- } else {
- redundancy=0;
- }
- }
- }
ec_enc_init(&enc, data, max_data_bytes-1);