1 /* 2 * Copyright 2018 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 package org.webrtc; 12 13 import java.util.ArrayList; 14 import java.util.Collections; 15 import java.util.List; 16 import org.webrtc.MediaStreamTrack; 17 import org.webrtc.RtpParameters; 18 19 /** 20 * Java wrapper for a C++ RtpTransceiverInterface. 21 * 22 * <p>The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the WebRTC 23 * specification. A transceiver represents a combination of an RTCRtpSender 24 * and an RTCRtpReceiver that share a common mid. As defined in JSEP, an 25 * RTCRtpTransceiver is said to be associated with a media description if its 26 * mid property is non-nil; otherwise, it is said to be disassociated. 27 * JSEP: https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24 28 * 29 * <p>Note that RTCRtpTransceivers are only supported when using 30 * RTCPeerConnection with Unified Plan SDP. 31 * 32 * <p>WebRTC specification for RTCRtpTransceiver, the JavaScript analog: 33 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver 34 */ 35 public class RtpTransceiver { 36 /** Java version of webrtc::RtpTransceiverDirection - the ordering must be kept in sync. */ 37 public enum RtpTransceiverDirection { 38 SEND_RECV(0), 39 SEND_ONLY(1), 40 RECV_ONLY(2), 41 INACTIVE(3), 42 STOPPED(4); 43 44 private final int nativeIndex; 45 RtpTransceiverDirection(int nativeIndex)46 private RtpTransceiverDirection(int nativeIndex) { 47 this.nativeIndex = nativeIndex; 48 } 49 50 @CalledByNative("RtpTransceiverDirection") getNativeIndex()51 int getNativeIndex() { 52 return nativeIndex; 53 } 54 55 @CalledByNative("RtpTransceiverDirection") fromNativeIndex(int nativeIndex)56 static RtpTransceiverDirection fromNativeIndex(int nativeIndex) { 57 for (RtpTransceiverDirection type : RtpTransceiverDirection.values()) { 58 if (type.getNativeIndex() == nativeIndex) { 59 return type; 60 } 61 } 62 throw new IllegalArgumentException( 63 "Uknown native RtpTransceiverDirection type" + nativeIndex); 64 } 65 } 66 67 /** 68 * Tracks webrtc::RtpTransceiverInit. https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit 69 * A structure for initializing an RtpTransceiver in a call to addTransceiver. 70 * Note: This does not contain a list of encoding parameters, because they are currently 71 * not being used natively. 72 */ 73 public static final class RtpTransceiverInit { 74 private final RtpTransceiverDirection direction; 75 private final List<String> streamIds; 76 private final List<RtpParameters.Encoding> sendEncodings; 77 RtpTransceiverInit()78 public RtpTransceiverInit() { 79 this(RtpTransceiverDirection.SEND_RECV); 80 } 81 RtpTransceiverInit(RtpTransceiverDirection direction)82 public RtpTransceiverInit(RtpTransceiverDirection direction) { 83 this(direction, Collections.emptyList(), Collections.emptyList()); 84 } 85 RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds)86 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds) { 87 this(direction, streamIds, Collections.emptyList()); 88 } 89 RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds, List<RtpParameters.Encoding> sendEncodings)90 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds, 91 List<RtpParameters.Encoding> sendEncodings) { 92 this.direction = direction; 93 this.streamIds = new ArrayList<String>(streamIds); 94 this.sendEncodings = new ArrayList<RtpParameters.Encoding>(sendEncodings); 95 } 96 97 @CalledByNative("RtpTransceiverInit") getDirectionNativeIndex()98 int getDirectionNativeIndex() { 99 return direction.getNativeIndex(); 100 } 101 102 @CalledByNative("RtpTransceiverInit") getStreamIds()103 List<String> getStreamIds() { 104 return new ArrayList<String>(this.streamIds); 105 } 106 107 @CalledByNative("RtpTransceiverInit") getSendEncodings()108 List<RtpParameters.Encoding> getSendEncodings() { 109 return new ArrayList<RtpParameters.Encoding>(this.sendEncodings); 110 } 111 } 112 113 private long nativeRtpTransceiver; 114 private RtpSender cachedSender; 115 private RtpReceiver cachedReceiver; 116 117 @CalledByNative RtpTransceiver(long nativeRtpTransceiver)118 protected RtpTransceiver(long nativeRtpTransceiver) { 119 this.nativeRtpTransceiver = nativeRtpTransceiver; 120 cachedSender = nativeGetSender(nativeRtpTransceiver); 121 cachedReceiver = nativeGetReceiver(nativeRtpTransceiver); 122 } 123 124 /** 125 * Media type of the transceiver. Any sender(s)/receiver(s) will have this 126 * type as well. 127 */ getMediaType()128 public MediaStreamTrack.MediaType getMediaType() { 129 checkRtpTransceiverExists(); 130 return nativeGetMediaType(nativeRtpTransceiver); 131 } 132 133 /** 134 * The mid attribute is the mid negotiated and present in the local and 135 * remote descriptions. Before negotiation is complete, the mid value may be 136 * null. After rollbacks, the value may change from a non-null value to null. 137 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid 138 */ getMid()139 public String getMid() { 140 checkRtpTransceiverExists(); 141 return nativeGetMid(nativeRtpTransceiver); 142 } 143 144 /** 145 * The sender attribute exposes the RtpSender corresponding to the RTP media 146 * that may be sent with the transceiver's mid. The sender is always present, 147 * regardless of the direction of media. 148 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender 149 */ getSender()150 public RtpSender getSender() { 151 return cachedSender; 152 } 153 154 /** 155 * The receiver attribute exposes the RtpReceiver corresponding to the RTP 156 * media that may be received with the transceiver's mid. The receiver is 157 * always present, regardless of the direction of media. 158 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver 159 */ getReceiver()160 public RtpReceiver getReceiver() { 161 return cachedReceiver; 162 } 163 164 /** 165 * The stopped attribute indicates that the sender of this transceiver will no 166 * longer send, and that the receiver will no longer receive. It is true if 167 * either stop has been called or if setting the local or remote description 168 * has caused the RtpTransceiver to be stopped. 169 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped 170 */ isStopped()171 public boolean isStopped() { 172 checkRtpTransceiverExists(); 173 return nativeStopped(nativeRtpTransceiver); 174 } 175 176 /** 177 * The direction attribute indicates the preferred direction of this 178 * transceiver, which will be used in calls to CreateOffer and CreateAnswer. 179 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction 180 */ getDirection()181 public RtpTransceiverDirection getDirection() { 182 checkRtpTransceiverExists(); 183 return nativeDirection(nativeRtpTransceiver); 184 } 185 186 /** 187 * The current_direction attribute indicates the current direction negotiated 188 * for this transceiver. If this transceiver has never been represented in an 189 * offer/answer exchange, or if the transceiver is stopped, the value is null. 190 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection 191 */ getCurrentDirection()192 public RtpTransceiverDirection getCurrentDirection() { 193 checkRtpTransceiverExists(); 194 return nativeCurrentDirection(nativeRtpTransceiver); 195 } 196 197 /** 198 * Sets the preferred direction of this transceiver. An update of 199 * directionality does not take effect immediately. Instead, future calls to 200 * CreateOffer and CreateAnswer mark the corresponding media descriptions as 201 * sendrecv, sendonly, recvonly, or inactive. 202 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction 203 */ setDirection(RtpTransceiverDirection rtpTransceiverDirection)204 public boolean setDirection(RtpTransceiverDirection rtpTransceiverDirection) { 205 checkRtpTransceiverExists(); 206 return nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection); 207 } 208 209 /** 210 * The Stop method will for the time being call the StopInternal method. 211 * After a migration procedure, stop() will be equivalent to StopStandard. 212 */ stop()213 public void stop() { 214 checkRtpTransceiverExists(); 215 nativeStopInternal(nativeRtpTransceiver); 216 } 217 218 /** 219 * The StopInternal method stops the RtpTransceiver, like Stop, but goes 220 * immediately to Stopped state. 221 */ stopInternal()222 public void stopInternal() { 223 checkRtpTransceiverExists(); 224 nativeStopInternal(nativeRtpTransceiver); 225 } 226 227 /** 228 * The StopStandard method irreversibly stops the RtpTransceiver. The sender 229 * of this transceiver will no longer send, the receiver will no longer 230 * receive. 231 * 232 * <p>The transceiver will enter Stopping state and signal NegotiationNeeded. 233 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop 234 */ stopStandard()235 public void stopStandard() { 236 checkRtpTransceiverExists(); 237 nativeStopStandard(nativeRtpTransceiver); 238 } 239 240 @CalledByNative dispose()241 public void dispose() { 242 checkRtpTransceiverExists(); 243 cachedSender.dispose(); 244 cachedReceiver.dispose(); 245 JniCommon.nativeReleaseRef(nativeRtpTransceiver); 246 nativeRtpTransceiver = 0; 247 } 248 checkRtpTransceiverExists()249 private void checkRtpTransceiverExists() { 250 if (nativeRtpTransceiver == 0) { 251 throw new IllegalStateException("RtpTransceiver has been disposed."); 252 } 253 } 254 nativeGetMediaType(long rtpTransceiver)255 private static native MediaStreamTrack.MediaType nativeGetMediaType(long rtpTransceiver); nativeGetMid(long rtpTransceiver)256 private static native String nativeGetMid(long rtpTransceiver); nativeGetSender(long rtpTransceiver)257 private static native RtpSender nativeGetSender(long rtpTransceiver); nativeGetReceiver(long rtpTransceiver)258 private static native RtpReceiver nativeGetReceiver(long rtpTransceiver); nativeStopped(long rtpTransceiver)259 private static native boolean nativeStopped(long rtpTransceiver); nativeDirection(long rtpTransceiver)260 private static native RtpTransceiverDirection nativeDirection(long rtpTransceiver); nativeCurrentDirection(long rtpTransceiver)261 private static native RtpTransceiverDirection nativeCurrentDirection(long rtpTransceiver); nativeStopInternal(long rtpTransceiver)262 private static native void nativeStopInternal(long rtpTransceiver); nativeStopStandard(long rtpTransceiver)263 private static native void nativeStopStandard(long rtpTransceiver); nativeSetDirection( long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection)264 private static native boolean nativeSetDirection( 265 long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection); 266 } 267