Commit e2a09db9 authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Implementing decoder-side support for redundant mode switching (bemasc's idea)

parent 60d59c87
......@@ -83,6 +83,8 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
int audiosize;
int mode;
int transition=0;
int start_band;
int redundancy;
/* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */
if (len<=2)
......@@ -130,7 +132,8 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
&& !(mode == MODE_HYBRID && st->prev_mode == MODE_SILK_ONLY))
{
transition = 1;
opus_decode(st, NULL, 0, pcm_transition, IMAX(480, audiosize), 0);
if (mode == MODE_CELT_ONLY && !st->prev_redundancy)
opus_decode(st, NULL, 0, pcm_transition, IMAX(480, audiosize), 0);
}
if (audiosize > frame_size)
{
......@@ -185,13 +188,21 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
pcm[i] = 0;
}
start_band = 0;
if (mode == MODE_HYBRID)
{
/* This should be adjusted based on the SILK bandwidth */
celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(17));
} else {
celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0));
/* Check if we have a redundant 0-8 kHz band */
redundancy = ec_dec_bit_logp(&dec, 12);
if (!redundancy)
start_band = 17;
}
celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(start_band));
if (redundancy)
transition = 0;
if (transition && mode != MODE_CELT_ONLY)
opus_decode(st, NULL, 0, pcm_transition, IMAX(480, audiosize), 0);
if (mode != MODE_SILK_ONLY)
{
......@@ -242,6 +253,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
#endif
st->prev_mode = mode;
st->prev_redundancy = redundancy;
return celt_ret<0 ? celt_ret : audiosize;
}
......
......@@ -41,6 +41,7 @@ struct OpusDecoder {
/* Sampling rate (at the API level) */
int Fs;
int prev_mode;
int prev_redundancy;
#ifdef OPUS_TEST_RANGE_CODER_STATE
int rangeFinal;
......
......@@ -95,6 +95,8 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
int silk_internal_bandwidth;
int bytes_target;
int prefill=0;
int start_band;
int redundancy = 0;
bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
......@@ -213,6 +215,17 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
} else {
celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
}
start_band = 0;
if (st->mode == MODE_HYBRID)
{
/* Check if we have a redundant 0-8 kHz band */
ec_enc_bit_logp(&enc, redundancy, 12);
if (!redundancy)
start_band = 17;
}
celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));
if (st->mode == MODE_HYBRID)
{
int len;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment