sdp media to description parsing
This commit is contained in:
parent
18059345c8
commit
28ead10ca4
|
@ -1,12 +1,16 @@
|
||||||
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
package eu.siacs.conversations.xmpp.jingle.stanzas;
|
||||||
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
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.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
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 eu.siacs.conversations.Config;
|
import eu.siacs.conversations.Config;
|
||||||
import eu.siacs.conversations.xml.Element;
|
import eu.siacs.conversations.xml.Element;
|
||||||
|
@ -66,6 +70,14 @@ public class RtpDescription extends GenericDescription {
|
||||||
super("rtcp-fb", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
super("rtcp-fb", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FeedbackNegotiation(String type, String subType) {
|
||||||
|
super("rtcp-fb", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
||||||
|
this.setAttribute("type", type);
|
||||||
|
if (subType != null) {
|
||||||
|
this.setAttribute("subtype", subType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return this.getAttribute("type");
|
return this.getAttribute("type");
|
||||||
}
|
}
|
||||||
|
@ -96,6 +108,13 @@ public class RtpDescription extends GenericDescription {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class FeedbackNegotiationTrrInt extends Element {
|
public static class FeedbackNegotiationTrrInt extends Element {
|
||||||
|
|
||||||
|
private FeedbackNegotiationTrrInt(int value) {
|
||||||
|
super("rtcp-fb-trr-int", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
||||||
|
this.setAttribute("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private FeedbackNegotiationTrrInt() {
|
private FeedbackNegotiationTrrInt() {
|
||||||
super("rtcp-fb-trr-int", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
super("rtcp-fb-trr-int", Namespace.JINGLE_RTP_FEEDBACK_NEGOTIATION);
|
||||||
}
|
}
|
||||||
|
@ -105,11 +124,8 @@ public class RtpDescription extends GenericDescription {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
try {
|
return SessionDescription.ignorantIntParser(value);
|
||||||
return Integer.parseInt(value);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static FeedbackNegotiationTrrInt upgrade(final Element element) {
|
private static FeedbackNegotiationTrrInt upgrade(final Element element) {
|
||||||
|
@ -169,7 +185,7 @@ public class RtpDescription extends GenericDescription {
|
||||||
if (pair.length == 2) {
|
if (pair.length == 2) {
|
||||||
final String id = pair[0];
|
final String id = pair[0];
|
||||||
final String uri = pair[1];
|
final String uri = pair[1];
|
||||||
return new RtpHeaderExtension(id,uri);
|
return new RtpHeaderExtension(id, uri);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -185,7 +201,7 @@ public class RtpDescription extends GenericDescription {
|
||||||
|
|
||||||
public PayloadType(String id, String name, int clockRate, int channels) {
|
public PayloadType(String id, String name, int clockRate, int channels) {
|
||||||
super("payload-type", Namespace.JINGLE_APPS_RTP);
|
super("payload-type", Namespace.JINGLE_APPS_RTP);
|
||||||
this.setAttribute("id",id);
|
this.setAttribute("id", id);
|
||||||
this.setAttribute("name", name);
|
this.setAttribute("name", name);
|
||||||
this.setAttribute("clockrate", clockRate);
|
this.setAttribute("clockrate", clockRate);
|
||||||
if (channels != 1) {
|
if (channels != 1) {
|
||||||
|
@ -252,7 +268,7 @@ public class RtpDescription extends GenericDescription {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PayloadType ofSdpString(final String sdp) {
|
public static PayloadType ofSdpString(final String sdp) {
|
||||||
final String[] pair = sdp.split(" ",2);
|
final String[] pair = sdp.split(" ", 2);
|
||||||
if (pair.length == 2) {
|
if (pair.length == 2) {
|
||||||
final String id = pair[0];
|
final String id = pair[0];
|
||||||
final String[] parts = pair[1].split("/");
|
final String[] parts = pair[1].split("/");
|
||||||
|
@ -263,13 +279,25 @@ public class RtpDescription extends GenericDescription {
|
||||||
if (parts.length >= 3) {
|
if (parts.length >= 3) {
|
||||||
channels = SessionDescription.ignorantIntParser(parts[2]);
|
channels = SessionDescription.ignorantIntParser(parts[2]);
|
||||||
} else {
|
} else {
|
||||||
channels =1;
|
channels = 1;
|
||||||
}
|
}
|
||||||
return new PayloadType(id,name,clockRate,channels);
|
return new PayloadType(id, name, clockRate, channels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addChildren(final List<Element> children) {
|
||||||
|
if (children != null) {
|
||||||
|
this.children.addAll(children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addParameters(List<Parameter> parameters) {
|
||||||
|
if (parameters != null) {
|
||||||
|
this.children.addAll(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//map to `fmtp $id key=value;key=value
|
//map to `fmtp $id key=value;key=value
|
||||||
|
@ -301,6 +329,23 @@ public class RtpDescription extends GenericDescription {
|
||||||
parameter.setChildren(element.getChildren());
|
parameter.setChildren(element.getChildren());
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Pair<String, List<Parameter>> ofSdpString(final String sdp) {
|
||||||
|
final String[] pair = sdp.split(" ");
|
||||||
|
if (pair.length == 2) {
|
||||||
|
final String id = pair[0];
|
||||||
|
ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>();
|
||||||
|
for (final String parameter : pair[1].split(";")) {
|
||||||
|
final String[] parts = parameter.split("=", 2);
|
||||||
|
if (parts.length == 2) {
|
||||||
|
builder.add(new Parameter(parts[0], parts[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Pair<>(id, builder.build());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Media {
|
public enum Media {
|
||||||
|
@ -322,13 +367,39 @@ 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();
|
||||||
for(final String rtpmap : media.attributes.get("rtpmap")) {
|
final Map<String, List<Parameter>> parameterMap = new HashMap<>();
|
||||||
|
ArrayListMultimap<String, Element> feedbackNegotiationMap = ArrayListMultimap.create();
|
||||||
|
for (final String rtcpFb : media.attributes.get("rtcp-fb")) {
|
||||||
|
final String[] parts = rtcpFb.split(" ");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
final String id = parts[0];
|
||||||
|
final String type = parts[1];
|
||||||
|
final String subType = parts.length >= 3 ? parts[2] : null;
|
||||||
|
if ("trr-int".equals(type)) {
|
||||||
|
if (subType != null) {
|
||||||
|
feedbackNegotiationMap.put(id, new FeedbackNegotiationTrrInt(SessionDescription.ignorantIntParser(subType)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
feedbackNegotiationMap.put(id, new FeedbackNegotiation(type, subType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final String fmtp : media.attributes.get("fmtp")) {
|
||||||
|
final Pair<String, List<Parameter>> pair = Parameter.ofSdpString(fmtp);
|
||||||
|
if (pair != null) {
|
||||||
|
parameterMap.put(pair.first, pair.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rtpDescription.addChildren(feedbackNegotiationMap.get("*"));
|
||||||
|
for (final String rtpmap : media.attributes.get("rtpmap")) {
|
||||||
final PayloadType payloadType = PayloadType.ofSdpString(rtpmap);
|
final PayloadType payloadType = PayloadType.ofSdpString(rtpmap);
|
||||||
if (payloadType != null) {
|
if (payloadType != null) {
|
||||||
|
payloadType.addParameters(parameterMap.get(payloadType.getId()));
|
||||||
|
payloadType.addChildren(feedbackNegotiationMap.get(payloadType.getId()));
|
||||||
rtpDescription.addChild(payloadType);
|
rtpDescription.addChild(payloadType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(final String extmap : media.attributes.get("extmap")) {
|
for (final String extmap : media.attributes.get("extmap")) {
|
||||||
final RtpHeaderExtension extension = RtpHeaderExtension.ofSdpString(extmap);
|
final RtpHeaderExtension extension = RtpHeaderExtension.ofSdpString(extmap);
|
||||||
if (extension != null) {
|
if (extension != null) {
|
||||||
rtpDescription.addChild(extension);
|
rtpDescription.addChild(extension);
|
||||||
|
@ -336,4 +407,10 @@ public class RtpDescription extends GenericDescription {
|
||||||
}
|
}
|
||||||
return rtpDescription;
|
return rtpDescription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addChildren(List<Element> elements) {
|
||||||
|
if (elements != null) {
|
||||||
|
this.children.addAll(elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue