blob: 1102bd7eb1e5426c3cca9475154279c515b75c9a [file] [log] [blame]
Seth Hampsonc384e142018-03-06 15:47:10 -08001/*
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
11package org.webrtc;
12
13import java.util.ArrayList;
14import java.util.Collections;
15import java.util.List;
Patrik Höglundbd6ffaf2018-11-16 14:55:16 +010016import org.webrtc.MediaStreamTrack;
Amit Hilbuchae4b6232019-03-29 14:02:42 -070017import org.webrtc.RtpParameters;
Seth Hampsonc384e142018-03-06 15:47:10 -080018
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 */
Seth Hampsonc384e142018-03-06 15:47:10 -080035public 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),
Saúl Ibarra Corretgé043a8032022-08-04 15:28:03 +020041 INACTIVE(3),
42 STOPPED(4);
Seth Hampsonc384e142018-03-06 15:47:10 -080043
44 private final int nativeIndex;
45
46 private RtpTransceiverDirection(int nativeIndex) {
47 this.nativeIndex = nativeIndex;
48 }
49
50 @CalledByNative("RtpTransceiverDirection")
51 int getNativeIndex() {
52 return nativeIndex;
53 }
54
55 @CalledByNative("RtpTransceiverDirection")
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;
Amit Hilbuchae4b6232019-03-29 14:02:42 -070076 private final List<RtpParameters.Encoding> sendEncodings;
Seth Hampsonc384e142018-03-06 15:47:10 -080077
78 public RtpTransceiverInit() {
79 this(RtpTransceiverDirection.SEND_RECV);
80 }
81
82 public RtpTransceiverInit(RtpTransceiverDirection direction) {
Amit Hilbuchae4b6232019-03-29 14:02:42 -070083 this(direction, Collections.emptyList(), Collections.emptyList());
Seth Hampsonc384e142018-03-06 15:47:10 -080084 }
85
86 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds) {
Amit Hilbuchae4b6232019-03-29 14:02:42 -070087 this(direction, streamIds, Collections.emptyList());
88 }
89
90 public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds,
91 List<RtpParameters.Encoding> sendEncodings) {
Seth Hampsonc384e142018-03-06 15:47:10 -080092 this.direction = direction;
93 this.streamIds = new ArrayList<String>(streamIds);
Amit Hilbuchae4b6232019-03-29 14:02:42 -070094 this.sendEncodings = new ArrayList<RtpParameters.Encoding>(sendEncodings);
Seth Hampsonc384e142018-03-06 15:47:10 -080095 }
96
97 @CalledByNative("RtpTransceiverInit")
98 int getDirectionNativeIndex() {
99 return direction.getNativeIndex();
100 }
101
102 @CalledByNative("RtpTransceiverInit")
103 List<String> getStreamIds() {
104 return new ArrayList<String>(this.streamIds);
105 }
Amit Hilbuchae4b6232019-03-29 14:02:42 -0700106
107 @CalledByNative("RtpTransceiverInit")
108 List<RtpParameters.Encoding> getSendEncodings() {
109 return new ArrayList<RtpParameters.Encoding>(this.sendEncodings);
110 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800111 }
112
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200113 private long nativeRtpTransceiver;
Seth Hampsonc384e142018-03-06 15:47:10 -0800114 private RtpSender cachedSender;
115 private RtpReceiver cachedReceiver;
116
117 @CalledByNative
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 */
128 public MediaStreamTrack.MediaType getMediaType() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200129 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800130 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 */
139 public String getMid() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200140 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800141 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 */
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 */
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 */
171 public boolean isStopped() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200172 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800173 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 */
181 public RtpTransceiverDirection getDirection() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200182 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800183 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 */
192 public RtpTransceiverDirection getCurrentDirection() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200193 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800194 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 */
Harald Alvestrand7f8b4342020-08-17 12:57:30 +0200204 public boolean setDirection(RtpTransceiverDirection rtpTransceiverDirection) {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200205 checkRtpTransceiverExists();
Harald Alvestrand7f8b4342020-08-17 12:57:30 +0200206 return nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection);
Seth Hampsonc384e142018-03-06 15:47:10 -0800207 }
208
209 /**
Harald Alvestrand6060df52020-08-11 09:54:02 +0200210 * The Stop method will for the time being call the StopInternal method.
211 * After a migration procedure, stop() will be equivalent to StopStandard.
Seth Hampsonc384e142018-03-06 15:47:10 -0800212 */
213 public void stop() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200214 checkRtpTransceiverExists();
Harald Alvestrand6060df52020-08-11 09:54:02 +0200215 nativeStopInternal(nativeRtpTransceiver);
216 }
217
218 /**
219 * The StopInternal method stops the RtpTransceiver, like Stop, but goes
220 * immediately to Stopped state.
221 */
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 */
235 public void stopStandard() {
236 checkRtpTransceiverExists();
237 nativeStopStandard(nativeRtpTransceiver);
Seth Hampsonc384e142018-03-06 15:47:10 -0800238 }
239
Seth Hampson31dbc242018-05-07 09:28:19 -0700240 @CalledByNative
Seth Hampsonc384e142018-03-06 15:47:10 -0800241 public void dispose() {
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200242 checkRtpTransceiverExists();
Seth Hampsonc384e142018-03-06 15:47:10 -0800243 cachedSender.dispose();
244 cachedReceiver.dispose();
245 JniCommon.nativeReleaseRef(nativeRtpTransceiver);
Sami Kalliomäkiee05e902018-09-28 14:38:21 +0200246 nativeRtpTransceiver = 0;
247 }
248
249 private void checkRtpTransceiverExists() {
250 if (nativeRtpTransceiver == 0) {
251 throw new IllegalStateException("RtpTransceiver has been disposed.");
252 }
Seth Hampsonc384e142018-03-06 15:47:10 -0800253 }
254
255 private static native MediaStreamTrack.MediaType nativeGetMediaType(long rtpTransceiver);
256 private static native String nativeGetMid(long rtpTransceiver);
257 private static native RtpSender nativeGetSender(long rtpTransceiver);
258 private static native RtpReceiver nativeGetReceiver(long rtpTransceiver);
259 private static native boolean nativeStopped(long rtpTransceiver);
260 private static native RtpTransceiverDirection nativeDirection(long rtpTransceiver);
261 private static native RtpTransceiverDirection nativeCurrentDirection(long rtpTransceiver);
Harald Alvestrand6060df52020-08-11 09:54:02 +0200262 private static native void nativeStopInternal(long rtpTransceiver);
263 private static native void nativeStopStandard(long rtpTransceiver);
Harald Alvestrand7f8b4342020-08-17 12:57:30 +0200264 private static native boolean nativeSetDirection(
Seth Hampsonc384e142018-03-06 15:47:10 -0800265 long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection);
266}