Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,36 @@ impl Decoder {
map_sys_error!(result => ())
}

#[cfg(feature = "dred")]
#[inline]
///Configures the decoder's computational complexity.
///
///The supported range is 0-10 inclusive with 10 representing the highest complexity.
///Values of 5 or above will use deep packet loss concealment.
pub fn set_complexity(&mut self, value: u8) -> Result<(), ErrorCode> {
let result = unsafe {
sys::opus_decoder_ctl(
self.inner.as_mut(),
sys::OPUS_SET_COMPLEXITY_REQUEST,
value as i32,
)
};

map_sys_error!(result => ())
}

#[cfg(feature = "dred")]
#[inline]
///Gets the decoder's complexity configuration.
pub fn get_complexity(&mut self) -> Result<u8, ErrorCode> {
let mut value: i32 = 0;
let result = unsafe {
sys::opus_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_COMPLEXITY_REQUEST, &mut value)
};

map_sys_error!(result => value as u8)
}

#[inline]
///Gets the decoder's last bandpass
pub fn get_bandwidth(&mut self) -> Result<Bandwidth, ErrorCode> {
Expand Down
43 changes: 43 additions & 0 deletions tests/opus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,49 @@ fn should_verify_decoder_building() {
}
}

#[test]
#[cfg(feature = "dred")]
fn should_verify_decoder_complexity() {
let mut decoder = Decoder::new(Channels::Stereo, SampleRate::Hz48000).expect("Create");
decoder.set_complexity(5).expect("set complexity");
let value = decoder.get_complexity().expect("get complexity");
assert_eq!(value, 5);
}

#[test]
#[cfg(feature = "dred")]
fn should_produce_different_artifacts_on_packet_loss() {
const SIZE_20MS: usize = frame_bytes_size(SampleRate::Hz48000, Channels::Stereo, 20);

//Helper to prime a decoder and get the concealed audio from a subsequent packet loss.
fn get_concealed_audio(complexity: u8, packet: &[u8]) -> Vec<u16> {
let mut decoder = Decoder::new(Channels::Stereo, SampleRate::Hz48000).expect("Failed to create decoder");
decoder.set_complexity(complexity).expect("Failed to set complexity");

let mut buffer = [0u16; SIZE_20MS];
//Prime the decoder with one real frame.
decoder.decode_to_slice(packet, &mut buffer, false).expect("Failed to decode initial packet");
//Get the concealed audio from a lost frame.
let len = decoder.decode_to_slice(&[], &mut buffer, false).expect("Failed to decode lost packet");
buffer[..len].to_vec()
}

//Create a non-silent audio frame to encode.
let mut encoder = Encoder::new(Channels::Stereo, SampleRate::Hz48000, Application::Audio).expect("Failed to create encoder");
let input = [123u16; SIZE_20MS];
let mut packet_buffer = [0u8; 256];
let packet_len = encoder.encode_to_slice(&input, &mut packet_buffer).expect("Failed to encode");
let packet = &packet_buffer[..packet_len];

//Get concealed audio for different complexities.
let concealed_c0 = get_concealed_audio(0, packet);
let concealed_c10 = get_concealed_audio(10, packet);

//Assert the outputs are different.
assert_eq!(concealed_c0.len(), concealed_c10.len());
assert_ne!(concealed_c0, concealed_c10, "Concealed audio should differ by complexity");
}

#[test]
fn should_fail_to_repacketizer() {
let mut packet = [0u8; 1277];
Expand Down
Loading