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 43 private final int nativeIndex; 44 RtpTransceiverDirection(int nativeIndex)45 private RtpTransceiverDirection(int nativeIndex) { 46 this.nativeIndex = nativeIndex; 47 } 48 49 @CalledByNative("RtpTransceiverDirection") getNativeIndex()50 int getNativeIndex() { 51 return nativeIndex; 52 } 53 54 @CalledByNative("RtpTransceiverDirection") fromNativeIndex(int nativeIndex)55 static RtpTransceiverDirection fromNativeIndex(int nativeIndex) { 56 for (RtpTransceiverDirection type : RtpTransceiverDirection.values()) { 57 if (type.getNativeIndex() == nativeIndex) { 58 return type; 59 } 60 } 61 throw new IllegalArgumentException( 62 "Uknown native RtpTransceiverDirection type" + nativeIndex); 63 } 64 } 65 66 /** 67 * Tracks webrtc::RtpTransceiverInit. https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit 68 * A structure for initializing an RtpTransceiver in a call to addTransceiver. 69 * Note: This does not contain a list of encoding parameters, because they are currently 70 * not being used natively. 71 */ 72 public static final class RtpTransceiverInit { 73 private final RtpTransceiverDirection direction; 74 private final List<String> streamIds; 75 private final List<RtpParameters.Encoding> sendEncodings; 76 RtpTransceiverInit()77 public RtpTransceiverInit() { 78 this(RtpTransceiverDirection.SEND_RECV); 79 } 80 RtpTransceiverInit(RtpTransceiverDirection direction)81 public RtpTransceiverInit(RtpTransceiverDirection direction) { 82 this(direction, Collections.emptyList(), Collections.emptyList()); 83 } 84 RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds)85 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds) { 86 this(direction, streamIds, Collections.emptyList()); 87 } 88 RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds, List<RtpParameters.Encoding> sendEncodings)89 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds, 90 List<RtpParameters.Encoding> sendEncodings) { 91 this.direction = direction; 92 this.streamIds = new ArrayList<String>(streamIds); 93 this.sendEncodings = new ArrayList<RtpParameters.Encoding>(sendEncodings); 94 } 95 96 @CalledByNative("RtpTransceiverInit") getDirectionNativeIndex()97 int getDirectionNativeIndex() { 98 return direction.getNativeIndex(); 99 } 100 101 @CalledByNative("RtpTransceiverInit") getStreamIds()102 List<String> getStreamIds() { 103 return new ArrayList<String>(this.streamIds); 104 } 105 106 @CalledByNative("RtpTransceiverInit") getSendEncodings()107 List<RtpParameters.Encoding> getSendEncodings() { 108 return new ArrayList<RtpParameters.Encoding>(this.sendEncodings); 109 } 110 } 111 112 private long nativeRtpTransceiver; 113 private RtpSender cachedSender; 114 private RtpReceiver cachedReceiver; 115 116 @CalledByNative RtpTransceiver(long nativeRtpTransceiver)117 protected RtpTransceiver(long nativeRtpTransceiver) { 118 this.nativeRtpTransceiver = nativeRtpTransceiver; 119 cachedSender = nativeGetSender(nativeRtpTransceiver); 120 cachedReceiver = nativeGetReceiver(nativeRtpTransceiver); 121 } 122 123 /** 124 * Media type of the transceiver. Any sender(s)/receiver(s) will have this 125 * type as well. 126 */ getMediaType()127 public MediaStreamTrack.MediaType getMediaType() { 128 checkRtpTransceiverExists(); 129 return nativeGetMediaType(nativeRtpTransceiver); 130 } 131 132 /** 133 * The mid attribute is the mid negotiated and present in the local and 134 * remote descriptions. Before negotiation is complete, the mid value may be 135 * null. After rollbacks, the value may change from a non-null value to null. 136 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid 137 */ getMid()138 public String getMid() { 139 checkRtpTransceiverExists(); 140 return nativeGetMid(nativeRtpTransceiver); 141 } 142 143 /** 144 * The sender attribute exposes the RtpSender corresponding to the RTP media 145 * that may be sent with the transceiver's mid. The sender is always present, 146 * regardless of the direction of media. 147 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender 148 */ getSender()149 public RtpSender getSender() { 150 return cachedSender; 151 } 152 153 /** 154 * The receiver attribute exposes the RtpReceiver corresponding to the RTP 155 * media that may be received with the transceiver's mid. The receiver is 156 * always present, regardless of the direction of media. 157 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver 158 */ getReceiver()159 public RtpReceiver getReceiver() { 160 return cachedReceiver; 161 } 162 163 /** 164 * The stopped attribute indicates that the sender of this transceiver will no 165 * longer send, and that the receiver will no longer receive. It is true if 166 * either stop has been called or if setting the local or remote description 167 * has caused the RtpTransceiver to be stopped. 168 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped 169 */ isStopped()170 public boolean isStopped() { 171 checkRtpTransceiverExists(); 172 return nativeStopped(nativeRtpTransceiver); 173 } 174 175 /** 176 * The direction attribute indicates the preferred direction of this 177 * transceiver, which will be used in calls to CreateOffer and CreateAnswer. 178 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction 179 */ getDirection()180 public RtpTransceiverDirection getDirection() { 181 checkRtpTransceiverExists(); 182 return nativeDirection(nativeRtpTransceiver); 183 } 184 185 /** 186 * The current_direction attribute indicates the current direction negotiated 187 * for this transceiver. If this transceiver has never been represented in an 188 * offer/answer exchange, or if the transceiver is stopped, the value is null. 189 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection 190 */ getCurrentDirection()191 public RtpTransceiverDirection getCurrentDirection() { 192 checkRtpTransceiverExists(); 193 return nativeCurrentDirection(nativeRtpTransceiver); 194 } 195 196 /** 197 * Sets the preferred direction of this transceiver. An update of 198 * directionality does not take effect immediately. Instead, future calls to 199 * CreateOffer and CreateAnswer mark the corresponding media descriptions as 200 * sendrecv, sendonly, recvonly, or inactive. 201 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction 202 */ setDirection(RtpTransceiverDirection rtpTransceiverDirection)203 public void setDirection(RtpTransceiverDirection rtpTransceiverDirection) { 204 checkRtpTransceiverExists(); 205 nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection); 206 } 207 208 /** 209 * The Stop method irreversibly stops the RtpTransceiver. The sender of this 210 * transceiver will no longer send, the receiver will no longer receive. 211 * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop 212 */ stop()213 public void stop() { 214 checkRtpTransceiverExists(); 215 nativeStop(nativeRtpTransceiver); 216 } 217 218 @CalledByNative dispose()219 public void dispose() { 220 checkRtpTransceiverExists(); 221 cachedSender.dispose(); 222 cachedReceiver.dispose(); 223 JniCommon.nativeReleaseRef(nativeRtpTransceiver); 224 nativeRtpTransceiver = 0; 225 } 226 checkRtpTransceiverExists()227 private void checkRtpTransceiverExists() { 228 if (nativeRtpTransceiver == 0) { 229 throw new IllegalStateException("RtpTransceiver has been disposed."); 230 } 231 } 232 nativeGetMediaType(long rtpTransceiver)233 private static native MediaStreamTrack.MediaType nativeGetMediaType(long rtpTransceiver); nativeGetMid(long rtpTransceiver)234 private static native String nativeGetMid(long rtpTransceiver); nativeGetSender(long rtpTransceiver)235 private static native RtpSender nativeGetSender(long rtpTransceiver); nativeGetReceiver(long rtpTransceiver)236 private static native RtpReceiver nativeGetReceiver(long rtpTransceiver); nativeStopped(long rtpTransceiver)237 private static native boolean nativeStopped(long rtpTransceiver); nativeDirection(long rtpTransceiver)238 private static native RtpTransceiverDirection nativeDirection(long rtpTransceiver); nativeCurrentDirection(long rtpTransceiver)239 private static native RtpTransceiverDirection nativeCurrentDirection(long rtpTransceiver); nativeStop(long rtpTransceiver)240 private static native void nativeStop(long rtpTransceiver); nativeSetDirection( long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection)241 private static native void nativeSetDirection( 242 long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection); 243 } 244