use crate::silk::FrameSignalType;
use crate::silk::SilkNlsfCb;
use crate::silk::StereoEncState;
use crate::silk::decode_indices::SideInfoIndices;
use crate::silk::lin2log::lin2log;
use crate::silk::lp_variable_cutoff::LpState;
use crate::silk::resampler::Resampler;
use crate::silk::tables_nlsf_cb_wb::SILK_NLSF_CB_WB;
use crate::silk::tables_other::SILK_UNIFORM8_ICDF;
use crate::silk::tables_pitch_lag::PITCH_CONTOUR_ICDF;
use crate::silk::tuning_parameters::VARIABLE_HP_MIN_CUTOFF_HZ;
use crate::silk::{MAX_FRAMES_PER_PACKET, MAX_LPC_ORDER, MAX_NB_SUBFR, MAX_SHAPE_LPC_ORDER};
use core::array::from_fn;
pub const VAD_N_BANDS: usize = 4;
pub const ENCODER_NUM_CHANNELS: usize = 2;
pub(crate) const MAX_FS_KHZ: usize = 16;
pub(crate) const SUB_FRAME_LENGTH_MS: usize = 5;
pub(crate) const MAX_SUB_FRAME_LENGTH: usize = SUB_FRAME_LENGTH_MS * MAX_FS_KHZ;
pub(crate) const MAX_FRAME_LENGTH_MS: usize = SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR;
const DEFAULT_INTERNAL_FS_KHZ: i32 = 16;
pub(crate) const DEFAULT_FRAME_LENGTH: usize =
MAX_FRAME_LENGTH_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
pub(crate) const LA_PITCH_MS: usize = 2;
pub(crate) const LA_SHAPE_MS: usize = 5;
pub(crate) const LA_SHAPE_MAX: usize = LA_SHAPE_MS * MAX_FS_KHZ;
pub(crate) const FIND_PITCH_LPC_WIN_MS: usize = 20 + (LA_PITCH_MS << 1);
pub(crate) const FIND_PITCH_LPC_WIN_MS_2_SF: usize = 10 + (LA_PITCH_MS << 1);
pub(crate) const LTP_MEM_LENGTH_MS: usize = 20;
pub(crate) const MAX_FRAME_LENGTH: usize = MAX_FRAME_LENGTH_MS * MAX_FS_KHZ;
pub(crate) const INPUT_BUFFER_LENGTH: usize = MAX_FRAME_LENGTH + 2;
pub(crate) const X_BUFFER_LENGTH: usize = 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX;
pub(crate) const MAX_DEL_DEC_STATES: i32 = 4;
pub(crate) const MAX_FIND_PITCH_LPC_ORDER: i32 = 16;
pub(crate) const SHAPE_LPC_WIN_MAX: i32 = 15 * MAX_FS_KHZ as i32;
pub(crate) const NSQ_LPC_BUF_LENGTH: usize = MAX_LPC_ORDER;
pub(crate) const MAX_LTP_MEM_LENGTH: usize = 4 * MAX_SUB_FRAME_LENGTH;
pub(crate) const VAD_NOISE_LEVELS_BIAS: i32 = 50;
const INITIAL_NRG_RATIO_Q8: i32 = 100 * 256;
const INITIAL_VAD_COUNTER: i32 = 15;
#[derive(Clone, Debug, PartialEq)]
pub struct VadState {
pub ana_state: [i32; 2],
pub ana_state1: [i32; 2],
pub ana_state2: [i32; 2],
pub xnrg_subfr: [i32; VAD_N_BANDS],
pub nrg_ratio_smth_q8: [i32; VAD_N_BANDS],
pub hp_state: i16,
pub nl: [i32; VAD_N_BANDS],
pub inv_nl: [i32; VAD_N_BANDS],
pub noise_level_bias: [i32; VAD_N_BANDS],
pub counter: i32,
}
impl Default for VadState {
fn default() -> Self {
let mut state = Self {
ana_state: [0; 2],
ana_state1: [0; 2],
ana_state2: [0; 2],
xnrg_subfr: [0; VAD_N_BANDS],
nrg_ratio_smth_q8: [INITIAL_NRG_RATIO_Q8; VAD_N_BANDS],
hp_state: 0,
nl: [0; VAD_N_BANDS],
inv_nl: [0; VAD_N_BANDS],
noise_level_bias: [0; VAD_N_BANDS],
counter: INITIAL_VAD_COUNTER,
};
state.reset();
state
}
}
impl VadState {
pub fn reset(&mut self) {
for (band, bias) in self.noise_level_bias.iter_mut().enumerate() {
*bias = (VAD_NOISE_LEVELS_BIAS / (band as i32 + 1)).max(1);
}
for (nl, bias) in self.nl.iter_mut().zip(self.noise_level_bias.iter()) {
*nl = 100 * *bias;
}
for (inv, nl) in self.inv_nl.iter_mut().zip(self.nl.iter()) {
*inv = if *nl != 0 { i32::MAX / *nl } else { 0 };
}
self.nrg_ratio_smth_q8 = [INITIAL_NRG_RATIO_Q8; VAD_N_BANDS];
self.xnrg_subfr = [0; VAD_N_BANDS];
self.hp_state = 0;
self.counter = INITIAL_VAD_COUNTER;
}
}
#[derive(Clone, Debug, PartialEq, Default)]
pub struct EncoderShapeState {
pub last_gain_index: i32,
pub harm_boost_smth_q16: i32,
pub harm_shape_gain_smth_q16: i32,
pub tilt_smth_q16: i32,
}
#[derive(Clone, Debug, PartialEq)]
pub struct NoiseShapingQuantizerState {
pub xq: [i16; 2 * MAX_FRAME_LENGTH],
pub s_ltp_shp_q14: [i32; 2 * MAX_FRAME_LENGTH],
pub s_lpc_q14: [i32; MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH],
pub s_ar2_q14: [i32; MAX_SHAPE_LPC_ORDER],
pub s_lf_ar_shp_q14: i32,
pub s_diff_shp_q14: i32,
pub lag_prev: i32,
pub s_ltp_buf_idx: usize,
pub s_ltp_shp_buf_idx: usize,
pub rand_seed: i32,
pub prev_gain_q16: i32,
pub rewhite_flag: bool,
}
impl Default for NoiseShapingQuantizerState {
fn default() -> Self {
Self {
xq: [0; 2 * MAX_FRAME_LENGTH],
s_ltp_shp_q14: [0; 2 * MAX_FRAME_LENGTH],
s_lpc_q14: [0; MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH],
s_ar2_q14: [0; MAX_SHAPE_LPC_ORDER],
s_lf_ar_shp_q14: 0,
s_diff_shp_q14: 0,
lag_prev: 0,
s_ltp_buf_idx: 0,
s_ltp_shp_buf_idx: 0,
rand_seed: 0,
prev_gain_q16: 1 << 16,
rewhite_flag: false,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct EncoderStateCommon {
pub use_dtx: bool,
pub use_cbr: bool,
pub use_in_band_fec: bool,
pub prev_signal_type: FrameSignalType,
pub fs_khz: i32,
pub nb_subfr: usize,
pub frame_length: usize,
pub api_sample_rate_hz: i32,
pub prev_api_sample_rate_hz: i32,
pub max_internal_sample_rate_hz: i32,
pub min_internal_sample_rate_hz: i32,
pub desired_internal_sample_rate_hz: i32,
pub allow_bandwidth_switch: bool,
pub n_channels_api: i32,
pub n_channels_internal: i32,
pub channel_nb: i32,
pub prev_lag: i32,
pub subfr_length: usize,
pub ltp_mem_length: usize,
pub la_pitch: i32,
pub la_shape: i32,
pub shape_win_length: i32,
pub max_pitch_lag: i32,
pub pitch_lpc_win_length: usize,
pub predict_lpc_order: usize,
pub ps_nlsf_cb: &'static SilkNlsfCb,
pub pitch_contour_icdf: &'static [u8],
pub pitch_lag_low_bits_icdf: &'static [u8],
pub prev_nlsf_q15: [i16; MAX_LPC_ORDER],
pub target_rate_bps: i32,
pub snr_db_q7: i32,
pub sum_log_gain_q7: i32,
pub nsq_state: NoiseShapingQuantizerState,
pub frame_counter: i32,
pub input_buf: [i16; INPUT_BUFFER_LENGTH],
pub input_quality_bands_q15: [i32; VAD_N_BANDS],
pub input_tilt_q15: i32,
pub speech_activity_q8: i32,
pub no_speech_counter: i32,
pub variable_hp_smth1_q15: i32,
pub variable_hp_smth2_q15: i32,
pub vad_flags: [bool; MAX_FRAMES_PER_PACKET],
pub lbrr_flag: bool,
pub lbrr_flags: [bool; MAX_FRAMES_PER_PACKET],
pub lbrr_prev_last_gain_index: i8,
pub indices_lbrr: [SideInfoIndices; MAX_FRAMES_PER_PACKET],
pub pulses: [i8; MAX_FRAME_LENGTH],
pub pulses_lbrr: [[i8; MAX_FRAME_LENGTH]; MAX_FRAMES_PER_PACKET],
pub packet_size_ms: i32,
pub packet_loss_perc: i32,
pub n_frames_per_packet: usize,
pub n_frames_encoded: usize,
pub indices: SideInfoIndices,
pub input_buf_ix: usize,
pub first_frame_after_reset: bool,
pub controlled_since_last_payload: bool,
pub prefill_flag: bool,
pub pitch_estimation_complexity: i32,
pub pitch_estimation_threshold_q16: i32,
pub pitch_estimation_lpc_order: i32,
pub shaping_lpc_order: i32,
pub n_states_delayed_decision: i32,
pub use_interpolated_nlsfs: bool,
pub nlsf_msvq_survivors: i32,
pub warping_q16: i32,
pub complexity: i32,
pub ec_prev_signal_type: FrameSignalType,
pub ec_prev_lag_index: i16,
pub in_dtx: bool,
pub lbrr_enabled: bool,
pub lbrr_gain_increases: i32,
pub arch: i32,
}
impl Default for EncoderStateCommon {
fn default() -> Self {
let api_fs_hz = DEFAULT_INTERNAL_FS_KHZ * 1000;
let subfr_length = SUB_FRAME_LENGTH_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
let ltp_mem_length = LTP_MEM_LENGTH_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
let la_pitch = (LA_PITCH_MS as i32) * DEFAULT_INTERNAL_FS_KHZ;
let la_shape = (LA_SHAPE_MS as i32) * DEFAULT_INTERNAL_FS_KHZ;
let shape_win_length =
(SUB_FRAME_LENGTH_MS as i32 * DEFAULT_INTERNAL_FS_KHZ) + 2 * la_shape;
let max_pitch_lag = 18 * DEFAULT_INTERNAL_FS_KHZ;
let pitch_lpc_win_length = FIND_PITCH_LPC_WIN_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
Self {
use_dtx: false,
use_cbr: false,
use_in_band_fec: false,
prev_signal_type: FrameSignalType::Inactive,
fs_khz: DEFAULT_INTERNAL_FS_KHZ,
nb_subfr: MAX_NB_SUBFR,
frame_length: DEFAULT_FRAME_LENGTH,
api_sample_rate_hz: api_fs_hz,
prev_api_sample_rate_hz: api_fs_hz,
max_internal_sample_rate_hz: api_fs_hz,
min_internal_sample_rate_hz: api_fs_hz,
desired_internal_sample_rate_hz: api_fs_hz,
allow_bandwidth_switch: false,
n_channels_api: 1,
n_channels_internal: 1,
channel_nb: 0,
prev_lag: 0,
subfr_length,
ltp_mem_length,
la_pitch,
la_shape,
shape_win_length,
max_pitch_lag,
pitch_lpc_win_length,
predict_lpc_order: MAX_LPC_ORDER,
ps_nlsf_cb: &SILK_NLSF_CB_WB,
pitch_contour_icdf: &PITCH_CONTOUR_ICDF,
pitch_lag_low_bits_icdf: &SILK_UNIFORM8_ICDF,
prev_nlsf_q15: [0; MAX_LPC_ORDER],
target_rate_bps: 0,
snr_db_q7: 0,
sum_log_gain_q7: 0,
nsq_state: NoiseShapingQuantizerState::default(),
frame_counter: 0,
input_buf: [0; INPUT_BUFFER_LENGTH],
input_quality_bands_q15: [0; VAD_N_BANDS],
input_tilt_q15: 0,
speech_activity_q8: 0,
no_speech_counter: 0,
variable_hp_smth1_q15: lin2log(VARIABLE_HP_MIN_CUTOFF_HZ) << 8,
variable_hp_smth2_q15: lin2log(VARIABLE_HP_MIN_CUTOFF_HZ) << 8,
vad_flags: [false; MAX_FRAMES_PER_PACKET],
lbrr_flag: false,
lbrr_flags: [false; MAX_FRAMES_PER_PACKET],
lbrr_prev_last_gain_index: 0,
indices_lbrr: from_fn(|_| SideInfoIndices::default()),
pulses: [0; MAX_FRAME_LENGTH],
pulses_lbrr: from_fn(|_| [0; MAX_FRAME_LENGTH]),
packet_size_ms: MAX_FRAME_LENGTH_MS as i32,
packet_loss_perc: 0,
n_frames_per_packet: 1,
n_frames_encoded: 0,
indices: SideInfoIndices::default(),
input_buf_ix: 0,
first_frame_after_reset: true,
controlled_since_last_payload: false,
prefill_flag: false,
pitch_estimation_complexity: 0,
pitch_estimation_threshold_q16: 0,
pitch_estimation_lpc_order: 0,
shaping_lpc_order: 0,
n_states_delayed_decision: 0,
use_interpolated_nlsfs: false,
nlsf_msvq_survivors: 0,
warping_q16: 0,
complexity: 0,
ec_prev_signal_type: FrameSignalType::Inactive,
ec_prev_lag_index: 0,
in_dtx: false,
lbrr_enabled: false,
lbrr_gain_increases: 0,
arch: 0,
}
}
}
#[derive(Clone, Debug)]
pub struct EncoderChannelState {
pub common: EncoderStateCommon,
pub vad_state: VadState,
pub lp_state: LpState,
pub shape_state: EncoderShapeState,
pub resampler_state: Resampler,
pub x_buf: [i16; X_BUFFER_LENGTH],
pub ltp_corr_q15: i32,
}
impl Default for EncoderChannelState {
fn default() -> Self {
Self {
common: EncoderStateCommon::default(),
vad_state: VadState::default(),
lp_state: LpState::default(),
shape_state: EncoderShapeState::default(),
resampler_state: Resampler::default(),
x_buf: [0; X_BUFFER_LENGTH],
ltp_corr_q15: 0,
}
}
}
impl EncoderChannelState {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_common(common: EncoderStateCommon) -> Self {
Self {
common,
vad_state: VadState::default(),
lp_state: LpState::default(),
shape_state: EncoderShapeState::default(),
resampler_state: Resampler::default(),
x_buf: [0; X_BUFFER_LENGTH],
ltp_corr_q15: 0,
}
}
#[must_use]
pub fn common(&self) -> &EncoderStateCommon {
&self.common
}
#[must_use]
pub fn common_mut(&mut self) -> &mut EncoderStateCommon {
&mut self.common
}
#[must_use]
pub fn vad(&self) -> &VadState {
&self.vad_state
}
#[must_use]
pub fn vad_mut(&mut self) -> &mut VadState {
&mut self.vad_state
}
pub(crate) fn parts_mut(&mut self) -> (&mut EncoderStateCommon, &mut VadState) {
(&mut self.common, &mut self.vad_state)
}
pub(crate) fn common_and_lp_mut(&mut self) -> (&mut EncoderStateCommon, &mut LpState) {
(&mut self.common, &mut self.lp_state)
}
#[must_use]
pub fn low_pass_state(&self) -> &LpState {
&self.lp_state
}
#[must_use]
pub fn low_pass_state_mut(&mut self) -> &mut LpState {
&mut self.lp_state
}
pub fn update_variable_high_pass(&mut self) {
crate::silk::hp_variable_cutoff::hp_variable_cutoff(self);
}
}
#[derive(Clone, Debug)]
pub struct Encoder {
pub state_fxx: [EncoderChannelState; ENCODER_NUM_CHANNELS],
pub stereo_state: StereoEncState,
pub n_bits_used_lbrr: i32,
pub n_bits_exceeded: i32,
pub n_channels_api: i32,
pub n_channels_internal: i32,
pub n_prev_channels_internal: i32,
pub time_since_switch_allowed_ms: i32,
pub allow_bandwidth_switch: bool,
pub prev_decode_only_middle: bool,
}
impl Default for Encoder {
fn default() -> Self {
Self {
state_fxx: from_fn(|_| EncoderChannelState::default()),
stereo_state: StereoEncState::default(),
n_bits_used_lbrr: 0,
n_bits_exceeded: 0,
n_channels_api: 1,
n_channels_internal: 1,
n_prev_channels_internal: 1,
time_since_switch_allowed_ms: 0,
allow_bandwidth_switch: false,
prev_decode_only_middle: false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn encoder_state_common_defaults_match_reference() {
let common = EncoderStateCommon::default();
let api_fs = DEFAULT_INTERNAL_FS_KHZ * 1000;
let subfr_len = SUB_FRAME_LENGTH_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
let ltp_mem_len = LTP_MEM_LENGTH_MS * DEFAULT_INTERNAL_FS_KHZ as usize;
assert_eq!(common.prev_signal_type, FrameSignalType::Inactive);
assert!(!common.use_dtx);
assert!(!common.use_cbr);
assert!(!common.use_in_band_fec);
assert_eq!(common.fs_khz, DEFAULT_INTERNAL_FS_KHZ);
assert_eq!(common.nb_subfr, MAX_NB_SUBFR);
assert_eq!(common.frame_length, DEFAULT_FRAME_LENGTH);
assert_eq!(common.api_sample_rate_hz, api_fs);
assert_eq!(common.prev_api_sample_rate_hz, api_fs);
assert_eq!(common.max_internal_sample_rate_hz, api_fs);
assert_eq!(common.min_internal_sample_rate_hz, api_fs);
assert_eq!(common.desired_internal_sample_rate_hz, api_fs);
assert!(!common.allow_bandwidth_switch);
assert_eq!(common.n_channels_api, 1);
assert_eq!(common.n_channels_internal, 1);
assert_eq!(common.channel_nb, 0);
assert_eq!(common.prev_lag, 0);
assert_eq!(common.subfr_length, subfr_len);
assert_eq!(common.ltp_mem_length, ltp_mem_len);
assert_eq!(
common.la_pitch,
LA_PITCH_MS as i32 * DEFAULT_INTERNAL_FS_KHZ
);
assert_eq!(
common.la_shape,
LA_SHAPE_MS as i32 * DEFAULT_INTERNAL_FS_KHZ
);
assert_eq!(
common.pitch_lpc_win_length,
FIND_PITCH_LPC_WIN_MS * DEFAULT_INTERNAL_FS_KHZ as usize
);
assert_eq!(common.predict_lpc_order, MAX_LPC_ORDER);
assert_eq!(common.ps_nlsf_cb, &SILK_NLSF_CB_WB);
assert_eq!(common.pitch_contour_icdf, &PITCH_CONTOUR_ICDF);
assert_eq!(common.pitch_lag_low_bits_icdf, &SILK_UNIFORM8_ICDF);
assert_eq!(common.prev_nlsf_q15, [0; MAX_LPC_ORDER]);
assert_eq!(common.target_rate_bps, 0);
assert_eq!(common.snr_db_q7, 0);
assert_eq!(common.nsq_state, NoiseShapingQuantizerState::default());
assert_eq!(common.frame_counter, 0);
assert_eq!(common.input_buf, [0; INPUT_BUFFER_LENGTH]);
assert_eq!(common.input_quality_bands_q15, [0; VAD_N_BANDS]);
assert_eq!(common.input_tilt_q15, 0);
assert_eq!(common.speech_activity_q8, 0);
assert_eq!(common.no_speech_counter, 0);
assert_eq!(
common.variable_hp_smth1_q15,
lin2log(VARIABLE_HP_MIN_CUTOFF_HZ) << 8
);
assert_eq!(
common.variable_hp_smth2_q15,
lin2log(VARIABLE_HP_MIN_CUTOFF_HZ) << 8
);
assert_eq!(common.vad_flags, [false; MAX_FRAMES_PER_PACKET]);
assert!(!common.lbrr_flag);
assert_eq!(common.lbrr_flags, [false; MAX_FRAMES_PER_PACKET]);
assert_eq!(common.lbrr_prev_last_gain_index, 0);
assert!(
common
.indices_lbrr
.iter()
.all(|indices| *indices == SideInfoIndices::default())
);
assert_eq!(common.pulses, [0; MAX_FRAME_LENGTH]);
assert!(
common
.pulses_lbrr
.iter()
.all(|pulses| *pulses == [0; MAX_FRAME_LENGTH])
);
assert_eq!(common.packet_size_ms, MAX_FRAME_LENGTH_MS as i32);
assert_eq!(common.packet_loss_perc, 0);
assert_eq!(common.n_frames_per_packet, 1);
assert_eq!(common.n_frames_encoded, 0);
assert_eq!(common.indices, SideInfoIndices::default());
assert_eq!(common.input_buf_ix, 0);
assert!(common.first_frame_after_reset);
assert!(!common.controlled_since_last_payload);
assert!(!common.prefill_flag);
assert_eq!(common.ec_prev_signal_type, FrameSignalType::Inactive);
assert_eq!(common.ec_prev_lag_index, 0);
assert!(!common.in_dtx);
assert!(!common.lbrr_enabled);
assert_eq!(common.lbrr_gain_increases, 0);
assert_eq!(common.arch, 0);
}
#[test]
fn encoder_channel_state_default_wraps_common() {
let channel = EncoderChannelState::default();
assert_eq!(*channel.common(), EncoderStateCommon::default());
assert_eq!(channel.vad(), &VadState::default());
assert_eq!(channel.low_pass_state(), &LpState::default());
assert_eq!(channel.shape_state, EncoderShapeState::default());
assert_eq!(channel.resampler_state.fs_in_khz(), 0);
assert_eq!(channel.resampler_state.fs_out_khz(), 0);
assert_eq!(channel.x_buf, [0; X_BUFFER_LENGTH]);
}
#[test]
fn encoder_channel_state_with_common_preserves_input() {
let mut custom = EncoderStateCommon::default();
custom.fs_khz = 24;
let channel = EncoderChannelState::with_common(custom.clone());
assert_eq!(channel.common(), &custom);
}
#[test]
fn vad_state_reset_matches_reference_bias() {
let mut vad = VadState::default();
vad.noise_level_bias = [0; VAD_N_BANDS];
vad.reset();
assert_eq!(vad.noise_level_bias[0], VAD_NOISE_LEVELS_BIAS);
assert_eq!(vad.noise_level_bias[1], VAD_NOISE_LEVELS_BIAS / 2);
assert_eq!(vad.noise_level_bias[2], VAD_NOISE_LEVELS_BIAS / 3);
assert_eq!(vad.noise_level_bias[3], VAD_NOISE_LEVELS_BIAS / 4);
assert!(vad.nl.iter().all(|&nl| nl > 0));
assert!(vad.inv_nl.iter().all(|&inv| inv > 0));
assert_eq!(vad.nrg_ratio_smth_q8, [INITIAL_NRG_RATIO_Q8; VAD_N_BANDS]);
}
#[test]
fn encoder_super_state_defaults_cover_channels() {
let encoder = Encoder::default();
assert_eq!(encoder.state_fxx.len(), ENCODER_NUM_CHANNELS);
assert!(
encoder
.state_fxx
.iter()
.all(|channel| *channel.common() == EncoderStateCommon::default())
);
assert_eq!(encoder.n_channels_api, 1);
assert_eq!(encoder.n_channels_internal, 1);
assert_eq!(encoder.n_prev_channels_internal, 1);
assert_eq!(encoder.n_bits_used_lbrr, 0);
assert_eq!(encoder.n_bits_exceeded, 0);
assert_eq!(encoder.time_since_switch_allowed_ms, 0);
assert!(!encoder.allow_bandwidth_switch);
assert!(!encoder.prev_decode_only_middle);
}
}