Skip to content

Commit

Permalink
Improve Streams Table stats
Browse files Browse the repository at this point in the history
  • Loading branch information
LVala committed Dec 19, 2023
1 parent e7193de commit 673b30e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 13 deletions.
31 changes: 22 additions & 9 deletions client/src/app/rtp_streams_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
];
Expand All @@ -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)| {
Expand Down Expand Up @@ -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());
});
Expand All @@ -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();
Expand Down Expand Up @@ -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)
Expand Down
25 changes: 21 additions & 4 deletions client/src/streams/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ pub struct Stream {
pub max_jitter: f64,
pub cname: Option<String>,
bytes: usize,
rtp_bytes: usize,
sum_jitter: f64,
jitter_count: usize,
first_sequence_number: u16,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -113,20 +115,33 @@ 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<f64> {
if self.jitter_count == 0 {
return None;
}
Some(self.sum_jitter / self.jitter_count as f64)
}

pub fn get_mean_bitrate(&self) -> f64 {
let duration = self.get_duration().as_secs_f64();
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(),
Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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 {
Expand All @@ -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;
Expand Down

0 comments on commit 673b30e

Please sign in to comment.