From 597e660276a135dc2dee05aade01949dbfea366d Mon Sep 17 00:00:00 2001 From: Miriam Zimmerman Date: Tue, 31 Mar 2026 13:46:09 -0400 Subject: [PATCH] Add codec implementation to ringrtc_stats --- config/version.properties | 2 +- config/webrtc_artifact_checksums.json | 16 ++-- protobuf/protobuf/call_summary.proto | 13 ++-- src/rust/src/core/call_summary.rs | 7 ++ src/rust/src/webrtc/stats_observer.rs | 102 ++++++++++++++++++++++++-- 5 files changed, 119 insertions(+), 21 deletions(-) diff --git a/config/version.properties b/config/version.properties index 224268ee..3ab56548 100644 --- a/config/version.properties +++ b/config/version.properties @@ -1,4 +1,4 @@ -webrtc.version=7444h +webrtc.version=7444i ringrtc.version.major=2 ringrtc.version.minor=67 diff --git a/config/webrtc_artifact_checksums.json b/config/webrtc_artifact_checksums.json index 6556b1ff..7dd52659 100644 --- a/config/webrtc_artifact_checksums.json +++ b/config/webrtc_artifact_checksums.json @@ -1,10 +1,10 @@ { - "android": "29c7a789ba7c641fd71f27563f9fc8f2863c11ef8bba986dba9f7234902244fd", - "ios": "a9ee874613977319fd31cf2c87c2ab1bf434eaf64d72f446f6fdb0b899e0a61e", - "linux-x64": "f0a8fb24c7bd717e9ddcb0741909946987898595279b193b06ef2dcf21cb983a", - "linux-arm64": "4473a9239d3453dc26e6038e827ded3c0d826a6303343463f46f9edea5b22e5a", - "mac-x64": "9957e51250be8c1804e9a33e32bf97bc11592a640074a2f98901555e0fe2e5d5", - "mac-arm64": "76aff4499578064a33c7b2691c2f7ce993e4366eb5950c79eeb360a2d0d998e6", - "windows-x64": "10352eb69ad3494bbf91d5588364b854e73cfcb13a42f05982ffb9a18508a85d", - "windows-arm64": "72e3528382d9e0b1777427d83a41db7dcf564ef871a88530337ef394af0b65c7" + "android": "cb5ae2dca5f13fdfe9b0ba2f509ae1fa47e41d6b040ae5ae3b2abf65ba9ecdbe", + "ios": "35c84370b1bda402aab3902f5a04ffb89f6c9e2d7aa9e483e66db4253c6c4376", + "linux-x64": "903ec5323d937fd9fdea62a7924620b73552652256a4b08f207ba9d0f386f444", + "linux-arm64": "6eb2242360d4b384901b9afad4f92b6f154cc0ff796ec077665555df16c90704", + "mac-x64": "00ed4ba0202bbb029821b5fcee49e9a8cb8bda095a85e1bedf0b115ef3c8a232", + "mac-arm64": "fc9ba0d8d483d4814c03b4da8e7c6c478cb8217544b29964bd635685d9dac856", + "windows-x64": "8fa9404be7ad797b317b7d2208c18663e3c38282e657403d6d15f907f7c0884f", + "windows-arm64": "3bee7cf07a557898612d3abe994b4a51fcb8da6de501f6dc140b9a463e2561e9" } diff --git a/protobuf/protobuf/call_summary.proto b/protobuf/protobuf/call_summary.proto index 534e5688..5eecf321 100644 --- a/protobuf/protobuf/call_summary.proto +++ b/protobuf/protobuf/call_summary.proto @@ -24,14 +24,15 @@ enum VideoCodec { } message StreamSummary { - optional DistributionSummary bitrate = 1; - optional DistributionSummary packet_loss_pct = 2; - optional DistributionSummary jitter = 3; + optional DistributionSummary bitrate = 1; + optional DistributionSummary packet_loss_pct = 2; + optional DistributionSummary jitter = 3; // Only present for received video streams - optional DistributionSummary freeze_count = 4; - optional VideoCodec video_codec = 5; + optional DistributionSummary freeze_count = 4; + optional VideoCodec video_codec = 5; // Always present - optional uint32 ssrc = 6; + optional uint32 ssrc = 6; + optional string codec_implementation = 7; } message StreamSummaries { diff --git a/src/rust/src/core/call_summary.rs b/src/rust/src/core/call_summary.rs index ceec9780..c240604c 100644 --- a/src/rust/src/core/call_summary.rs +++ b/src/rust/src/core/call_summary.rs @@ -214,6 +214,7 @@ struct StreamSummary { jitter: DistributionSummary, freeze_count: DistributionSummary, video_codec: StatsVideoCodecType, + codec_implementation: Option, } /// `StreamSummaries` is converted into `protobuf::call_summary::StreamSummaries` @@ -536,6 +537,7 @@ impl From<(&u32, &StreamSummary)> for protobuf::call_summary::StreamSummary { StatsVideoCodecType::Vp9 => Some(VideoCodec::Vp9.into()), StatsVideoCodecType::Invalid => None, }, + codec_implementation: summary.codec_implementation.clone(), ssrc: Some(*ssrc), } } @@ -754,6 +756,8 @@ impl CallInfo { summary.bitrate.push(snapshot.bitrate); summary.packet_loss.push(snapshot.remote_packets_lost_pct); summary.jitter.push(snapshot.remote_jitter as f32); + summary.video_codec = snapshot.codec; + summary.codec_implementation = snapshot.encoder_implementation.clone(); }); self.stats_sets .push_video_send_stream_stats(snapshot.into()); @@ -773,6 +777,8 @@ impl CallInfo { summary.packet_loss.push(snapshot.packets_lost_pct); summary.jitter.push(snapshot.jitter as f32); summary.freeze_count.push(snapshot.freeze_count as f32); + summary.video_codec = snapshot.codec; + summary.codec_implementation = snapshot.decoder_implementation.clone(); }); self.stats_sets .push_video_recv_stream_stats(snapshot.into()); @@ -1416,6 +1422,7 @@ mod test { }), freeze_count: None, video_codec: None, + codec_implementation: None, ssrc: Some(v), }) .collect::>() diff --git a/src/rust/src/webrtc/stats_observer.rs b/src/rust/src/webrtc/stats_observer.rs index 75ff356e..c8b4e3eb 100644 --- a/src/rust/src/webrtc/stats_observer.rs +++ b/src/rust/src/webrtc/stats_observer.rs @@ -8,6 +8,8 @@ use std::{ borrow::Cow, collections::HashMap, + default::Default, + ffi::CStr, fmt::{Debug, Display, Formatter}, ops::Sub, slice, @@ -113,6 +115,7 @@ fn compute_packets_per_second(packet_count: u32, seconds_elapsed: f32) -> f32 { // Stays in sync with rffi type #[derive(Debug, Copy, Clone, Default)] +#[repr(C)] pub enum StatsVideoCodecType { #[default] Invalid = 0, @@ -372,6 +375,7 @@ pub struct VideoSenderStatsSnapshot { pub remote_jitter: f64, pub remote_round_trip_time: f64, pub codec: StatsVideoCodecType, + pub encoder_implementation: Option, } impl Display for VideoSenderStatsSnapshot { @@ -397,7 +401,9 @@ impl Display for VideoSenderStatsSnapshot { remote_jitter, remote_round_trip_time, codec, + encoder_implementation, } = self; + let encoder_impl_str = encoder_implementation.as_deref().unwrap_or("ImplNone"); write!( f, "{},\ @@ -419,7 +425,8 @@ impl Display for VideoSenderStatsSnapshot { {remote_packets_lost_pct:.1}%,\ {remote_jitter:.1}ms,\ {remote_round_trip_time:.1}ms,\ - {codec}", + {codec},\ + {encoder_impl_str}", Self::LOG_MARKER ) } @@ -448,7 +455,8 @@ impl VideoSenderStatsSnapshot { remote_packets_lost_pct,\ remote_jitter,\ remote_round_trip_time,\ - codec"; + codec,\ + encoder_implementation"; fn derive( curr_stats: &VideoSenderStatistics, @@ -500,6 +508,16 @@ impl VideoSenderStatsSnapshot { let quality_limitation_reason = curr_stats.quality_limitation_reason_description(); + let encoder_implementation = if !curr_stats.raw_encoder_implementation.is_null() { + Some(unsafe { + CStr::from_ptr(curr_stats.raw_encoder_implementation.as_ptr()) + .to_string_lossy() + .into_owned() + }) + } else { + None + }; + Self { ssrc: curr_stats.ssrc, packets_per_second, @@ -521,6 +539,7 @@ impl VideoSenderStatsSnapshot { remote_jitter, remote_round_trip_time, codec: curr_stats.codec, + encoder_implementation, } } } @@ -539,6 +558,7 @@ pub struct VideoReceiverStatsSnapshot { pub jitter: f64, pub freeze_count: u32, pub codec: StatsVideoCodecType, + pub decoder_implementation: Option, } impl Display for VideoReceiverStatsSnapshot { @@ -556,7 +576,9 @@ impl Display for VideoReceiverStatsSnapshot { jitter, freeze_count, codec, + decoder_implementation, } = self; + let decoder_impl_str = decoder_implementation.as_deref().unwrap_or("ImplNone"); write!( f, "{},\ @@ -570,7 +592,8 @@ impl Display for VideoReceiverStatsSnapshot { {width}x{height},\ {jitter:.0}ms,\ {freeze_count},\ - {codec}", + {codec},\ + {decoder_impl_str}", Self::LOG_MARKER, ) } @@ -591,7 +614,8 @@ impl VideoReceiverStatsSnapshot { resolution,\ jitter,\ freeze_count,\ - codec"; + codec,\ + decoder_implementation"; fn derive( curr_stats: &VideoReceiverStatistics, @@ -619,6 +643,16 @@ impl VideoReceiverStatsSnapshot { .naive_checked_div(frames_decoded_delta as f64) .unwrap_or(0.0); + let decoder_implementation = if !curr_stats.raw_decoder_implementation.is_null() { + Some(unsafe { + CStr::from_ptr(curr_stats.raw_decoder_implementation.as_ptr()) + .to_string_lossy() + .into_owned() + }) + } else { + None + }; + Self { ssrc: curr_stats.ssrc, packets_per_second, @@ -632,6 +666,7 @@ impl VideoReceiverStatsSnapshot { jitter, freeze_count, codec: curr_stats.codec, + decoder_implementation, } } } @@ -990,7 +1025,7 @@ pub struct AudioSenderStatistics { } #[repr(C)] -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct VideoSenderStatistics { pub ssrc: u32, pub packets_sent: u32, @@ -1011,6 +1046,34 @@ pub struct VideoSenderStatistics { pub remote_jitter: f64, pub remote_round_trip_time: f64, pub codec: StatsVideoCodecType, + pub raw_encoder_implementation: webrtc::ptr::Borrowed, +} + +impl Default for VideoSenderStatistics { + fn default() -> Self { + Self { + ssrc: Default::default(), + packets_sent: Default::default(), + bytes_sent: Default::default(), + frames_encoded: Default::default(), + key_frames_encoded: Default::default(), + total_encode_time: Default::default(), + frame_width: Default::default(), + frame_height: Default::default(), + retransmitted_packets_sent: Default::default(), + retransmitted_bytes_sent: Default::default(), + total_packet_send_delay: Default::default(), + nack_count: Default::default(), + pli_count: Default::default(), + quality_limitation_reason: Default::default(), + quality_limitation_resolution_changes: Default::default(), + remote_packets_lost: Default::default(), + remote_jitter: Default::default(), + remote_round_trip_time: Default::default(), + codec: Default::default(), + raw_encoder_implementation: webrtc::ptr::Borrowed::null(), + } + } } impl VideoSenderStatistics { @@ -1056,7 +1119,7 @@ pub struct AudioReceiverStatistics { } #[repr(C)] -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct VideoReceiverStatistics { pub ssrc: u32, pub packets_received: u32, @@ -1076,6 +1139,33 @@ pub struct VideoReceiverStatistics { pub jitter_buffer_flushes: u64, pub estimated_playout_timestamp: f64, pub codec: StatsVideoCodecType, + pub raw_decoder_implementation: webrtc::ptr::Borrowed, +} + +impl Default for VideoReceiverStatistics { + fn default() -> Self { + Self { + ssrc: Default::default(), + packets_received: Default::default(), + packets_lost: Default::default(), + bytes_received: Default::default(), + frames_received: Default::default(), + frames_decoded: Default::default(), + key_frames_decoded: Default::default(), + total_decode_time: Default::default(), + frame_width: Default::default(), + frame_height: Default::default(), + freeze_count: Default::default(), + total_freezes_duration: Default::default(), + jitter: Default::default(), + jitter_buffer_delay: Default::default(), + jitter_buffer_emitted_count: Default::default(), + jitter_buffer_flushes: Default::default(), + estimated_playout_timestamp: Default::default(), + codec: Default::default(), + raw_decoder_implementation: webrtc::ptr::Borrowed::null(), + } + } } #[repr(C)]