webrtc_m130/sdk/android/api/org/webrtc/RtpTransceiver.java
Byoungchan Lee b244727265 [Android] Add RtcError class and use it in RtpTransceiver.setCodecPreferences
This CL modifies RtpTransceiver.setCodecPreferences to return RtcError
instead of void, making it easier to handle errors when setting
codec preferences. To achieve this, new RtcException and RtcError
classes are introduced to represent errors in WebRTC,
mimicking api/rtc_error.h in C++.

Bug: webrtc:42225493
Change-Id: I0f4c6e56f8f2af3353915a41084f6b7b46d793d4
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/352900
Reviewed-by: Zoé Lepaul <xalep@webrtc.org>
Commit-Queue: Zoé Lepaul <xalep@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42476}
2024-06-13 13:57:21 +00:00

274 lines
9.8 KiB
Java

/*
* 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.MediaStreamTrack;
import org.webrtc.RtpParameters;
/**
* 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
*/
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),
STOPPED(4);
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;
private final List<RtpParameters.Encoding> sendEncodings;
public RtpTransceiverInit() {
this(RtpTransceiverDirection.SEND_RECV);
}
public RtpTransceiverInit(RtpTransceiverDirection direction) {
this(direction, Collections.emptyList(), Collections.emptyList());
}
public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds) {
this(direction, streamIds, Collections.emptyList());
}
public RtpTransceiverInit(RtpTransceiverDirection direction, List<String> streamIds,
List<RtpParameters.Encoding> sendEncodings) {
this.direction = direction;
this.streamIds = new ArrayList<String>(streamIds);
this.sendEncodings = new ArrayList<RtpParameters.Encoding>(sendEncodings);
}
@CalledByNative("RtpTransceiverInit")
int getDirectionNativeIndex() {
return direction.getNativeIndex();
}
@CalledByNative("RtpTransceiverInit")
List<String> getStreamIds() {
return new ArrayList<String>(this.streamIds);
}
@CalledByNative("RtpTransceiverInit")
List<RtpParameters.Encoding> getSendEncodings() {
return new ArrayList<RtpParameters.Encoding>(this.sendEncodings);
}
}
private 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() {
checkRtpTransceiverExists();
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() {
checkRtpTransceiverExists();
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() {
checkRtpTransceiverExists();
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() {
checkRtpTransceiverExists();
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() {
checkRtpTransceiverExists();
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 boolean setDirection(RtpTransceiverDirection rtpTransceiverDirection) {
checkRtpTransceiverExists();
return nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection);
}
/**
* The Stop method will for the time being call the StopInternal method.
* After a migration procedure, stop() will be equivalent to StopStandard.
*/
public void stop() {
checkRtpTransceiverExists();
nativeStopInternal(nativeRtpTransceiver);
}
public RtcError setCodecPreferences(List<RtpCapabilities.CodecCapability> codecs) {
checkRtpTransceiverExists();
return nativeSetCodecPreferences(nativeRtpTransceiver, codecs);
}
/**
* The StopInternal method stops the RtpTransceiver, like Stop, but goes
* immediately to Stopped state.
*/
public void stopInternal() {
checkRtpTransceiverExists();
nativeStopInternal(nativeRtpTransceiver);
}
/**
* The StopStandard method irreversibly stops the RtpTransceiver. The sender
* of this transceiver will no longer send, the receiver will no longer
* receive.
*
* <p>The transceiver will enter Stopping state and signal NegotiationNeeded.
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
*/
public void stopStandard() {
checkRtpTransceiverExists();
nativeStopStandard(nativeRtpTransceiver);
}
@CalledByNative
public void dispose() {
checkRtpTransceiverExists();
cachedSender.dispose();
cachedReceiver.dispose();
JniCommon.nativeReleaseRef(nativeRtpTransceiver);
nativeRtpTransceiver = 0;
}
private void checkRtpTransceiverExists() {
if (nativeRtpTransceiver == 0) {
throw new IllegalStateException("RtpTransceiver has been disposed.");
}
}
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 nativeStopInternal(long rtpTransceiver);
private static native void nativeStopStandard(long rtpTransceiver);
private static native boolean nativeSetDirection(
long rtpTransceiver, RtpTransceiverDirection rtpTransceiverDirection);
private static native RtcError nativeSetCodecPreferences(
long rtpTransceiver, List<RtpCapabilities.CodecCapability> codecs);
}