Add opus decoder configuration plumbing
- Removes the need for the OpusGeneratePlc field trial setting
This commit is contained in:
parent
a9832d0681
commit
fd98a5ca7a
@ -449,6 +449,9 @@ pub struct AudioConfig {
|
||||
pub enable_dtx: bool,
|
||||
/// Flag to enable the Opus in-band FEC.
|
||||
pub enable_fec: bool,
|
||||
/// None when using NetEq PLC, 0 use Opus PLC, 5 use Opus Deep PLC (if compiled),
|
||||
/// 6 use Opus Deep PLC + LACE (if compiled), 7 use Opus Deep PLC + NoLACE (if compiled).
|
||||
pub decoder_complexity: Option<u8>,
|
||||
/// Flag to enable transport-wide congestion control for audio.
|
||||
pub enable_tcc: bool,
|
||||
/// Flag to enable WebRTC's high pass filter.
|
||||
@ -511,6 +514,7 @@ impl Default for AudioConfig {
|
||||
enable_cbr: true,
|
||||
enable_dtx: true,
|
||||
enable_fec: true,
|
||||
decoder_complexity: Some(0),
|
||||
enable_tcc: false,
|
||||
enable_high_pass_filter: true,
|
||||
// Default tests now disable AEC in order to prevent random timing delays
|
||||
|
||||
@ -962,6 +962,10 @@ pub async fn start_cli(
|
||||
args.push(format!("--dtx={}", call_config.audio.enable_dtx));
|
||||
args.push(format!("--fec={}", call_config.audio.enable_fec));
|
||||
|
||||
if let Some(complexity) = call_config.audio.decoder_complexity {
|
||||
args.push(format!("--decoder-complexity={}", complexity));
|
||||
}
|
||||
|
||||
args.push(format!("--tcc={}", call_config.audio.enable_tcc));
|
||||
|
||||
args.push(format!("--vp9={}", call_config.video.enable_vp9));
|
||||
|
||||
@ -924,6 +924,66 @@ async fn run_perf_test(test: &mut Test) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Test the different PLC modes: NetEq, Opus.
|
||||
async fn run_plc_tests(test: &mut Test) -> Result<()> {
|
||||
let test_cases = [None, Some(0)].map(|decoder_complexity| TestCaseConfig {
|
||||
test_case_name: format!(
|
||||
"plc_{}",
|
||||
decoder_complexity.map_or("None".to_string(), |c| c.to_string())
|
||||
),
|
||||
client_a_config: CallConfig {
|
||||
audio: AudioConfig {
|
||||
input_name: "normal_phrasing".to_string(),
|
||||
generate_spectrogram: false,
|
||||
decoder_complexity,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
client_b_config: CallConfig {
|
||||
audio: AudioConfig {
|
||||
input_name: "normal_phrasing".to_string(),
|
||||
visqol_speech_analysis: true,
|
||||
visqol_audio_analysis: true,
|
||||
pesq_speech_analysis: true,
|
||||
plc_speech_analysis: true,
|
||||
decoder_complexity,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
iterations: 1,
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
test.run(
|
||||
GroupConfig {
|
||||
group_name: "plc_tests".to_string(),
|
||||
summary_report_columns: SummaryReportColumns {
|
||||
show_visqol_mos_speech: true,
|
||||
show_visqol_mos_audio: true,
|
||||
show_pesq_mos: true,
|
||||
show_plc_mos: true,
|
||||
show_video: false,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
test_cases.into(),
|
||||
vec![
|
||||
NetworkProfile::None,
|
||||
NetworkProfile::SimpleLoss(10),
|
||||
NetworkProfile::SimpleLoss(20),
|
||||
NetworkProfile::SimpleLoss(30),
|
||||
NetworkProfile::SimpleLoss(40),
|
||||
NetworkProfile::SimpleLoss(50),
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
@ -1007,6 +1067,7 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
"changing_bandwidth_audio_test" => run_changing_bandwidth_audio_test(test).await?,
|
||||
"profiling_suite" => run_perf_test(test).await?,
|
||||
"plc_tests" => run_plc_tests(test).await?,
|
||||
_ => panic!("unknown test set \"{test_set_name}\""),
|
||||
}
|
||||
test.report().await?;
|
||||
|
||||
@ -110,7 +110,6 @@ public class CallManager {
|
||||
fieldTrialsWithDefaults.put("RingRTC-PruneTurnPorts", "Enabled");
|
||||
fieldTrialsWithDefaults.put("WebRTC-Bwe-ProbingConfiguration", "skip_if_est_larger_than_fraction_of_max:0.99");
|
||||
fieldTrialsWithDefaults.put("WebRTC-IncreaseIceCandidatePriorityHostSrflx", "Enabled");
|
||||
fieldTrialsWithDefaults.put("WebRTC-Audio-OpusGeneratePlc", "Enabled");
|
||||
fieldTrialsWithDefaults.putAll(fieldTrials);
|
||||
|
||||
CallManager.fieldTrials = buildFieldTrialsString(fieldTrialsWithDefaults);
|
||||
|
||||
@ -92,7 +92,6 @@ public class CallManagerGlobal {
|
||||
"RingRTC-PruneTurnPorts": "Enabled",
|
||||
"WebRTC-Bwe-ProbingConfiguration": "skip_if_est_larger_than_fraction_of_max:0.99",
|
||||
"WebRTC-IncreaseIceCandidatePriorityHostSrflx": "Enabled",
|
||||
"WebRTC-Audio-OpusGeneratePlc": "Enabled",
|
||||
]) { (provided, _) in provided }
|
||||
RTCInitFieldTrialDictionary(fieldTrialsWithDefaults)
|
||||
Logger.info("Initialized field trials with \(fieldTrialsWithDefaults)")
|
||||
|
||||
@ -46,7 +46,6 @@ class NativeCallManager {
|
||||
'WebRTC-Bwe-ProbingConfiguration':
|
||||
'skip_if_est_larger_than_fraction_of_max:0.99',
|
||||
'WebRTC-IncreaseIceCandidatePriorityHostSrflx': 'Enabled',
|
||||
'WebRTC-Audio-OpusGeneratePlc': 'Enabled',
|
||||
},
|
||||
config.field_trials
|
||||
);
|
||||
|
||||
@ -20,7 +20,7 @@ use ringrtc::{
|
||||
core::group_call::GroupId,
|
||||
lite::sfu::{GroupMember, MembershipProof, UserId},
|
||||
webrtc::{
|
||||
media::{AudioBandwidth, AudioEncoderConfig},
|
||||
media::{AudioBandwidth, AudioDecoderConfig, AudioEncoderConfig},
|
||||
peer_connection_factory::{AudioConfig, AudioJitterBufferConfig, IceServer},
|
||||
},
|
||||
};
|
||||
@ -126,6 +126,10 @@ struct Args {
|
||||
#[arg(long, default_value_t = 0)]
|
||||
adaptation: i32,
|
||||
|
||||
/// The decoding complexity for audio.
|
||||
#[arg(long, default_value = None, value_parser = clap::value_parser!(u8).range(0..=10))]
|
||||
decoder_complexity: Option<u8>,
|
||||
|
||||
/// Whether to enable transport-cc feedback for audio. This will allow the bitrate to vary
|
||||
/// between `min_bitrate_bps` and `max_bitrate_bps` when using CBR.
|
||||
#[arg(long, action = clap::ArgAction::Set, default_value = "false")]
|
||||
@ -303,6 +307,9 @@ fn main() -> Result<()> {
|
||||
enable_fec: args.fec,
|
||||
dred_duration: 0,
|
||||
},
|
||||
audio_decoder_config: AudioDecoderConfig {
|
||||
complexity: args.decoder_complexity,
|
||||
},
|
||||
enable_tcc_audio: args.tcc,
|
||||
audio_jitter_buffer_config: AudioJitterBufferConfig {
|
||||
max_packets: args.audio_jitter_buffer_max_packets,
|
||||
|
||||
@ -17,7 +17,7 @@ use std::fmt;
|
||||
pub use versioning::SemanticVersion;
|
||||
|
||||
use crate::webrtc::{
|
||||
media::AudioEncoderConfig,
|
||||
media::{AudioDecoderConfig, AudioEncoderConfig},
|
||||
peer_connection_factory::{AudioConfig, AudioJitterBufferConfig},
|
||||
};
|
||||
|
||||
@ -842,6 +842,7 @@ pub struct CallConfig {
|
||||
|
||||
pub audio_config: AudioConfig,
|
||||
pub audio_encoder_config: AudioEncoderConfig,
|
||||
pub audio_decoder_config: AudioDecoderConfig,
|
||||
pub enable_tcc_audio: bool,
|
||||
pub audio_jitter_buffer_config: AudioJitterBufferConfig,
|
||||
pub audio_rtcp_report_interval_ms: i32,
|
||||
@ -858,6 +859,7 @@ impl Default for CallConfig {
|
||||
call_summary_time_limit_secs: 300,
|
||||
audio_config: Default::default(),
|
||||
audio_encoder_config: Default::default(),
|
||||
audio_decoder_config: Default::default(),
|
||||
enable_tcc_audio: false,
|
||||
audio_jitter_buffer_config: Default::default(),
|
||||
audio_rtcp_report_interval_ms: 5000,
|
||||
|
||||
@ -763,6 +763,7 @@ where
|
||||
observer.get_result()?;
|
||||
|
||||
peer_connection.configure_audio_encoders(&self.call_config.audio_encoder_config);
|
||||
peer_connection.configure_audio_decoders(&self.call_config.audio_decoder_config);
|
||||
|
||||
self.apply_bandwidth_controller(&mut bandwidth_controller, &mut webrtc)?;
|
||||
|
||||
@ -889,6 +890,7 @@ where
|
||||
observer.get_result()?;
|
||||
|
||||
peer_connection.configure_audio_encoders(&self.call_config.audio_encoder_config);
|
||||
peer_connection.configure_audio_decoders(&self.call_config.audio_decoder_config);
|
||||
|
||||
self.apply_bandwidth_controller(&mut bandwidth_controller, &mut webrtc)?;
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ use crate::{
|
||||
webrtc,
|
||||
webrtc::{
|
||||
ffi::ice_gatherer::RffiIceGatherer,
|
||||
media::RffiAudioEncoderConfig,
|
||||
media::{RffiAudioDecoderConfig, RffiAudioEncoderConfig},
|
||||
network::{RffiIp, RffiIpPort},
|
||||
peer_connection::{RffiAudioLevel, RffiReceivedAudioLevel},
|
||||
rtp,
|
||||
@ -145,6 +145,11 @@ unsafe extern "C" {
|
||||
config: webrtc::ptr::Borrowed<RffiAudioEncoderConfig>,
|
||||
);
|
||||
|
||||
pub fn Rust_configureAudioDecoders(
|
||||
peer_connection: webrtc::ptr::BorrowedRc<RffiPeerConnection>,
|
||||
config: webrtc::ptr::Borrowed<RffiAudioDecoderConfig>,
|
||||
);
|
||||
|
||||
pub fn Rust_getAudioLevels(
|
||||
peer_connection: webrtc::ptr::BorrowedRc<RffiPeerConnection>,
|
||||
captured_out: webrtc::ptr::Borrowed<RffiAudioLevel>,
|
||||
|
||||
@ -440,3 +440,34 @@ impl AudioEncoderConfig {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Same as webrtc::AudioDecoder::Config in api/audio_codecs/audio_decoder.h.
|
||||
// Very OPUS-specific
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RffiAudioDecoderConfig {
|
||||
complexity: i32,
|
||||
}
|
||||
|
||||
// A nice form of RffiAudioDecoderConfig
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AudioDecoderConfig {
|
||||
pub complexity: Option<u8>,
|
||||
}
|
||||
|
||||
impl Default for AudioDecoderConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
complexity: Some(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AudioDecoderConfig {
|
||||
pub fn rffi(&self) -> RffiAudioDecoderConfig {
|
||||
RffiAudioDecoderConfig {
|
||||
// Set to -1 to use the default Opus value (and avoid setting anything).
|
||||
complexity: self.complexity.map(|c| c as i32).unwrap_or(-1),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ use crate::{
|
||||
webrtc,
|
||||
webrtc::{
|
||||
ice_gatherer::IceGatherer,
|
||||
media::AudioEncoderConfig,
|
||||
media::{AudioDecoderConfig, AudioEncoderConfig},
|
||||
network::RffiIpPort,
|
||||
peer_connection_factory::RffiPeerConnectionFactoryOwner,
|
||||
peer_connection_observer::RffiPeerConnectionObserver,
|
||||
@ -376,6 +376,19 @@ impl PeerConnection {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn configure_audio_decoders(&self, audio_decoder_config: &AudioDecoderConfig) {
|
||||
info!(
|
||||
"PeerConnection.configure_audio_decoders({:?})",
|
||||
audio_decoder_config
|
||||
);
|
||||
unsafe {
|
||||
pc::Rust_configureAudioDecoders(
|
||||
self.rffi.as_borrowed(),
|
||||
webrtc::ptr::Borrowed::from_ptr(&audio_decoder_config.rffi()),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_audio_levels(&self) -> (AudioLevel, Vec<RffiReceivedAudioLevel>) {
|
||||
let captured_level: RffiAudioLevel = 0;
|
||||
let mut received_levels: Vec<RffiReceivedAudioLevel> = Vec::with_capacity(100);
|
||||
|
||||
@ -17,7 +17,7 @@ use crate::{
|
||||
core::platform::PlatformItem,
|
||||
webrtc,
|
||||
webrtc::{
|
||||
media::RffiAudioEncoderConfig,
|
||||
media::{RffiAudioDecoderConfig, RffiAudioEncoderConfig},
|
||||
network::RffiIpPort,
|
||||
peer_connection::{RffiAudioLevel, RffiReceivedAudioLevel},
|
||||
rtp,
|
||||
@ -355,6 +355,14 @@ pub unsafe fn Rust_configureAudioEncoders(
|
||||
info!("Rust_configureAudioEncoders:");
|
||||
}
|
||||
|
||||
#[allow(non_snake_case, clippy::missing_safety_doc)]
|
||||
pub unsafe fn Rust_configureAudioDecoders(
|
||||
_peer_connection: webrtc::ptr::BorrowedRc<RffiPeerConnection>,
|
||||
_config: webrtc::ptr::Borrowed<RffiAudioDecoderConfig>,
|
||||
) {
|
||||
info!("Rust_configureAudioDecoders:");
|
||||
}
|
||||
|
||||
#[allow(non_snake_case, clippy::missing_safety_doc)]
|
||||
pub fn Rust_getAudioLevels(
|
||||
_peer_connection: webrtc::ptr::BorrowedRc<RffiPeerConnection>,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user