create objects for ssma (xep-0339)
This commit is contained in:
parent
28ead10ca4
commit
ef51ec2c1d
|
@ -40,6 +40,7 @@ public final class Namespace {
|
||||||
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
|
public static final String JINGLE_FEATURE_VIDEO = "urn:xmpp:jingle:apps:rtp:video";
|
||||||
public static final String JINGLE_RTP_HEADER_EXTENSIONS = "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0";
|
public static final String JINGLE_RTP_HEADER_EXTENSIONS = "urn:xmpp:jingle:apps:rtp:rtp-hdrext:0";
|
||||||
public static final String JINGLE_RTP_FEEDBACK_NEGOTIATION = "urn:xmpp:jingle:apps:rtp:rtcp-fb:0";
|
public static final String JINGLE_RTP_FEEDBACK_NEGOTIATION = "urn:xmpp:jingle:apps:rtp:rtcp-fb:0";
|
||||||
|
public static final String JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES = "urn:xmpp:jingle:apps:rtp:ssma:0";
|
||||||
public static final String IBB = "http://jabber.org/protocol/ibb";
|
public static final String IBB = "http://jabber.org/protocol/ibb";
|
||||||
public static final String PING = "urn:xmpp:ping";
|
public static final String PING = "urn:xmpp:ping";
|
||||||
public static final String PUSH = "urn:xmpp:push:0";
|
public static final String PUSH = "urn:xmpp:push:0";
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import eu.siacs.conversations.Config;
|
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
import eu.siacs.conversations.xml.Namespace;
|
import eu.siacs.conversations.xml.Namespace;
|
||||||
import eu.siacs.conversations.xmpp.jingle.SessionDescription;
|
import eu.siacs.conversations.xmpp.jingle.SessionDescription;
|
||||||
|
@ -56,6 +55,16 @@ public class RtpDescription extends GenericDescription {
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Source> getSources() {
|
||||||
|
final ImmutableList.Builder<Source> builder = new ImmutableList.Builder<>();
|
||||||
|
for (final Element child : this.children) {
|
||||||
|
if ("source".equals(child.getName()) && Namespace.JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES.equals(child.getNamespace())) {
|
||||||
|
builder.add(Source.upgrade(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
public static RtpDescription upgrade(final Element element) {
|
public static RtpDescription upgrade(final Element element) {
|
||||||
Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
|
Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
|
||||||
Preconditions.checkArgument(Namespace.JINGLE_APPS_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
|
Preconditions.checkArgument(Namespace.JINGLE_APPS_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
|
||||||
|
@ -348,6 +357,78 @@ public class RtpDescription extends GenericDescription {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//XEP-0339: Source-Specific Media Attributes in Jingle
|
||||||
|
//maps to `a=ssrc:<ssrc-id> <attribute>:<value>`
|
||||||
|
public static class Source extends Element {
|
||||||
|
|
||||||
|
private Source() {
|
||||||
|
super("source", Namespace.JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Source(String ssrcId, Collection<Parameter> parameters) {
|
||||||
|
super("source", Namespace.JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES);
|
||||||
|
this.setAttribute("ssrc", ssrcId);
|
||||||
|
for (Parameter parameter : parameters) {
|
||||||
|
this.addChild(parameter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSsrcId() {
|
||||||
|
return this.getAttribute("ssrc");
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Parameter> getParameters() {
|
||||||
|
ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>();
|
||||||
|
for (Element child : this.children) {
|
||||||
|
if ("parameter".equals(child.getName())) {
|
||||||
|
builder.add(Parameter.upgrade(child));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Source upgrade(final Element element) {
|
||||||
|
Preconditions.checkArgument("source".equals(element.getName()));
|
||||||
|
Preconditions.checkArgument(Namespace.JINGLE_RTP_SOURCE_SPECIFIC_MEDIA_ATTRIBUTES.equals(element.getNamespace()));
|
||||||
|
final Source source = new Source();
|
||||||
|
source.setChildren(element.getChildren());
|
||||||
|
source.setAttributes(element.getAttributes());
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Parameter extends Element {
|
||||||
|
|
||||||
|
public String getParameterName() {
|
||||||
|
return this.getAttribute("name");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParameterValue() {
|
||||||
|
return this.getAttribute("value");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Parameter() {
|
||||||
|
super("parameter");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Parameter(final String attribute, final String value) {
|
||||||
|
super("parameter");
|
||||||
|
this.setAttribute("name", attribute);
|
||||||
|
if (value != null) {
|
||||||
|
this.setAttribute("value", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Parameter upgrade(final Element element) {
|
||||||
|
Preconditions.checkArgument("parameter".equals(element.getName()));
|
||||||
|
Parameter parameter = new Parameter();
|
||||||
|
parameter.setAttributes(element.getAttributes());
|
||||||
|
parameter.setChildren(element.getChildren());
|
||||||
|
return parameter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public enum Media {
|
public enum Media {
|
||||||
VIDEO, AUDIO, UNKNOWN;
|
VIDEO, AUDIO, UNKNOWN;
|
||||||
|
|
||||||
|
@ -368,7 +449,8 @@ public class RtpDescription extends GenericDescription {
|
||||||
public static RtpDescription of(final SessionDescription.Media media) {
|
public static RtpDescription of(final SessionDescription.Media media) {
|
||||||
final RtpDescription rtpDescription = new RtpDescription();
|
final RtpDescription rtpDescription = new RtpDescription();
|
||||||
final Map<String, List<Parameter>> parameterMap = new HashMap<>();
|
final Map<String, List<Parameter>> parameterMap = new HashMap<>();
|
||||||
ArrayListMultimap<String, Element> feedbackNegotiationMap = ArrayListMultimap.create();
|
final ArrayListMultimap<String, Element> feedbackNegotiationMap = ArrayListMultimap.create();
|
||||||
|
final ArrayListMultimap<String, Source.Parameter> sourceParameterMap = ArrayListMultimap.create();
|
||||||
for (final String rtcpFb : media.attributes.get("rtcp-fb")) {
|
for (final String rtcpFb : media.attributes.get("rtcp-fb")) {
|
||||||
final String[] parts = rtcpFb.split(" ");
|
final String[] parts = rtcpFb.split(" ");
|
||||||
if (parts.length >= 2) {
|
if (parts.length >= 2) {
|
||||||
|
@ -384,6 +466,16 @@ public class RtpDescription extends GenericDescription {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (final String ssrc : media.attributes.get(("ssrc"))) {
|
||||||
|
final String[] parts = ssrc.split(" ", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
final String id = parts[0];
|
||||||
|
final String[] subParts = parts[1].split(":", 2);
|
||||||
|
final String attribute = subParts[0];
|
||||||
|
final String value = subParts.length == 2 ? subParts[1] : null;
|
||||||
|
sourceParameterMap.put(id, new Source.Parameter(attribute, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (final String fmtp : media.attributes.get("fmtp")) {
|
for (final String fmtp : media.attributes.get("fmtp")) {
|
||||||
final Pair<String, List<Parameter>> pair = Parameter.ofSdpString(fmtp);
|
final Pair<String, List<Parameter>> pair = Parameter.ofSdpString(fmtp);
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
|
@ -405,6 +497,9 @@ public class RtpDescription extends GenericDescription {
|
||||||
rtpDescription.addChild(extension);
|
rtpDescription.addChild(extension);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (Map.Entry<String, Collection<Source.Parameter>> source : sourceParameterMap.asMap().entrySet()) {
|
||||||
|
rtpDescription.addChild(new Source(source.getKey(), source.getValue()));
|
||||||
|
}
|
||||||
return rtpDescription;
|
return rtpDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue