Add new PeerConnection APIs to the Java SDK.
This adds wrappers to the following native APIs:
- SdpSemantics enum added to the RTCConfiguration
- RtpTransceiver
- PeerConnection.addTrack
- PeerConnection.removeTrack
- PeerConnection.addTransceiver
- PeerConnection.getTransceivers
These APIs are used with the new Unified Plan semantics.
Bug: webrtc:8869
Change-Id: I19443f3ff7ffc91a139ad8276331f09e57cec554
Reviewed-on: https://webrtc-review.googlesource.com/57800
Commit-Queue: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22317}
diff --git a/sdk/android/api/org/webrtc/MediaStream.java b/sdk/android/api/org/webrtc/MediaStream.java
index d66d844..e04fabd 100644
--- a/sdk/android/api/org/webrtc/MediaStream.java
+++ b/sdk/android/api/org/webrtc/MediaStream.java
@@ -88,13 +88,19 @@
JniCommon.nativeReleaseRef(nativeStream);
}
+ // TODO(shampson): Remove this when downstreams have moved to using id() instead.
+ @Deprecated
public String label() {
- return nativeGetLabel(nativeStream);
+ return nativeGetId(nativeStream);
+ }
+
+ public String getId() {
+ return nativeGetId(nativeStream);
}
@Override
public String toString() {
- return "[" + label() + ":A=" + audioTracks.size() + ":V=" + videoTracks.size() + "]";
+ return "[" + getId() + ":A=" + audioTracks.size() + ":V=" + videoTracks.size() + "]";
}
@CalledByNative
@@ -137,5 +143,5 @@
long stream, long nativeVideoTrack);
private static native boolean nativeRemoveAudioTrack(long stream, long nativeAudioTrack);
private static native boolean nativeRemoveVideoTrack(long stream, long nativeVideoTrack);
- private static native String nativeGetLabel(long stream);
+ private static native String nativeGetId(long stream);
}
diff --git a/sdk/android/api/org/webrtc/PeerConnection.java b/sdk/android/api/org/webrtc/PeerConnection.java
index de1e57d..603b36e 100644
--- a/sdk/android/api/org/webrtc/PeerConnection.java
+++ b/sdk/android/api/org/webrtc/PeerConnection.java
@@ -341,6 +341,33 @@
}
}
+ /**
+ * Java version of webrtc::SdpSemantics.
+ *
+ * Configure the SDP semantics used by this PeerConnection. Note that the
+ * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The
+ * RtpTransceiver API is only available with UNIFIED_PLAN semantics.
+ *
+ * <p>PLAN_B will cause PeerConnection to create offers and answers with at
+ * most one audio and one video m= section with multiple RtpSenders and
+ * RtpReceivers specified as multiple a=ssrc lines within the section. This
+ * will also cause PeerConnection to ignore all but the first m= section of
+ * the same media type.
+ *
+ * <p>UNIFIED_PLAN will cause PeerConnection to create offers and answers with
+ * multiple m= sections where each m= section maps to one RtpSender and one
+ * RtpReceiver (an RtpTransceiver), either both audio or both video. This
+ * will also cause PeerConnection to ignore all but the first a=ssrc lines
+ * that form a Plan B stream.
+ *
+ * <p>For users who wish to send multiple audio/video streams and need to stay
+ * interoperable with legacy WebRTC implementations, specify PLAN_B.
+ *
+ * <p>For users who wish to send multiple audio/video streams and/or wish to
+ * use the new RtpTransceiver API, specify UNIFIED_PLAN.
+ */
+ public enum SdpSemantics { PLAN_B, UNIFIED_PLAN }
+
/** Java version of PeerConnectionInterface.RTCConfiguration */
// TODO(qingsi): Resolve the naming inconsistency of fields with/without units.
public static class RTCConfiguration {
@@ -386,6 +413,7 @@
// Use "Unknown" to represent no preference of adapter types, not the
// preference of adapters of unknown types.
public AdapterType networkPreference;
+ public SdpSemantics sdpSemantics;
// This is an optional wrapper for the C++ webrtc::TurnCustomizer.
public TurnCustomizer turnCustomizer;
@@ -423,6 +451,7 @@
combinedAudioVideoBwe = null;
enableDtlsSrtp = null;
networkPreference = AdapterType.UNKNOWN;
+ sdpSemantics = SdpSemantics.PLAN_B;
}
@CalledByNative("RTCConfiguration")
@@ -574,12 +603,18 @@
AdapterType getNetworkPreference() {
return networkPreference;
}
+
+ @CalledByNative("RTCConfiguration")
+ SdpSemantics getSdpSemantics() {
+ return sdpSemantics;
+ }
};
private final List<MediaStream> localStreams = new ArrayList<>();
private final long nativePeerConnection;
private List<RtpSender> senders = new ArrayList<>();
private List<RtpReceiver> receivers = new ArrayList<>();
+ private List<RtpTransceiver> transceivers = new ArrayList<>();
/**
* Wraps a PeerConnection created by the factory. Can be used by clients that want to implement
@@ -622,18 +657,24 @@
nativeSetRemoteDescription(observer, sdp);
}
- // True if remote audio should be played out. Defaults to true.
- // Note that even if playout is enabled, streams will only be played out if
- // the appropriate SDP is also applied. The main purpose of this API is to
- // be able to control the exact time when audio playout starts.
+ /**
+ * Enables/disables playout of received audio streams. Enabled by default.
+ *
+ * Note that even if playout is enabled, streams will only be played out if
+ * the appropriate SDP is also applied. The main purpose of this API is to
+ * be able to control the exact time when audio playout starts.
+ */
public void setAudioPlayout(boolean playout) {
nativeSetAudioPlayout(playout);
}
- // True if local audio shall be recorded. Defaults to true.
- // Note that even if recording is enabled, streams will only be recorded if
- // the appropriate SDP is also applied. The main purpose of this API is to
- // be able to control the exact time when audio recording starts.
+ /**
+ * Enables/disables recording of transmitted audio streams. Enabled by default.
+ *
+ * Note that even if recording is enabled, streams will only be recorded if
+ * the appropriate SDP is also applied. The main purpose of this API is to
+ * be able to control the exact time when audio recording starts.
+ */
public void setAudioRecording(boolean recording) {
nativeSetAudioRecording(recording);
}
@@ -650,6 +691,11 @@
return nativeRemoveIceCandidates(candidates);
}
+ /**
+ * Adds a new MediaStream to be sent on this peer connection.
+ * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please
+ * use addTrack instead.
+ */
public boolean addStream(MediaStream stream) {
boolean ret = nativeAddLocalStream(stream.nativeStream);
if (!ret) {
@@ -659,6 +705,11 @@
return true;
}
+ /**
+ * Removes the given media stream from this peer connection.
+ * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use
+ * removeTrack instead.
+ */
public void removeStream(MediaStream stream) {
nativeRemoveLocalStream(stream.nativeStream);
localStreams.remove(stream);
@@ -666,15 +717,15 @@
/**
* Creates an RtpSender without a track.
- * <p>
- * This method allows an application to cause the PeerConnection to negotiate
+ *
+ * <p>This method allows an application to cause the PeerConnection to negotiate
* sending/receiving a specific media type, but without having a track to
* send yet.
- * <p>
- * When the application does want to begin sending a track, it can call
+ *
+ * <p>When the application does want to begin sending a track, it can call
* RtpSender.setTrack, which doesn't require any additional SDP negotiation.
- * <p>
- * Example use:
+ *
+ * <p>Example use:
* <pre>
* {@code
* audioSender = pc.createSender("audio", "stream1");
@@ -686,12 +737,15 @@
* videoSender.setTrack(videoTrack, false);
* }
* </pre>
- * Note: This corresponds most closely to "addTransceiver" in the official
+ * <p>Note: This corresponds most closely to "addTransceiver" in the official
* WebRTC API, in that it creates a sender without a track. It was
* implemented before addTransceiver because it provides useful
* functionality, and properly implementing transceivers would have required
* a great deal more work.
*
+ * <p>Note: This is only available with SdpSemantics.PLAN_B specified. Please use
+ * addTransceiver instead.
+ *
* @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or
* "video").
* @param stream_id The ID of the MediaStream that this sender's track will
@@ -702,15 +756,18 @@
* @return A new RtpSender object if successful, or null otherwise.
*/
public RtpSender createSender(String kind, String stream_id) {
- RtpSender new_sender = nativeCreateSender(kind, stream_id);
- if (new_sender != null) {
- senders.add(new_sender);
+ RtpSender newSender = nativeCreateSender(kind, stream_id);
+ if (newSender != null) {
+ senders.add(newSender);
}
- return new_sender;
+ return newSender;
}
- // Note that calling getSenders will dispose of the senders previously
- // returned (and same goes for getReceivers).
+ /**
+ * Gets all RtpSenders associated with this peer connection.
+ * Note that calling getSenders will dispose of the senders previously
+ * returned.
+ */
public List<RtpSender> getSenders() {
for (RtpSender sender : senders) {
sender.dispose();
@@ -719,6 +776,11 @@
return Collections.unmodifiableList(senders);
}
+ /**
+ * Gets all RtpReceivers associated with this peer connection.
+ * Note that calling getReceivers will dispose of the receivers previously
+ * returned.
+ */
public List<RtpReceiver> getReceivers() {
for (RtpReceiver receiver : receivers) {
receiver.dispose();
@@ -727,35 +789,162 @@
return Collections.unmodifiableList(receivers);
}
+ /**
+ * Gets all RtpTransceivers associated with this peer connection.
+ * Note that calling getTransceivers will dispose of the transceivers previously
+ * returned.
+ * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified.
+ */
+ public List<RtpTransceiver> getTransceivers() {
+ for (RtpTransceiver transceiver : transceivers) {
+ transceiver.dispose();
+ }
+ transceivers = nativeGetTransceivers();
+ return Collections.unmodifiableList(transceivers);
+ }
+
+ /**
+ * Adds a new media stream track to be sent on this peer connection, and returns
+ * the newly created RtpSender. If streamIds are specified, the RtpSender will
+ * be associated with the streams specified in the streamIds list.
+ *
+ * @throws IllegalStateException if an error accors in C++ addTrack.
+ * An error can occur if:
+ * - A sender already exists for the track.
+ * - The peer connection is closed.
+ */
+ public RtpSender addTrack(MediaStreamTrack track) {
+ return addTrack(track, Collections.emptyList());
+ }
+
+ public RtpSender addTrack(MediaStreamTrack track, List<String> streamIds) {
+ if (track == null || streamIds == null) {
+ throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
+ }
+ RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds);
+ if (newSender == null) {
+ throw new IllegalStateException("C++ addTrack failed.");
+ }
+ senders.add(newSender);
+ return newSender;
+ }
+
+ /**
+ * Stops sending media from sender. The sender will still appear in getSenders. Future
+ * calls to createOffer will mark the m section for the corresponding transceiver as
+ * receive only or inactive, as defined in JSEP. Returns true on success.
+ */
+ public boolean removeTrack(RtpSender sender) {
+ if (sender == null) {
+ throw new NullPointerException("No RtpSender specified for removeTrack.");
+ }
+ return nativeRemoveTrack(sender.nativeRtpSender);
+ }
+
+ /**
+ * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a
+ * transceiver will cause future calls to CreateOffer to add a media description
+ * for the corresponding transceiver.
+ *
+ * <p>The initial value of |mid| in the returned transceiver is null. Setting a
+ * new session description may change it to a non-null value.
+ *
+ * <p>https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver
+ *
+ * <p>If a MediaStreamTrack is specified then a transceiver will be added with a
+ * sender set to transmit the given track. The kind
+ * of the transceiver (and sender/receiver) will be derived from the kind of
+ * the track.
+ *
+ * <p>If MediaType is specified then a transceiver will be added based upon that type.
+ * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO.
+ *
+ * <p>Optionally, an RtpTransceiverInit structure can be specified to configure
+ * the transceiver from construction. If not specified, the transceiver will
+ * default to having a direction of kSendRecv and not be part of any streams.
+ *
+ * <p>Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified.
+ * @throws IllegalStateException if an error accors in C++ addTransceiver
+ */
+ public RtpTransceiver addTransceiver(MediaStreamTrack track) {
+ return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit());
+ }
+
+ public RtpTransceiver addTransceiver(
+ MediaStreamTrack track, RtpTransceiver.RtpTransceiverInit init) {
+ if (track == null) {
+ throw new NullPointerException("No MediaStreamTrack specified for addTransceiver.");
+ }
+ if (init == null) {
+ init = new RtpTransceiver.RtpTransceiverInit();
+ }
+ RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init);
+ if (newTransceiver == null) {
+ throw new IllegalStateException("C++ addTransceiver failed.");
+ }
+ transceivers.add(newTransceiver);
+ return newTransceiver;
+ }
+
+ public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) {
+ return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit());
+ }
+
+ public RtpTransceiver addTransceiver(
+ MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init) {
+ if (mediaType == null) {
+ throw new NullPointerException("No MediaType specified for addTransceiver.");
+ }
+ if (init == null) {
+ init = new RtpTransceiver.RtpTransceiverInit();
+ }
+ RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init);
+ if (newTransceiver == null) {
+ throw new IllegalStateException("C++ addTransceiver failed.");
+ }
+ transceivers.add(newTransceiver);
+ return newTransceiver;
+ }
+
// Older, non-standard implementation of getStats.
@Deprecated
public boolean getStats(StatsObserver observer, MediaStreamTrack track) {
return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
}
- // Gets stats using the new stats collection API, see webrtc/api/stats/. These
- // will replace old stats collection API when the new API has matured enough.
+ /**
+ * Gets stats using the new stats collection API, see webrtc/api/stats/. These
+ * will replace old stats collection API when the new API has matured enough.
+ */
public void getStats(RTCStatsCollectorCallback callback) {
nativeNewGetStats(callback);
}
- // Limits the bandwidth allocated for all RTP streams sent by this
- // PeerConnection. Pass null to leave a value unchanged.
+ /**
+ * Limits the bandwidth allocated for all RTP streams sent by this
+ * PeerConnection. Pass null to leave a value unchanged.
+ */
public boolean setBitrate(Integer min, Integer current, Integer max) {
return nativeSetBitrate(min, current, max);
}
- // Starts recording an RTC event log. Ownership of the file is transfered to
- // the native code. If an RTC event log is already being recorded, it will be
- // stopped and a new one will start using the provided file. Logging will
- // continue until the stopRtcEventLog function is called. The max_size_bytes
- // argument is ignored, it is added for future use.
+ /**
+ * Starts recording an RTC event log.
+ *
+ * Ownership of the file is transfered to the native code. If an RTC event
+ * log is already being recorded, it will be stopped and a new one will start
+ * using the provided file. Logging will continue until the stopRtcEventLog
+ * function is called. The max_size_bytes argument is ignored, it is added
+ * for future use.
+ */
public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) {
return nativeStartRtcEventLog(file_descriptor, max_size_bytes);
}
- // Stops recording an RTC event log. If no RTC event log is currently being
- // recorded, this call will have no effect.
+ /**
+ * Stops recording an RTC event log. If no RTC event log is currently being
+ * recorded, this call will have no effect.
+ */
public void stopRtcEventLog() {
nativeStopRtcEventLog();
}
@@ -780,14 +969,14 @@
/**
* Free native resources associated with this PeerConnection instance.
- * <p>
+ *
* This method removes a reference count from the C++ PeerConnection object,
* which should result in it being destroyed. It also calls equivalent
* "dispose" methods on the Java objects attached to this PeerConnection
* (streams, senders, receivers), such that their associated C++ objects
* will also be destroyed.
- * <p>
- * Note that this method cannot be safely called from an observer callback
+ *
+ * <p>Note that this method cannot be safely called from an observer callback
* (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for
* example, destroy the PeerConnection after an "ICE failed" callback, you
* must do this asynchronously (in other words, unwind the stack first). See
@@ -808,6 +997,10 @@
for (RtpReceiver receiver : receivers) {
receiver.dispose();
}
+ for (RtpTransceiver transceiver : transceivers) {
+ transceiver.dispose();
+ }
+ transceivers.clear();
receivers.clear();
nativeFreeOwnedPeerConnection(nativePeerConnection);
}
@@ -854,6 +1047,13 @@
private native RtpSender nativeCreateSender(String kind, String stream_id);
private native List<RtpSender> nativeGetSenders();
private native List<RtpReceiver> nativeGetReceivers();
+ private native List<RtpTransceiver> nativeGetTransceivers();
+ private native RtpSender nativeAddTrack(long track, List<String> streamIds);
+ private native boolean nativeRemoveTrack(long sender);
+ private native RtpTransceiver nativeAddTransceiverWithTrack(
+ long track, RtpTransceiver.RtpTransceiverInit init);
+ private native RtpTransceiver nativeAddTransceiverOfType(
+ MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init);
private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
private native void nativeStopRtcEventLog();
}
diff --git a/sdk/android/api/org/webrtc/RtpTransceiver.java b/sdk/android/api/org/webrtc/RtpTransceiver.java
new file mode 100644
index 0000000..d77ecb4
--- /dev/null
+++ b/sdk/android/api/org/webrtc/RtpTransceiver.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2018 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+package org.webrtc;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.webrtc.RtpParameters.Encoding;
+
+/**
+ * Java wrapper for a C++ RtpTransceiverInterface.
+ *
+ * <p>The RTCRtpTransceiver maps to the RTCRtpTransceiver defined by the WebRTC
+ * specification. A transceiver represents a combination of an RTCRtpSender
+ * and an RTCRtpReceiver that share a common mid. As defined in JSEP, an
+ * RTCRtpTransceiver is said to be associated with a media description if its
+ * mid property is non-nil; otherwise, it is said to be disassociated.
+ * JSEP: https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-24
+ *
+ * <p>Note that RTCRtpTransceivers are only supported when using
+ * RTCPeerConnection with Unified Plan SDP.
+ *
+ * <p>WebRTC specification for RTCRtpTransceiver, the JavaScript analog:
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver
+ */
+@JNINamespace("webrtc::jni")
+public class RtpTransceiver {
+ /** Java version of webrtc::RtpTransceiverDirection - the ordering must be kept in sync. */
+ public enum RtpTransceiverDirection {
+ SEND_RECV(0),
+ SEND_ONLY(1),
+ RECV_ONLY(2),
+ INACTIVE(3);
+
+ private final int nativeIndex;
+
+ private RtpTransceiverDirection(int nativeIndex) {
+ this.nativeIndex = nativeIndex;
+ }
+
+ @CalledByNative("RtpTransceiverDirection")
+ int getNativeIndex() {
+ return nativeIndex;
+ }
+
+ @CalledByNative("RtpTransceiverDirection")
+ static RtpTransceiverDirection fromNativeIndex(int nativeIndex) {
+ for (RtpTransceiverDirection type : RtpTransceiverDirection.values()) {
+ if (type.getNativeIndex() == nativeIndex) {
+ return type;
+ }
+ }
+ throw new IllegalArgumentException(
+ "Uknown native RtpTransceiverDirection type" + nativeIndex);
+ }
+ }
+
+ /**
+ * Tracks webrtc::RtpTransceiverInit. https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiverinit
+ * A structure for initializing an RtpTransceiver in a call to addTransceiver.
+ * Note: This does not contain a list of encoding parameters, because they are currently
+ * not being used natively.
+ */
+ public static final class RtpTransceiverInit {
+ private final RtpTransceiverDirection direction;
+ private final List<String> streamIds;
+
+ public RtpTransceiverInit() {
+ this(RtpTransceiverDirection.SEND_RECV);
+ }
+
+ public RtpTransceiverInit(RtpTransceiverDirection direction) {
+ this(direction, Collections.emptyList());
+ }
+
+ public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds) {
+ this.direction = direction;
+ this.streamIds = new ArrayList<String>(streamIds);
+ }
+
+ @CalledByNative("RtpTransceiverInit")
+ int getDirectionNativeIndex() {
+ return direction.getNativeIndex();
+ }
+
+ @CalledByNative("RtpTransceiverInit")
+ List<String> getStreamIds() {
+ return new ArrayList<String>(this.streamIds);
+ }
+ }
+
+ private final long nativeRtpTransceiver;
+ private RtpSender cachedSender;
+ private RtpReceiver cachedReceiver;
+
+ @CalledByNative
+ protected RtpTransceiver(long nativeRtpTransceiver) {
+ this.nativeRtpTransceiver = nativeRtpTransceiver;
+ cachedSender = nativeGetSender(nativeRtpTransceiver);
+ cachedReceiver = nativeGetReceiver(nativeRtpTransceiver);
+ }
+
+ /**
+ * Media type of the transceiver. Any sender(s)/receiver(s) will have this
+ * type as well.
+ */
+ public MediaStreamTrack.MediaType getMediaType() {
+ return nativeGetMediaType(nativeRtpTransceiver);
+ }
+
+ /**
+ * The mid attribute is the mid negotiated and present in the local and
+ * remote descriptions. Before negotiation is complete, the mid value may be
+ * null. After rollbacks, the value may change from a non-null value to null.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
+ */
+ public String getMid() {
+ return nativeGetMid(nativeRtpTransceiver);
+ }
+
+ /**
+ * The sender attribute exposes the RtpSender corresponding to the RTP media
+ * that may be sent with the transceiver's mid. The sender is always present,
+ * regardless of the direction of media.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-sender
+ */
+ public RtpSender getSender() {
+ return cachedSender;
+ }
+
+ /**
+ * The receiver attribute exposes the RtpReceiver corresponding to the RTP
+ * media that may be received with the transceiver's mid. The receiver is
+ * always present, regardless of the direction of media.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-receiver
+ */
+ public RtpReceiver getReceiver() {
+ return cachedReceiver;
+ }
+
+ /**
+ * The stopped attribute indicates that the sender of this transceiver will no
+ * longer send, and that the receiver will no longer receive. It is true if
+ * either stop has been called or if setting the local or remote description
+ * has caused the RtpTransceiver to be stopped.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped
+ */
+ public boolean isStopped() {
+ return nativeStopped(nativeRtpTransceiver);
+ }
+
+ /**
+ * The direction attribute indicates the preferred direction of this
+ * transceiver, which will be used in calls to CreateOffer and CreateAnswer.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
+ */
+ public RtpTransceiverDirection getDirection() {
+ return nativeDirection(nativeRtpTransceiver);
+ }
+
+ /**
+ * The current_direction attribute indicates the current direction negotiated
+ * for this transceiver. If this transceiver has never been represented in an
+ * offer/answer exchange, or if the transceiver is stopped, the value is null.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
+ */
+ public RtpTransceiverDirection getCurrentDirection() {
+ return nativeCurrentDirection(nativeRtpTransceiver);
+ }
+
+ /**
+ * Sets the preferred direction of this transceiver. An update of
+ * directionality does not take effect immediately. Instead, future calls to
+ * CreateOffer and CreateAnswer mark the corresponding media descriptions as
+ * sendrecv, sendonly, recvonly, or inactive.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
+ */
+ public void setDirection(RtpTransceiverDirection rtpTransceiverDirection) {
+ nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection);
+ }
+
+ /**
+ * The Stop method irreversibly stops the RtpTransceiver. The sender of this
+ * transceiver will no longer send, the receiver will no longer receive.
+ * https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
+ */
+ public void stop() {
+ nativeStop(nativeRtpTransceiver);
+ }
+
+ public void dispose() {
+ cachedSender.dispose();
+ cachedReceiver.dispose();
+ JniCommon.nativeReleaseRef(nativeRtpTransceiver);
+ }
+
+ private static native MediaStreamTrack.MediaType nativeGetMediaType(long rtpTransceiver);
+ private static native String nativeGetMid(long rtpTransceiver);
+ private static native RtpSender nativeGetSender(long rtpTransceiver);
+ private static native RtpReceiver nativeGetReceiver(long rtpTransceiver);
+ private static native boolean nativeStopped(long rtpTransceiver);
+ private static native RtpTransceiverDirection nativeDirection(long rtpTransceiver);
+ private static native RtpTransceiverDirection nativeCurrentDirection(long rtpTransceiver);
+ private static native void nativeStop(long rtpTransceiver);
+ private static native void nativeSetDirection(
+ long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection);
+}