aboutsummaryrefslogtreecommitdiff
path: root/xmpp-vala/src/module/xep/0167_jingle_rtp
diff options
context:
space:
mode:
authorMarvin W <git@larma.de>2021-04-29 15:46:06 +0200
committerMarvin W <git@larma.de>2021-04-29 15:53:59 +0200
commit3880628de4785db4c0a03a79a0c486507fe9b1a8 (patch)
tree488180882a2a60576c68e688b743acfaff8d32f7 /xmpp-vala/src/module/xep/0167_jingle_rtp
parent328c3cf37f296f4519829afd03d21f94ea4153e5 (diff)
downloaddino-3880628de4785db4c0a03a79a0c486507fe9b1a8.tar.gz
dino-3880628de4785db4c0a03a79a0c486507fe9b1a8.zip
Video optimizations
Diffstat (limited to 'xmpp-vala/src/module/xep/0167_jingle_rtp')
-rw-r--r--xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala40
-rw-r--r--xmpp-vala/src/module/xep/0167_jingle_rtp/jingle_rtp_module.vala5
-rw-r--r--xmpp-vala/src/module/xep/0167_jingle_rtp/payload_type.vala49
-rw-r--r--xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala7
4 files changed, 98 insertions, 3 deletions
diff --git a/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala b/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala
index d6f1acd2..d4440169 100644
--- a/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala
+++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/content_parameters.vala
@@ -17,6 +17,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
public bool encryption_required { get; private set; default = false; }
public PayloadType? agreed_payload_type { get; private set; }
public Gee.List<PayloadType> payload_types = new ArrayList<PayloadType>(PayloadType.equals_func);
+ public Gee.List<HeaderExtension> header_extensions = new ArrayList<HeaderExtension>();
public Gee.List<Crypto> remote_cryptos = new ArrayList<Crypto>();
public Crypto? local_crypto = null;
public Crypto? remote_crypto = null;
@@ -54,9 +55,12 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
this.remote_cryptos.add(Crypto.parse(crypto));
}
}
- foreach (StanzaNode payloadType in node.get_subnodes("payload-type")) {
+ foreach (StanzaNode payloadType in node.get_subnodes(PayloadType.NAME)) {
this.payload_types.add(PayloadType.parse(payloadType));
}
+ foreach (StanzaNode subnode in node.get_subnodes(HeaderExtension.NAME, HeaderExtension.NS_URI)) {
+ this.header_extensions.add(HeaderExtension.parse(subnode));
+ }
}
public async void handle_proposed_content(XmppStream stream, Jingle.Session session, Jingle.Content content) {
@@ -66,6 +70,11 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
content.reject();
return;
}
+ // Drop unsupported header extensions
+ var iter = header_extensions.iterator();
+ while(iter.next()) {
+ if (!parent.is_header_extension_supported(media, iter.@get())) iter.remove();
+ }
remote_crypto = parent.pick_remote_crypto(remote_cryptos);
if (local_crypto == null && remote_crypto != null) {
local_crypto = parent.pick_local_crypto(remote_crypto);
@@ -151,7 +160,7 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
Gee.List<StanzaNode> crypto_nodes = description_node.get_deep_subnodes("encryption", "crypto");
if (crypto_nodes.size == 0) {
- warning("Counterpart didn't include any cryptos");
+ debug("Counterpart didn't include any cryptos");
if (encryption_required) {
return;
}
@@ -182,6 +191,9 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
ret.put_node(payload_type.to_xml());
}
}
+ foreach (HeaderExtension ext in header_extensions) {
+ ret.put_node(ext.to_xml());
+ }
if (local_crypto != null) {
ret.put_node(new StanzaNode.build("encryption", NS_URI)
.put_node(local_crypto.to_xml()));
@@ -191,4 +203,28 @@ public class Xmpp.Xep.JingleRtp.Parameters : Jingle.ContentParameters, Object {
}
return ret;
}
+}
+
+public class Xmpp.Xep.JingleRtp.HeaderExtension {
+ public const string NS_URI = "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0";
+ public const string NAME = "rtp-hdrext";
+
+ public uint8 id { get; private set; }
+ public string uri { get; private set; }
+
+ public HeaderExtension(uint8 id, string uri) {
+ this.id = id;
+ this.uri = uri;
+ }
+
+ public static HeaderExtension parse(StanzaNode node) {
+ return new HeaderExtension((uint8) node.get_attribute_int("id"), node.get_attribute("uri"));
+ }
+
+ public StanzaNode to_xml() {
+ return new StanzaNode.build(NAME, NS_URI)
+ .add_self_xmlns()
+ .put_attribute("id", id.to_string())
+ .put_attribute("uri", uri);
+ }
} \ No newline at end of file
diff --git a/xmpp-vala/src/module/xep/0167_jingle_rtp/jingle_rtp_module.vala b/xmpp-vala/src/module/xep/0167_jingle_rtp/jingle_rtp_module.vala
index 3adad114..6eb6289b 100644
--- a/xmpp-vala/src/module/xep/0167_jingle_rtp/jingle_rtp_module.vala
+++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/jingle_rtp_module.vala
@@ -24,6 +24,8 @@ public abstract class Module : XmppStreamModule {
public abstract Crypto? pick_remote_crypto(Gee.List<Crypto> cryptos);
public abstract Crypto? pick_local_crypto(Crypto? remote);
public abstract Stream create_stream(Jingle.Content content);
+ public abstract bool is_header_extension_supported(string media, HeaderExtension ext);
+ public abstract Gee.List<HeaderExtension> get_suggested_header_extensions(string media);
public abstract void close_stream(Stream stream);
public async Jingle.Session start_call(XmppStream stream, Jid receiver_full_jid, bool video, string? sid = null) throws Jingle.Error {
@@ -40,6 +42,7 @@ public abstract class Module : XmppStreamModule {
// Create audio content
Parameters audio_content_parameters = new Parameters(this, "audio", yield get_supported_payloads("audio"));
audio_content_parameters.local_crypto = generate_local_crypto();
+ audio_content_parameters.header_extensions.add_all(get_suggested_header_extensions("audio"));
Jingle.Transport? audio_transport = yield jingle_module.select_transport(stream, content_type.required_transport_type, content_type.required_components, receiver_full_jid, Set.empty());
if (audio_transport == null) {
throw new Jingle.Error.NO_SHARED_PROTOCOLS("No suitable audio transports");
@@ -57,6 +60,7 @@ public abstract class Module : XmppStreamModule {
// Create video content
Parameters video_content_parameters = new Parameters(this, "video", yield get_supported_payloads("video"));
video_content_parameters.local_crypto = generate_local_crypto();
+ video_content_parameters.header_extensions.add_all(get_suggested_header_extensions("video"));
Jingle.Transport? video_transport = yield stream.get_module(Jingle.Module.IDENTITY).select_transport(stream, content_type.required_transport_type, content_type.required_components, receiver_full_jid, Set.empty());
if (video_transport == null) {
throw new Jingle.Error.NO_SHARED_PROTOCOLS("No suitable video transports");
@@ -98,6 +102,7 @@ public abstract class Module : XmppStreamModule {
// Content for video does not yet exist -> create it
Parameters video_content_parameters = new Parameters(this, "video", yield get_supported_payloads("video"));
video_content_parameters.local_crypto = generate_local_crypto();
+ video_content_parameters.header_extensions.add_all(get_suggested_header_extensions("video"));
Jingle.Transport? video_transport = yield stream.get_module(Jingle.Module.IDENTITY).select_transport(stream, content_type.required_transport_type, content_type.required_components, receiver_full_jid, Set.empty());
if (video_transport == null) {
throw new Jingle.Error.NO_SHARED_PROTOCOLS("No suitable video transports");
diff --git a/xmpp-vala/src/module/xep/0167_jingle_rtp/payload_type.vala b/xmpp-vala/src/module/xep/0167_jingle_rtp/payload_type.vala
index 452f1d65..faba38c9 100644
--- a/xmpp-vala/src/module/xep/0167_jingle_rtp/payload_type.vala
+++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/payload_type.vala
@@ -3,6 +3,8 @@ using Xmpp;
using Xmpp.Xep;
public class Xmpp.Xep.JingleRtp.PayloadType {
+ public const string NAME = "payload-type";
+
public uint8 id { get; set; }
public string? name { get; set; }
public uint8 channels { get; set; default = 1; }
@@ -10,6 +12,7 @@ public class Xmpp.Xep.JingleRtp.PayloadType {
public uint32 maxptime { get; set; }
public uint32 ptime { get; set; }
public Map<string, string> parameters = new HashMap<string, string>();
+ public Gee.List<RtcpFeedback> rtcp_fbs = new ArrayList<RtcpFeedback>();
public static PayloadType parse(StanzaNode node) {
PayloadType payloadType = new PayloadType();
@@ -22,11 +25,14 @@ public class Xmpp.Xep.JingleRtp.PayloadType {
foreach (StanzaNode parameter in node.get_subnodes("parameter")) {
payloadType.parameters[parameter.get_attribute("name")] = parameter.get_attribute("value");
}
+ foreach (StanzaNode subnode in node.get_subnodes(RtcpFeedback.NAME, RtcpFeedback.NS_URI)) {
+ payloadType.rtcp_fbs.add(RtcpFeedback.parse(subnode));
+ }
return payloadType;
}
public StanzaNode to_xml() {
- StanzaNode node = new StanzaNode.build("payload-type", NS_URI)
+ StanzaNode node = new StanzaNode.build(NAME, NS_URI)
.put_attribute("id", id.to_string());
if (channels != 1) node.put_attribute("channels", channels.to_string());
if (clockrate != 0) node.put_attribute("clockrate", clockrate.to_string());
@@ -38,9 +44,25 @@ public class Xmpp.Xep.JingleRtp.PayloadType {
.put_attribute("name", parameter)
.put_attribute("value", parameters[parameter]));
}
+ foreach (RtcpFeedback rtcp_fb in rtcp_fbs) {
+ node.put_node(rtcp_fb.to_xml());
+ }
return node;
}
+ public PayloadType clone() {
+ PayloadType clone = new PayloadType();
+ clone.id = id;
+ clone.name = name;
+ clone.channels = channels;
+ clone.clockrate = clockrate;
+ clone.maxptime = maxptime;
+ clone.ptime = ptime;
+ clone.parameters.set_all(parameters);
+ clone.rtcp_fbs.add_all(rtcp_fbs);
+ return clone;
+ }
+
public static bool equals_func(PayloadType a, PayloadType b) {
return a.id == b.id &&
a.name == b.name &&
@@ -49,4 +71,29 @@ public class Xmpp.Xep.JingleRtp.PayloadType {
a.maxptime == b.maxptime &&
a.ptime == b.ptime;
}
+}
+
+public class Xmpp.Xep.JingleRtp.RtcpFeedback {
+ public const string NS_URI = "urn:xmpp:jingle:apps:rtp:rtcp-fb:0";
+ public const string NAME = "rtcp-fb";
+
+ public string type_ { get; private set; }
+ public string? subtype { get; private set; }
+
+ public RtcpFeedback(string type, string? subtype = null) {
+ this.type_ = type;
+ this.subtype = subtype;
+ }
+
+ public static RtcpFeedback parse(StanzaNode node) {
+ return new RtcpFeedback(node.get_attribute("type"), node.get_attribute("subtype"));
+ }
+
+ public StanzaNode to_xml() {
+ StanzaNode node = new StanzaNode.build(NAME, NS_URI)
+ .add_self_xmlns()
+ .put_attribute("type", type_);
+ if (subtype != null) node.put_attribute("subtype", subtype);
+ return node;
+ }
} \ No newline at end of file
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 adae11f5..65be8a0a 100644
--- a/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala
+++ b/xmpp-vala/src/module/xep/0167_jingle_rtp/stream.vala
@@ -33,6 +33,13 @@ public abstract class Xmpp.Xep.JingleRtp.Stream : Object {
}
return null;
}}
+ public Gee.List<JingleRtp.HeaderExtension>? header_extensions { get {
+ var content_params = content.content_params;
+ if (content_params is Parameters) {
+ return ((Parameters)content_params).header_extensions;
+ }
+ return null;
+ }}
public bool sending { get {
return content.session.senders_include_us(content.senders);
}}