diff --git a/libdino/src/service/call_peer_state.vala b/libdino/src/service/call_peer_state.vala
index ddd0d8dd..c7bcd201 100644
--- a/libdino/src/service/call_peer_state.vala
+++ b/libdino/src/service/call_peer_state.vala
@@ -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; }
}
\ No newline at end of file
diff --git a/main/src/ui/call_window/call_connection_details_window.vala b/main/src/ui/call_window/call_connection_details_window.vala
index b292b971..95e00296 100644
--- a/main/src/ui/call_window/call_connection_details_window.vala
+++ b/main/src/ui/call_window/call_connection_details_window.vala
@@ -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 = "%lu 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 = "%lu 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 = "%lu 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 = "%lu 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;
}
diff --git a/plugins/rtp/src/stream.vala b/plugins/rtp/src/stream.vala
index 17c955a5..bfe5ae28 100644
--- a/plugins/rtp/src/stream.vala
+++ b/plugins/rtp/src/stream.vala
@@ -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);
}
}
diff --git a/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala b/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala
index 65be8a0a..031f0ad0 100644
--- a/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala
+++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala
@@ -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;
}