RtpDescription.java

  1package eu.siacs.conversations.xmpp.jingle.stanzas;
  2
  3import com.google.common.base.Preconditions;
  4import com.google.common.collect.ImmutableList;
  5
  6import java.util.List;
  7import java.util.Locale;
  8
  9import eu.siacs.conversations.xml.Element;
 10import eu.siacs.conversations.xml.Namespace;
 11
 12public class RtpDescription extends GenericDescription {
 13
 14
 15    private RtpDescription(String name, String namespace) {
 16        super(name, namespace);
 17    }
 18
 19    public Media getMedia() {
 20        return Media.of(this.getAttribute("media"));
 21    }
 22
 23    public List<PayloadType> getPayloadTypes() {
 24        final ImmutableList.Builder<PayloadType> builder = new ImmutableList.Builder<>();
 25        for(Element child : getChildren()) {
 26            if ("payload-type".equals(child.getName())) {
 27                builder.add(PayloadType.of(child));
 28            }
 29        }
 30        return builder.build();
 31    }
 32
 33    public List<RtpHeaderExtension> getHeaderExtensions() {
 34        final ImmutableList.Builder<RtpHeaderExtension> builder = new ImmutableList.Builder<>();
 35        for(final Element child : getChildren()) {
 36            if ("rtp-hdrext".equals(child.getName()) && Namespace.JINGLE_RTP_HEADER_EXTENSIONS.equals(child.getNamespace())) {
 37                builder.add(RtpHeaderExtension.upgrade(child));
 38            }
 39        }
 40        return builder.build();
 41    }
 42
 43    public static RtpDescription upgrade(final Element element) {
 44        Preconditions.checkArgument("description".equals(element.getName()), "Name of provided element is not description");
 45        Preconditions.checkArgument(Namespace.JINGLE_APPS_RTP.equals(element.getNamespace()), "Element does not match the jingle rtp namespace");
 46        final RtpDescription description = new RtpDescription("description", Namespace.JINGLE_APPS_RTP);
 47        description.setAttributes(element.getAttributes());
 48        description.setChildren(element.getChildren());
 49        return description;
 50    }
 51
 52    //TODO: support for https://xmpp.org/extensions/xep-0293.html
 53
 54
 55    public static class RtpHeaderExtension extends Element {
 56
 57        private RtpHeaderExtension() {
 58            super("rtp-hdrext", Namespace.JINGLE_RTP_HEADER_EXTENSIONS);
 59        }
 60
 61        public String getId() {
 62            return this.getAttribute("id");
 63        }
 64
 65        public String getUri() {
 66            return this.getAttribute("uri");
 67        }
 68
 69        public static RtpHeaderExtension upgrade(final Element element) {
 70            Preconditions.checkArgument("rtp-hdrext".equals(element.getName()));
 71            Preconditions.checkArgument(Namespace.JINGLE_RTP_HEADER_EXTENSIONS.equals(element.getNamespace()));
 72            final RtpHeaderExtension extension = new RtpHeaderExtension();
 73            extension.setAttributes(element.getAttributes());
 74            extension.setChildren(element.getChildren());
 75            return extension;
 76        }
 77    }
 78
 79    public static class PayloadType extends Element {
 80
 81        private PayloadType(String name, String xmlns) {
 82            super(name, xmlns);
 83        }
 84        public String getId() {
 85            return this.getAttribute("id");
 86        }
 87
 88        public String getPayloadTypeName() {
 89            return this.getAttribute("name");
 90        }
 91
 92        public int getClockRate() {
 93            final String clockRate = this.getAttribute("clockrate");
 94            if (clockRate == null) {
 95                return 0;
 96            }
 97            try {
 98                return Integer.parseInt(clockRate);
 99            } catch (NumberFormatException e) {
100                return 0;
101            }
102        }
103
104        public int getChannels() {
105            final String channels = this.getAttribute("channels");
106            if (channels == null) {
107                return 1; // The number of channels; if omitted, it MUST be assumed to contain one channel
108            }
109            try {
110                return Integer.parseInt(channels);
111            } catch (NumberFormatException e) {
112                return 1;
113            }
114        }
115
116        public List<Parameter> getParameters() {
117            final ImmutableList.Builder<Parameter> builder = new ImmutableList.Builder<>();
118            for (Element child : getChildren()) {
119                if ("parameter".equals(child.getName())) {
120                    builder.add(Parameter.of(child));
121                }
122            }
123            return builder.build();
124        }
125
126        public static PayloadType of(final Element element) {
127            Preconditions.checkArgument("payload-type".equals(element.getName()), "element name must be called payload-type");
128            PayloadType payloadType = new PayloadType("payload-type", Namespace.JINGLE_APPS_RTP);
129            payloadType.setAttributes(element.getAttributes());
130            payloadType.setChildren(element.getChildren());
131            return payloadType;
132        }
133    }
134
135    public static class Parameter extends Element {
136
137        private Parameter() {
138            super("parameter", Namespace.JINGLE_APPS_RTP);
139        }
140
141        public Parameter(String name, String value) {
142            super("parameter", Namespace.JINGLE_APPS_RTP);
143            this.setAttribute("name", name);
144            this.setAttribute("value", value);
145        }
146
147        public String getParameterName() {
148            return this.getAttribute("name");
149        }
150
151        public String getParameterValue() {
152            return this.getAttribute("value");
153        }
154
155        public static Parameter of(final Element element) {
156            Preconditions.checkArgument("parameter".equals(element.getName()), "element name must be called parameter");
157            Parameter parameter = new Parameter();
158            parameter.setAttributes(element.getAttributes());
159            parameter.setChildren(element.getChildren());
160            return parameter;
161        }
162    }
163
164    public enum Media {
165        VIDEO, AUDIO, UNKNOWN;
166
167        @Override
168        public String toString() {
169            return super.toString().toLowerCase(Locale.ROOT);
170        }
171
172        public static Media of(String value) {
173            try {
174                return value == null ? UNKNOWN : Media.valueOf(value.toUpperCase(Locale.ROOT));
175            } catch (IllegalArgumentException e) {
176                return UNKNOWN;
177            }
178        }
179    }
180}