From 673b30ebb379701ffce3e800afff693ac0042086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Wala?= Date: Tue, 19 Dec 2023 19:00:30 +0100 Subject: [PATCH] Improve Streams Table stats --- client/src/app/rtp_streams_table.rs | 31 ++++++++++++++++++++--------- client/src/streams/stream.rs | 25 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/client/src/app/rtp_streams_table.rs b/client/src/app/rtp_streams_table.rs index a219ac5..bb8ba3f 100644 --- a/client/src/app/rtp_streams_table.rs +++ b/client/src/app/rtp_streams_table.rs @@ -74,12 +74,14 @@ impl RtpStreamsTable { ("SSRC", "RTP SSRC (Synchronization Source Identifier) identifies the source of an RTP stream"), ("Source", "Source IP address and port"), ("Destination", "Destination IP address and port"), - ("CNAME", "Source Description CNAME value, if received"), + ("CNAME", "Source Description CNAME value, if received (latest one if changed mid-stream"), + ("Payload type", "Payload type of this stream (latest one if changed mid-stream)"), ("Packet count", "Number of packets in stream"), ("Packet loss", "Percentage of packets lost"), ("Duration", "Difference between last timestamp and first timestamp."), - ("Mean jitter", "Average of jitter (in ms) for all of the packets"), - ("Mean bitrate", "Sum of packet sizes (IP header included) divided by stream's duration (in kbps)"), + ("Mean jitter", "Average of jitter for all of the packets"), + ("Mean bitrate", "Sum of packet sizes (IP header included) divided by stream's duration"), + ("Mean RTP bitrate", "Sum of packet sizes (RTP only) divided by stream's duration"), ("Mean packet rate", "Number of packets divided by stream's duration"), ("Jitter history", "Plot representing jitter for all of the stream's packets") ]; @@ -92,8 +94,8 @@ impl RtpStreamsTable { .columns(Column::initial(140.0).at_least(140.0), 2) .columns(Column::initial(80.0).at_least(80.0), 3) .column(Column::initial(70.0).at_least(70.0)) - .columns(Column::initial(80.0).at_least(80.0), 2) .column(Column::initial(70.0).at_least(70.0)) + .columns(Column::initial(80.0).at_least(80.0), 4) .column(Column::remainder().at_least(380.0).resizable(false)) .header(30.0, |mut header| { header_labels.iter().for_each(|(label, desc)| { @@ -133,6 +135,10 @@ impl RtpStreamsTable { row.col(|ui| { ui.label(stream.cname.as_ref().unwrap_or(&"N/A".to_string())); }); + row.col(|ui| { + let pt = stream.get_payload_type(); + ui.label(pt.id.to_string()).on_hover_text(pt.to_string()); + }); row.col(|ui| { ui.label(stream.rtp_packets.len().to_string()); }); @@ -143,15 +149,22 @@ impl RtpStreamsTable { }); row.col(|ui| { let duration = stream.get_duration().as_secs_f64(); - ui.label(format!("{:.3}s", duration)); + ui.label(format!("{:.2} s", duration)); }); row.col(|ui| { - let jitter = stream.get_mean_jitter() * 1000.0; - ui.label(format!("{:.3}ms", jitter)); + let jitter_label = match stream.get_mean_jitter() { + Some(jitter) => format!("{:.3} ms", jitter * 1000.0), + None => "N/A".to_string(), + }; + ui.label(jitter_label); }); row.col(|ui| { let bitrate = stream.get_mean_bitrate() / 1000.0; - ui.label(format!("{:.3}", bitrate)); + ui.label(format!("{:.2} kbps", bitrate)); + }); + row.col(|ui| { + let bitrate = stream.get_mean_rtp_bitrate() / 1000.0; + ui.label(format!("{:.2} kbps", bitrate)); }); row.col(|ui| { let packet_rate = stream.get_mean_packet_rate(); @@ -203,7 +216,7 @@ fn build_jitter_plot(ui: &mut egui::Ui, stream: &Stream) { .show_background(false) .show_axes([true, true]) .label_formatter(|_name, value| { - format!("packet id: {}\njitter = {:.3}ms", value.x, value.y) + format!("packet id: {}\njitter = {:.3} ms", value.x, value.y) }) .set_margin_fraction(Vec2::new(0.1, 0.1)) .allow_scroll(false) diff --git a/client/src/streams/stream.rs b/client/src/streams/stream.rs index 9be4016..df9f06a 100644 --- a/client/src/streams/stream.rs +++ b/client/src/streams/stream.rs @@ -50,6 +50,7 @@ pub struct Stream { pub max_jitter: f64, pub cname: Option, bytes: usize, + rtp_bytes: usize, sum_jitter: f64, jitter_count: usize, first_sequence_number: u16, @@ -86,6 +87,7 @@ impl Stream { rtp_packets: vec![rtp_info], rtcp_packets: Vec::new(), bytes: packet.length as usize, + rtp_bytes: rtp.payload_length, max_jitter: 0.0, sum_jitter: 0.0, jitter_count: 0, @@ -113,8 +115,11 @@ impl Stream { (self.last_sequence_number + 1 - self.first_sequence_number) as usize } - pub fn get_mean_jitter(&self) -> f64 { - self.sum_jitter / self.jitter_count as f64 + pub fn get_mean_jitter(&self) -> Option { + if self.jitter_count == 0 { + return None; + } + Some(self.sum_jitter / self.jitter_count as f64) } pub fn get_mean_bitrate(&self) -> f64 { @@ -122,11 +127,21 @@ impl Stream { self.bytes as f64 * 8.0 / duration } + pub fn get_mean_rtp_bitrate(&self) -> f64 { + let duration = self.get_duration().as_secs_f64(); + self.rtp_bytes as f64 * 8.0 / duration + } + pub fn get_mean_packet_rate(&self) -> f64 { let duration = self.get_duration().as_secs_f64(); self.rtp_packets.len() as f64 / duration } + pub fn get_payload_type(&self) -> PayloadType { + let packet = self.rtp_packets.last().unwrap(); + self.get_packet_payload_type(packet) + } + pub fn add_rtp_packet(&mut self, packet: &Packet, rtp: &RtpPacket) { let rtp_info = RtpInfo { packet: rtp.clone(), @@ -173,6 +188,7 @@ impl Stream { let mut rtp_packets = std::mem::take(&mut self.rtp_packets).into_iter(); let rtp_info = rtp_packets.next().unwrap(); self.bytes = rtp_info.bytes; + self.bytes = rtp_info.packet.payload_length; self.max_jitter = 0.0; self.sum_jitter = 0.0; self.jitter_count = 0; @@ -193,6 +209,7 @@ impl Stream { self.update_rates(&mut rtp_info); self.bytes += rtp_info.bytes; + self.rtp_bytes += rtp_info.packet.payload_length; self.first_time = min(self.first_time, rtp_info.time); self.last_time = max(self.last_time, rtp_info.time); @@ -208,7 +225,7 @@ impl Stream { // TODO } - fn get_payload_type(&self, rtp_info: &RtpInfo) -> PayloadType { + fn get_packet_payload_type(&self, rtp_info: &RtpInfo) -> PayloadType { let id = &rtp_info.packet.payload_type.id; if let Some(sdp) = &self.sdp { @@ -221,7 +238,7 @@ impl Stream { } fn update_jitter(&mut self, rtp_info: &mut RtpInfo) { - let payload_type = self.get_payload_type(rtp_info); + let payload_type = self.get_packet_payload_type(rtp_info); let Some(clock_rate) = payload_type.clock_rate else { return;