Integrate Opus DRED
- Update to webrtc 7680e
This commit is contained in:
parent
db369de324
commit
c39bdb22a7
@ -993,6 +993,99 @@ async fn run_plc_tests(test: &mut Test) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn run_dred_tests(test: &mut Test) -> Result<()> {
|
||||
let configs = [
|
||||
(60, true, 0, Some(0)), // Before DRED with FEC and Opus PLC
|
||||
(60, false, 6, Some(5)), // DRED 60ms
|
||||
(60, false, 12, Some(5)), // DRED 120ms
|
||||
(60, false, 25, Some(5)), // DRED 250ms
|
||||
(60, false, 50, Some(5)), // DRED 500ms
|
||||
(60, false, 100, Some(5)), // DRED 1s
|
||||
];
|
||||
|
||||
let losses = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50];
|
||||
|
||||
let test_cases: Vec<_> = configs
|
||||
.iter()
|
||||
.flat_map(|&(initial_packet_size_ms, enable_fec, dred_duration, decoder_complexity)| {
|
||||
losses.iter().map(move |&loss| TestCaseConfig {
|
||||
test_case_name: format!(
|
||||
"ptime_{initial_packet_size_ms}-fec_{enable_fec}-dred_duration_{dred_duration}-plc_{}-loss_{loss}",
|
||||
decoder_complexity.map_or("None".to_string(), |c| c.to_string())
|
||||
),
|
||||
length_seconds: 30,
|
||||
client_a_config: CallConfig {
|
||||
audio: AudioConfig {
|
||||
input_name: "normal_phrasing".to_string(),
|
||||
generate_spectrogram: false,
|
||||
visqol_speech_analysis: false,
|
||||
visqol_audio_analysis: false,
|
||||
pesq_speech_analysis: false,
|
||||
plc_speech_analysis: false,
|
||||
complexity: 9,
|
||||
initial_packet_size_ms,
|
||||
enable_fec,
|
||||
dred_duration,
|
||||
decoder_complexity,
|
||||
// Force DRED to be encoded with the expected loss rate.
|
||||
min_packet_loss_percent: if dred_duration > 0 { loss } else { 0 },
|
||||
// Only used for Deep PLC (decoder complexity 5) or DRED tests.
|
||||
dnn_weights_path: "/data/deep_plc-dred-weights.bin".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
profile: DeterministicLoss(loss),
|
||||
..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,
|
||||
complexity: 9,
|
||||
initial_packet_size_ms,
|
||||
enable_fec,
|
||||
dred_duration,
|
||||
decoder_complexity,
|
||||
// Force DRED to be encoded with the expected loss rate.
|
||||
min_packet_loss_percent: if dred_duration > 0 { loss } else { 0 },
|
||||
// Only used for Deep PLC (decoder complexity 5) or DRED tests.
|
||||
dnn_weights_path: "/data/deep_plc-dred-weights.bin".to_string(),
|
||||
..Default::default()
|
||||
},
|
||||
profile: DeterministicLoss(loss),
|
||||
..Default::default()
|
||||
},
|
||||
iterations: 3,
|
||||
..Default::default()
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
test.run(
|
||||
GroupConfig {
|
||||
group_name: "dred_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,
|
||||
show_send_stats: false,
|
||||
show_dred_stats: true,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
test_cases,
|
||||
vec![NetworkProfile::None],
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let args = Args::parse();
|
||||
@ -1078,6 +1171,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?,
|
||||
"dred_tests" => run_dred_tests(test).await?,
|
||||
_ => panic!("unknown test set \"{test_set_name}\""),
|
||||
}
|
||||
test.report().await?;
|
||||
|
||||
@ -169,6 +169,7 @@ pub struct MediaFileIo {
|
||||
}
|
||||
|
||||
impl Test {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
root_path: &PathBuf,
|
||||
output_dir: &str,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
webrtc.version=7680c
|
||||
webrtc.version=7680e
|
||||
|
||||
ringrtc.version.major=2
|
||||
ringrtc.version.minor=68
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
{
|
||||
"android": "8be76daee99a7ea273683dbcd396f92db4d7aa0a7a0aac61631cd53693322cf0",
|
||||
"ios": "665f1f19f3de74444c7953f70d599a94c57113374ac62d558f9bce11dc21d1e8",
|
||||
"linux-x64": "74b2e7f9e36b24e81eb06df067e9459d97a9f4d89e1d10dc81c766fb823d1f51",
|
||||
"linux-arm64": "77ee9067a80db4556b02f1f8d97a363ddd2f53499c7e0b1c945bc753d840458d",
|
||||
"mac-x64": "217bc4868e2751b51cd05e332fc87f219b314c8312e1cf02ec75d3be20eefdcc",
|
||||
"mac-arm64": "60536d4de2926fe5a71dae57d671f8d43e1b6cbbb55e555e3cfd79b40c6e6f48",
|
||||
"windows-x64": "c28a52dc851655b45bcc90251b2cc32aa0741e5b34c9ec6ec3ecefbe970f9ce6",
|
||||
"windows-arm64": "0cafb1d30500fe4f3dca465202d6bffb3c54e2ae5dc6e05ce638d600d132b60a"
|
||||
"android": "220b03c2a3af7b9262459aee837b432c6c05d120887c0fe5fb6283f3721e99cb",
|
||||
"ios": "43642dea9ebf9db29d69f0cb1dd9082978a69501bf0e69a14eaf37d015ae1faa",
|
||||
"linux-x64": "194055090f078b7e9f946b9f756144612b854f0d17fe077824d52753d7d7d916",
|
||||
"linux-arm64": "00c54e0fd9afd38c28f011d9ea5d09ba0472e4ae2c93ac756d8e051b55f9f8bf",
|
||||
"mac-x64": "07ac844dc85d808cbfead56e38584515b623efaddcd49dee54cb74da2f9338a0",
|
||||
"mac-arm64": "f35c85ebfaa6bc6dc70d56df552c0805c40f62643e8ff12df23093b663102273",
|
||||
"windows-x64": "8c748f17a958c96c931040329c95cb6235b782ffea2d19c5e1c0ed43b5f12d81",
|
||||
"windows-arm64": "93457fb51b8cd9cbfdcb2dff2a591896fb971c4ddcd38ac1854530e3f2173b29"
|
||||
}
|
||||
|
||||
@ -37,7 +37,9 @@ use crate::{
|
||||
},
|
||||
error::RingRtcError,
|
||||
webrtc::{
|
||||
ice_gatherer::IceGatherer, media::MediaStream, peer_connection::AudioLevel,
|
||||
ice_gatherer::IceGatherer,
|
||||
media::{MediaStream, configure_dred_from_assets},
|
||||
peer_connection::AudioLevel,
|
||||
peer_connection_observer::NetworkRoute,
|
||||
},
|
||||
};
|
||||
@ -583,47 +585,11 @@ where
|
||||
|
||||
let mut call_manager = self.call_manager()?;
|
||||
|
||||
// Change the call configuration based on available assets. Don't use this
|
||||
// if building for the call_sim feature.
|
||||
if cfg!(not(feature = "call_sim")) && call_config.audio_encoder_config.dred_duration > 0 {
|
||||
// See if model assets are available for Opus DRED (including Deep PLC).
|
||||
info!("assets: Checking for opus-dred assets in the registry...");
|
||||
if let Some(versions) = self.asset_registry.get_options_for("opus-dred") {
|
||||
info!(
|
||||
"assets: There are {} opus-dred asset versions available",
|
||||
versions.len()
|
||||
);
|
||||
if let Some(version) = versions.first() {
|
||||
if let Some(asset) = self.asset_registry.get_asset("opus-dred", *version) {
|
||||
info!("assets: opus-dred asset version {version} found");
|
||||
|
||||
// Set the weights on both the encoder and decoder.
|
||||
// Lifetime: Each clone of the Arc<asset_content> will be held by
|
||||
// a connection or group call object which lives as long as the
|
||||
// PeerConnection in WebRTC.
|
||||
call_config.audio_encoder_config.dnn_weights =
|
||||
Some(Arc::clone(&asset.content));
|
||||
call_config.audio_decoder_config.dnn_weights = Some(asset.content);
|
||||
|
||||
// Set up Opus for the optimal DRED configuration.
|
||||
// Disable FEC and make sure that Opus Deep PLC is always used.
|
||||
call_config.audio_encoder_config.enable_fec = false;
|
||||
call_config.audio_decoder_config.complexity = Some(5);
|
||||
} else {
|
||||
warn!("assets: Failed to get opus-dred asset version {version}!");
|
||||
}
|
||||
} else {
|
||||
warn!("assets: No versions found for opus-dred!");
|
||||
}
|
||||
} else {
|
||||
warn!("assets: No opus-dred assets found!");
|
||||
}
|
||||
|
||||
if call_config.audio_encoder_config.dnn_weights.is_none() {
|
||||
warn!("assets: Disabling DRED since no dnn weights were found!");
|
||||
call_config.audio_encoder_config.dred_duration = 0;
|
||||
}
|
||||
}
|
||||
configure_dred_from_assets(
|
||||
&self.asset_registry,
|
||||
&mut call_config.audio_encoder_config,
|
||||
&mut call_config.audio_decoder_config,
|
||||
);
|
||||
|
||||
match self.direction {
|
||||
// This happens after received_offer and an offer is put in self.pending_call.
|
||||
|
||||
@ -63,7 +63,8 @@ use crate::{
|
||||
webrtc::{
|
||||
self,
|
||||
media::{
|
||||
AudioEncoderConfig, AudioTrack, VideoFrame, VideoFrameMetadata, VideoSink, VideoTrack,
|
||||
AudioDecoderConfig, AudioEncoderConfig, AudioTrack, VideoFrame, VideoFrameMetadata,
|
||||
VideoSink, VideoTrack, configure_dred_from_assets,
|
||||
},
|
||||
peer_connection::{AudioLevel, PeerConnection, Protocol, ReceivedAudioLevel, SendRates},
|
||||
peer_connection_factory::{self as pcf, AudioJitterBufferConfig, PeerConnectionFactory},
|
||||
@ -2927,12 +2928,24 @@ impl Client {
|
||||
// Currently, this occurs via on_sfu_client_joined (Joining -> Joined) or
|
||||
// or via peek_result_inner (Joining -> Pending -> Joined)
|
||||
fn on_client_joined(state: &mut State) {
|
||||
let mut encoder_config = AudioEncoderConfig {
|
||||
dred_duration: state.dred_duration,
|
||||
..AudioEncoderConfig::default()
|
||||
};
|
||||
let mut decoder_config = AudioDecoderConfig::default();
|
||||
|
||||
configure_dred_from_assets(
|
||||
&state.asset_registry,
|
||||
&mut encoder_config,
|
||||
&mut decoder_config,
|
||||
);
|
||||
|
||||
state
|
||||
.peer_connection
|
||||
.configure_audio_encoders(&AudioEncoderConfig {
|
||||
dred_duration: state.dred_duration,
|
||||
..AudioEncoderConfig::default()
|
||||
});
|
||||
.configure_audio_encoders(&encoder_config);
|
||||
state
|
||||
.peer_connection
|
||||
.configure_audio_decoders(&decoder_config);
|
||||
}
|
||||
|
||||
pub fn on_signaling_message_received(
|
||||
|
||||
@ -12,7 +12,7 @@ use crate::webrtc::ffi::media;
|
||||
pub use crate::webrtc::peer_connection_factory::RffiPeerConnectionFactoryOwner;
|
||||
#[cfg(feature = "sim")]
|
||||
use crate::webrtc::sim::media;
|
||||
use crate::{lite::sfu::DemuxId, webrtc};
|
||||
use crate::{core::assets::AssetRegistry, lite::sfu::DemuxId, webrtc};
|
||||
|
||||
/// Rust wrapper around WebRTC C++ MediaStream object.
|
||||
#[derive(Clone, Debug)]
|
||||
@ -541,3 +541,51 @@ impl AudioDecoderConfig {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// If dred_duration > 0, looks up DNN weights from the asset registry
|
||||
/// and configures both encoder and decoder for DRED. If no weights are
|
||||
/// found, disables DRED by setting dred_duration to 0.
|
||||
pub fn configure_dred_from_assets(
|
||||
asset_registry: &AssetRegistry,
|
||||
encoder_config: &mut AudioEncoderConfig,
|
||||
decoder_config: &mut AudioDecoderConfig,
|
||||
) {
|
||||
// Don't load assets if we aren't using DRED or building for the Call Simulator.
|
||||
if cfg!(feature = "call_sim") || encoder_config.dred_duration == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
info!("assets: Checking for opus-dred assets in the registry...");
|
||||
if let Some(versions) = asset_registry.get_options_for("opus-dred") {
|
||||
info!(
|
||||
"assets: There are {} opus-dred asset versions available",
|
||||
versions.len()
|
||||
);
|
||||
if let Some(version) = versions.first() {
|
||||
if let Some(asset) = asset_registry.get_asset("opus-dred", *version) {
|
||||
info!("assets: opus-dred asset version {version} found");
|
||||
|
||||
// Set the weights on both the encoder and decoder.
|
||||
// Lifetime: Each clone of the Arc<asset_content> will be held by
|
||||
// a connection or group call object which lives as long as the
|
||||
// PeerConnection in WebRTC.
|
||||
encoder_config.dnn_weights = Some(Arc::clone(&asset.content));
|
||||
decoder_config.dnn_weights = Some(asset.content);
|
||||
|
||||
// Disable FEC when using DRED.
|
||||
encoder_config.enable_fec = false;
|
||||
|
||||
return;
|
||||
} else {
|
||||
warn!("assets: Failed to get opus-dred asset version {version}!");
|
||||
}
|
||||
} else {
|
||||
warn!("assets: No versions found for opus-dred!");
|
||||
}
|
||||
} else {
|
||||
warn!("assets: No opus-dred assets found!");
|
||||
}
|
||||
|
||||
warn!("assets: Disabling DRED since no dnn weights were found!");
|
||||
encoder_config.dred_duration = 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user