diff --git a/src/opus_decoder.c b/src/opus_decoder.c index 0be87dc0a..6520e748e 100644 --- a/src/opus_decoder.c +++ b/src/opus_decoder.c @@ -455,10 +455,6 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, { transition = 0; pcm_transition_silk_size=ALLOC_NONE; - /* don't use stale CELT decoder to decode second redundancy frame if - the first redundancy frame for a transition from SILK was lost */ - if (celt_to_silk && st->prev_mode == MODE_SILK_ONLY && !st->prev_redundancy) - redundancy = 0; } ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); @@ -504,6 +500,11 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, /* 5 ms redundant frame for CELT->SILK*/ if (redundancy && celt_to_silk) { + /* If the previous frame did not use CELT (the first redundancy frame in + a transition from SILK may have been lost) then the CELT decoder is + stale at this point and the redundancy audio is not useful, however + the final range is still needed (for testing), so the redundancy is + always decoded but the decoded audio may not be used */ MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0))); celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); @@ -566,7 +567,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data, smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); } - if (redundancy && celt_to_silk) + /* 5ms redundant frame for CELT->SILK; ignore if the previous frame did not + use CELT (the first redundancy frame in a transition from SILK may have + been lost) */ + if (redundancy && celt_to_silk && (st->prev_mode != MODE_SILK_ONLY || st->prev_redundancy)) { for (c=0;cchannels;c++) {