Display target bitrates in connection details UI

This commit is contained in:
fiaxh 2021-11-11 21:54:55 +01:00
parent 1b157a20ab
commit e205743f0c
4 changed files with 55 additions and 18 deletions

View file

@ -260,6 +260,10 @@ public class Dino.PeerState : Object {
ret.audio_codec = audio_content_parameter.agreed_payload_type.name;
ret.audio_clockrate = audio_content_parameter.agreed_payload_type.clockrate;
}
if (audio_content_parameter.stream != null && audio_content_parameter.stream.remb_enabled) {
ret.audio_target_receive_bitrate = audio_content_parameter.stream.target_receive_bitrate;
ret.audio_target_send_bitrate = audio_content_parameter.stream.target_send_bitrate;
}
}
if (audio_content != null) {
@ -278,6 +282,10 @@ public class Dino.PeerState : Object {
if (video_content_parameter.agreed_payload_type != null) {
ret.video_codec = video_content_parameter.agreed_payload_type.name;
}
if (video_content_parameter.stream != null && video_content_parameter.stream.remb_enabled) {
ret.video_target_receive_bitrate = video_content_parameter.stream.target_receive_bitrate;
ret.video_target_send_bitrate = video_content_parameter.stream.target_send_bitrate;
}
}
if (video_content != null) {
@ -443,6 +451,8 @@ public class Dino.PeerInfo {
public ulong? audio_bytes_received { get; set; default=0; }
public string? audio_codec { get; set; }
public uint32 audio_clockrate { get; set; }
public uint audio_target_receive_bitrate { get; set; default=0; }
public uint audio_target_send_bitrate { get; set; default=0; }
public bool video_content_exists { get; set; }
public bool video_rtp_ready { get; set; }
@ -450,4 +460,6 @@ public class Dino.PeerInfo {
public ulong? video_bytes_sent { get; set; default=0; }
public ulong? video_bytes_received { get; set; default=0; }
public string? video_codec { get; set; }
public uint video_target_receive_bitrate { get; set; default=0; }
public uint video_target_send_bitrate { get; set; default=0; }
}

View file

@ -8,15 +8,19 @@ namespace Dino.Ui {
public Label audio_rtp_ready = new Label("?") { xalign=0, visible=true };
public Label audio_rtcp_ready = new Label("?") { xalign=0, visible=true };
public Label audio_sent_bps = new Label("?") { xalign=0, visible=true };
public Label audio_recv_bps = new Label("?") { xalign=0, visible=true };
public Label audio_sent_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
public Label audio_recv_bps = new Label("?") { use_markup=true, xalign=0, visible=true };
public Label audio_codec = new Label("?") { xalign=0, visible=true };
public Label audio_target_receive_bitrate = new Label("n/a") { xalign=0, visible=true };
public Label audio_target_send_bitrate = new Label("n/a") { xalign=0, visible=true };
public Label video_rtp_ready = new Label("") { xalign=0, visible=true };
public Label video_rtcp_ready = new Label("") { xalign=0, visible=true };
public Label video_sent_bps = new Label("") { xalign=0, visible=true };
public Label video_recv_bps = new Label("") { xalign=0, visible=true };
public Label video_sent_bps = new Label("") { use_markup=true, xalign=0, visible=true };
public Label video_recv_bps = new Label("") { use_markup=true, xalign=0, visible=true };
public Label video_codec = new Label("") { xalign=0, visible=true };
public Label video_target_receive_bitrate = new Label("n/a") { xalign=0, visible=true };
public Label video_target_send_bitrate = new Label("n/a") { xalign=0, visible=true };
private int row_at = 0;
private bool video_added = false;
@ -34,6 +38,10 @@ namespace Dino.Ui {
grid.attach(audio_recv_bps, 1, row_at++, 1, 1);
put_row("Codec");
grid.attach(audio_codec, 1, row_at++, 1, 1);
put_row("Target receive bitrate");
grid.attach(audio_target_receive_bitrate, 1, row_at++, 1, 1);
put_row("Target send bitrate");
grid.attach(audio_target_send_bitrate, 1, row_at++, 1, 1);
this.child = grid;
}
@ -46,18 +54,26 @@ namespace Dino.Ui {
audio_rtp_ready.label = peer_info.audio_rtp_ready.to_string();
audio_rtcp_ready.label = peer_info.audio_rtcp_ready.to_string();
audio_codec.label = peer_info.audio_codec + " " + peer_info.audio_clockrate.to_string();
audio_target_receive_bitrate.label = peer_info.audio_target_receive_bitrate.to_string();
audio_target_send_bitrate.label = peer_info.audio_target_send_bitrate.to_string();
video_rtp_ready.label = peer_info.video_rtp_ready.to_string();
video_rtcp_ready.label = peer_info.video_rtcp_ready.to_string();
video_codec.label = peer_info.video_codec;
video_target_receive_bitrate.label = peer_info.video_target_receive_bitrate.to_string();
video_target_send_bitrate.label = peer_info.video_target_send_bitrate.to_string();
if (peer_info.video_content_exists) add_video_widgets();
if (prev_peer_info != null) {
audio_sent_bps.label = (peer_info.audio_bytes_sent - prev_peer_info.audio_bytes_sent).to_string();
audio_recv_bps.label = (peer_info.audio_bytes_received - prev_peer_info.audio_bytes_received).to_string();
video_sent_bps.label = (peer_info.video_bytes_sent - prev_peer_info.video_bytes_sent).to_string();
video_recv_bps.label = (peer_info.video_bytes_received - prev_peer_info.video_bytes_received).to_string();
ulong audio_sent_kbps = (peer_info.audio_bytes_sent - prev_peer_info.audio_bytes_sent) * 8 / 1000;
audio_sent_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_sent_kbps);
ulong audio_recv_kbps = (peer_info.audio_bytes_received - prev_peer_info.audio_bytes_received) * 8 / 1000;
audio_recv_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(audio_recv_kbps);
ulong video_sent_kbps = (peer_info.video_bytes_sent - prev_peer_info.video_bytes_sent) * 8 / 1000;
video_sent_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(video_sent_kbps);
ulong video_recv_kbps = (peer_info.video_bytes_received - prev_peer_info.video_bytes_received) * 8 / 1000;
video_recv_bps.label = "<span font_family='monospace'>%lu</span> kbps".printf(video_recv_kbps);
}
prev_peer_info = peer_info;
}
@ -76,6 +92,10 @@ namespace Dino.Ui {
grid.attach(video_recv_bps, 1, row_at++, 1, 1);
put_row("Codec");
grid.attach(video_codec, 1, row_at++, 1, 1);
put_row("Target receive bitrate");
grid.attach(video_target_receive_bitrate, 1, row_at++, 1, 1);
put_row("Target send bitrate");
grid.attach(video_target_send_bitrate, 1, row_at++, 1, 1);
video_added = true;
}

View file

@ -153,7 +153,7 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
plugin.unpause();
GLib.Signal.emit_by_name(rtpbin, "get-session", rtpid, out session);
if (session != null && payload_type.rtcp_fbs.any_match((it) => it.type_ == "goog-remb")) {
if (session != null && remb_enabled) {
Object internal_session;
session.@get("internal-session", out internal_session);
if (internal_session != null) {
@ -166,7 +166,6 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
}
}
private uint remb = 256;
private int last_packets_lost = -1;
private uint64 last_packets_received;
private uint64 last_octets_received;
@ -212,12 +211,12 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
if (new_received == 0) continue;
double loss_rate = (double)new_lost / (double)(new_lost + new_received);
if (new_lost <= 0 || loss_rate < 0.02) {
remb = (uint)(1.08 * (double)remb);
target_receive_bitrate = (uint)(1.08 * (double)target_receive_bitrate);
} else if (loss_rate > 0.1) {
remb = (uint)((1.0 - 0.5 * loss_rate) * (double)remb);
target_receive_bitrate = (uint)((1.0 - 0.5 * loss_rate) * (double)target_receive_bitrate);
}
remb = uint.max(remb, (uint)((new_octets * 8) / 1000));
remb = uint.max(16, remb); // Never go below 16
target_receive_bitrate = uint.max(target_receive_bitrate, (uint)((new_octets * 8) / 1000));
target_receive_bitrate = uint.max(16, target_receive_bitrate); // Never go below 16
uint8[] data = new uint8[] {
143, 206, 0, 5,
0, 0, 0, 0,
@ -231,7 +230,7 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
data[6] = (uint8)((our_ssrc >> 8) & 0xff);
data[7] = (uint8)(our_ssrc & 0xff);
uint8 br_exp = 0;
uint32 br_mant = remb * 1000;
uint32 br_mant = target_receive_bitrate * 1000;
uint8 bits = (uint8)Math.log2(br_mant);
if (bits > 16) {
br_exp = (uint8)bits - 16;
@ -258,8 +257,8 @@ public class Dino.Plugins.Rtp.Stream : Xmpp.Xep.JingleRtp.Stream {
if (data[0] != 'R' || data[1] != 'E' || data[2] != 'M' || data[3] != 'B') return;
uint8 br_exp = data[5] >> 2;
uint32 br_mant = (((uint32)data[5] & 0x3) << 16) + ((uint32)data[6] << 8) + (uint32)data[7];
uint bitrate = (br_mant << br_exp) / 1000;
self.input_device.update_bitrate(self.payload_type, bitrate);
self.target_send_bitrate = (br_mant << br_exp) / 1000;
self.input_device.update_bitrate(self.payload_type, self.target_send_bitrate);
}
}

View file

@ -1,5 +1,4 @@
public abstract class Xmpp.Xep.JingleRtp.Stream : Object {
public Jingle.Content content { get; protected set; }
public string name { get {
@ -54,6 +53,13 @@ public abstract class Xmpp.Xep.JingleRtp.Stream : Object {
return false;
}}
// Receiver Estimated Maximum Bitrate
public bool remb_enabled { get {
return payload_type != null ? payload_type.rtcp_fbs.any_match((it) => it.type_ == "goog-remb") : false;
}}
public uint target_receive_bitrate { get; set; default=256; }
public uint target_send_bitrate { get; set; default=256; }
protected Stream(Jingle.Content content) {
this.content = content;
}