diff --git a/silk/control_audio_bandwidth.c b/silk/control_audio_bandwidth.c index a9af91345c6c1d06a0660332280b80c41c1a44d0..b645dd57f45202927acd408829c92f486eda0e95 100644 --- a/silk/control_audio_bandwidth.c +++ b/silk/control_audio_bandwidth.c @@ -80,6 +80,8 @@ opus_int silk_control_audio_bandwidth( } else { if( psEncC->sLP.transition_frame_no <= 0 ) { encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: down (at double speed) */ psEncC->sLP.mode = -2; @@ -106,6 +108,8 @@ opus_int silk_control_audio_bandwidth( } else { if( psEncC->sLP.mode == 0 ) { encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); } else { /* Direction: up */ psEncC->sLP.mode = 1; diff --git a/src/opus_encoder.c b/src/opus_encoder.c index ea6bfa399be8b7f39da019d34c8f28d37087f862..aae31256ca579a7642b474adc97516d37080b85c 100644 --- a/src/opus_encoder.c +++ b/src/opus_encoder.c @@ -458,20 +458,20 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s int prefill=0; int start_band = 0; int redundancy = 0; - int redundancy_bytes = 0; + int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ int celt_to_silk = 0; VARDECL(opus_val16, pcm_buf); int nb_compr_bytes; int to_celt = 0; opus_uint32 redundant_rng = 0; int cutoff_Hz, hp_freq_smth1; - int voice_est; + int voice_est; /* Probability of voice in Q7 */ opus_int32 equiv_rate; int delay_compensation; int frame_rate; - opus_int32 max_rate; + opus_int32 max_rate; /* Max bitrate we're allowed to use */ int curr_bandwidth; - opus_int32 max_data_bytes; + opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ VARDECL(opus_val16, tmp_prefill); ALLOC_STACK; @@ -652,6 +652,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s } } } + /* For the first frame at a new SILK bandwidth */ if (st->silk_bw_switch) { redundancy = 1; @@ -659,6 +660,15 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s st->silk_bw_switch = 0; } + if (redundancy) + { + /* Fair share of the max size allowed */ + redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200)); + /* For VBR, target the actual bitrate (subject to the limit above) */ + if (st->use_vbr) + redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600); + } + if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) { silk_EncControlStruct dummy; @@ -823,7 +833,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s st->mode = MODE_SILK_ONLY; /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ - bytes_target = IMIN(max_data_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; + bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; data += 1; @@ -929,7 +939,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s st->silk_mode.useCBR = !st->use_vbr; /* Call SILK encoder for the low band */ - nBytes = IMIN(1275, max_data_bytes-1); + nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes); st->silk_mode.maxBits = nBytes*8; /* Only allow up to 90% of the bits for hybrid mode*/ @@ -941,8 +951,6 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s /* Reduce the initial target to make it easier to reach the CBR rate */ st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000); } - if (redundancy) - st->silk_mode.maxBits -= st->silk_mode.maxBits/(1 + frame_size/(st->Fs/200)); if (prefill) { @@ -990,6 +998,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s } st->silk_mode.opusCanSwitch = st->silk_mode.switchReady; + /* FIXME: How do we allocate the redundancy for CBR? */ if (st->silk_mode.opusCanSwitch) { redundancy = 1; @@ -1047,7 +1056,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps)); - nb_compr_bytes = max_data_bytes-1; + nb_compr_bytes = max_data_bytes-1-redundancy_bytes; } else { nb_compr_bytes = bytes_target; } @@ -1119,8 +1128,10 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s } if (!redundancy) + { st->silk_bw_switch = 0; - + redundancy_bytes = 0; + } if (st->mode != MODE_CELT_ONLY)start_band=17; if (st->mode == MODE_SILK_ONLY)