Throw IllegalStateException if native objects are used after dispose.
This makes it easier to debug issues related to double dispose / use after dispose. Bug: webrtc:7566, webrtc:8297 Change-Id: I07429b2b794deabb62b5f3ea1cf92eea6f66a149 Reviewed-on: https://webrtc-review.googlesource.com/102540 Commit-Queue: Sami Kalliomäki <sakal@webrtc.org> Reviewed-by: Paulina Hensman <phensman@webrtc.org> Cr-Commit-Position: refs/heads/master@{#24894}
This commit is contained in:

committed by
Commit Bot

parent
dca5a2ca73
commit
ee05e90297
@ -18,4 +18,9 @@ public class AudioSource extends MediaSource {
|
||||
public AudioSource(long nativeSource) {
|
||||
super(nativeSource);
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::AudioSourceInterface. */
|
||||
long getNativeAudioSource() {
|
||||
return getNativeMediaSource();
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,12 @@ public class AudioTrack extends MediaStreamTrack {
|
||||
* 0 to 10.
|
||||
*/
|
||||
public void setVolume(double volume) {
|
||||
nativeSetVolume(super.nativeTrack, volume);
|
||||
nativeSetVolume(getNativeAudioTrack(), volume);
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::AudioTrackInterface. */
|
||||
long getNativeAudioTrack() {
|
||||
return getNativeMediaStreamTrack();
|
||||
}
|
||||
|
||||
private static native void nativeSetVolume(long track, double volume);
|
||||
|
@ -102,7 +102,7 @@ public class DataChannel {
|
||||
}
|
||||
}
|
||||
|
||||
private final long nativeDataChannel;
|
||||
private long nativeDataChannel;
|
||||
private long nativeObserver;
|
||||
|
||||
@CalledByNative
|
||||
@ -112,6 +112,7 @@ public class DataChannel {
|
||||
|
||||
/** Register |observer|, replacing any previously-registered observer. */
|
||||
public void registerObserver(Observer observer) {
|
||||
checkDataChannelExists();
|
||||
if (nativeObserver != 0) {
|
||||
nativeUnregisterObserver(nativeObserver);
|
||||
}
|
||||
@ -120,18 +121,22 @@ public class DataChannel {
|
||||
|
||||
/** Unregister the (only) observer. */
|
||||
public void unregisterObserver() {
|
||||
checkDataChannelExists();
|
||||
nativeUnregisterObserver(nativeObserver);
|
||||
}
|
||||
|
||||
public String label() {
|
||||
checkDataChannelExists();
|
||||
return nativeLabel();
|
||||
}
|
||||
|
||||
public int id() {
|
||||
checkDataChannelExists();
|
||||
return nativeId();
|
||||
}
|
||||
|
||||
public State state() {
|
||||
checkDataChannelExists();
|
||||
return nativeState();
|
||||
}
|
||||
|
||||
@ -141,16 +146,19 @@ public class DataChannel {
|
||||
* to the network.
|
||||
*/
|
||||
public long bufferedAmount() {
|
||||
checkDataChannelExists();
|
||||
return nativeBufferedAmount();
|
||||
}
|
||||
|
||||
/** Close the channel. */
|
||||
public void close() {
|
||||
checkDataChannelExists();
|
||||
nativeClose();
|
||||
}
|
||||
|
||||
/** Send |data| to the remote peer; return success. */
|
||||
public boolean send(Buffer buffer) {
|
||||
checkDataChannelExists();
|
||||
// TODO(fischman): this could be cleverer about avoiding copies if the
|
||||
// ByteBuffer is direct and/or is backed by an array.
|
||||
byte[] data = new byte[buffer.data.remaining()];
|
||||
@ -160,7 +168,9 @@ public class DataChannel {
|
||||
|
||||
/** Dispose of native resources attached to this channel. */
|
||||
public void dispose() {
|
||||
checkDataChannelExists();
|
||||
JniCommon.nativeReleaseRef(nativeDataChannel);
|
||||
nativeDataChannel = 0;
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
@ -168,6 +178,12 @@ public class DataChannel {
|
||||
return nativeDataChannel;
|
||||
}
|
||||
|
||||
private void checkDataChannelExists() {
|
||||
if (nativeDataChannel == 0) {
|
||||
throw new IllegalStateException("DataChannel has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private native long nativeRegisterObserver(Observer observer);
|
||||
private native void nativeUnregisterObserver(long observer);
|
||||
private native String nativeLabel();
|
||||
|
@ -12,7 +12,7 @@ package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ DtmfSenderInterface. */
|
||||
public class DtmfSender {
|
||||
final long nativeDtmfSender;
|
||||
private long nativeDtmfSender;
|
||||
|
||||
public DtmfSender(long nativeDtmfSender) {
|
||||
this.nativeDtmfSender = nativeDtmfSender;
|
||||
@ -22,6 +22,7 @@ public class DtmfSender {
|
||||
* @return true if this DtmfSender is capable of sending DTMF. Otherwise false.
|
||||
*/
|
||||
public boolean canInsertDtmf() {
|
||||
checkDtmfSenderExists();
|
||||
return nativeCanInsertDtmf(nativeDtmfSender);
|
||||
}
|
||||
|
||||
@ -43,6 +44,7 @@ public class DtmfSender {
|
||||
* @return true on success and false on failure.
|
||||
*/
|
||||
public boolean insertDtmf(String tones, int duration, int interToneGap) {
|
||||
checkDtmfSenderExists();
|
||||
return nativeInsertDtmf(nativeDtmfSender, tones, duration, interToneGap);
|
||||
}
|
||||
|
||||
@ -50,6 +52,7 @@ public class DtmfSender {
|
||||
* @return The tones remaining to be played out
|
||||
*/
|
||||
public String tones() {
|
||||
checkDtmfSenderExists();
|
||||
return nativeTones(nativeDtmfSender);
|
||||
}
|
||||
|
||||
@ -58,6 +61,7 @@ public class DtmfSender {
|
||||
* insertDtmf() method, or the default value of 100 ms if insertDtmf() was never called.
|
||||
*/
|
||||
public int duration() {
|
||||
checkDtmfSenderExists();
|
||||
return nativeDuration(nativeDtmfSender);
|
||||
}
|
||||
|
||||
@ -67,11 +71,20 @@ public class DtmfSender {
|
||||
* called.
|
||||
*/
|
||||
public int interToneGap() {
|
||||
checkDtmfSenderExists();
|
||||
return nativeInterToneGap(nativeDtmfSender);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkDtmfSenderExists();
|
||||
JniCommon.nativeReleaseRef(nativeDtmfSender);
|
||||
nativeDtmfSender = 0;
|
||||
}
|
||||
|
||||
private void checkDtmfSenderExists() {
|
||||
if (nativeDtmfSender == 0) {
|
||||
throw new IllegalStateException("DtmfSender has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean nativeCanInsertDtmf(long dtmfSender);
|
||||
|
@ -25,18 +25,33 @@ public class MediaSource {
|
||||
}
|
||||
}
|
||||
|
||||
final long nativeSource; // Package-protected for PeerConnectionFactory.
|
||||
private long nativeSource;
|
||||
|
||||
public MediaSource(long nativeSource) {
|
||||
this.nativeSource = nativeSource;
|
||||
}
|
||||
|
||||
public State state() {
|
||||
checkMediaSourceExists();
|
||||
return nativeGetState(nativeSource);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkMediaSourceExists();
|
||||
JniCommon.nativeReleaseRef(nativeSource);
|
||||
nativeSource = 0;
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::MediaSourceInterface. */
|
||||
protected long getNativeMediaSource() {
|
||||
checkMediaSourceExists();
|
||||
return nativeSource;
|
||||
}
|
||||
|
||||
private void checkMediaSourceExists() {
|
||||
if (nativeSource == 0) {
|
||||
throw new IllegalStateException("MediaSource has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static native State nativeGetState(long pointer);
|
||||
|
@ -11,8 +11,8 @@
|
||||
package org.webrtc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/** Java wrapper for a C++ MediaStreamInterface. */
|
||||
public class MediaStream {
|
||||
@ -21,8 +21,7 @@ public class MediaStream {
|
||||
public final List<AudioTrack> audioTracks = new ArrayList<>();
|
||||
public final List<VideoTrack> videoTracks = new ArrayList<>();
|
||||
public final List<VideoTrack> preservedVideoTracks = new ArrayList<>();
|
||||
// Package-protected for PeerConnection.
|
||||
final long nativeStream;
|
||||
private long nativeStream;
|
||||
|
||||
@CalledByNative
|
||||
public MediaStream(long nativeStream) {
|
||||
@ -30,7 +29,8 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public boolean addTrack(AudioTrack track) {
|
||||
if (nativeAddAudioTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
checkMediaStreamExists();
|
||||
if (nativeAddAudioTrackToNativeStream(nativeStream, track.getNativeAudioTrack())) {
|
||||
audioTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -38,7 +38,8 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public boolean addTrack(VideoTrack track) {
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
checkMediaStreamExists();
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.getNativeVideoTrack())) {
|
||||
videoTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -49,7 +50,8 @@ public class MediaStream {
|
||||
// is called. If video track need to be preserved after MediaStream is destroyed it
|
||||
// should be added to MediaStream using addPreservedTrack() call.
|
||||
public boolean addPreservedTrack(VideoTrack track) {
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.nativeTrack)) {
|
||||
checkMediaStreamExists();
|
||||
if (nativeAddVideoTrackToNativeStream(nativeStream, track.getNativeVideoTrack())) {
|
||||
preservedVideoTracks.add(track);
|
||||
return true;
|
||||
}
|
||||
@ -57,18 +59,21 @@ public class MediaStream {
|
||||
}
|
||||
|
||||
public boolean removeTrack(AudioTrack track) {
|
||||
checkMediaStreamExists();
|
||||
audioTracks.remove(track);
|
||||
return nativeRemoveAudioTrack(nativeStream, track.nativeTrack);
|
||||
return nativeRemoveAudioTrack(nativeStream, track.getNativeAudioTrack());
|
||||
}
|
||||
|
||||
public boolean removeTrack(VideoTrack track) {
|
||||
checkMediaStreamExists();
|
||||
videoTracks.remove(track);
|
||||
preservedVideoTracks.remove(track);
|
||||
return nativeRemoveVideoTrack(nativeStream, track.nativeTrack);
|
||||
return nativeRemoveVideoTrack(nativeStream, track.getNativeVideoTrack());
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void dispose() {
|
||||
checkMediaStreamExists();
|
||||
// Remove and release previously added audio and video tracks.
|
||||
while (!audioTracks.isEmpty()) {
|
||||
AudioTrack track = audioTracks.get(0 /* index */);
|
||||
@ -85,9 +90,11 @@ public class MediaStream {
|
||||
removeTrack(preservedVideoTracks.get(0 /* index */));
|
||||
}
|
||||
JniCommon.nativeReleaseRef(nativeStream);
|
||||
nativeStream = 0;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
checkMediaStreamExists();
|
||||
return nativeGetId(nativeStream);
|
||||
}
|
||||
|
||||
@ -116,12 +123,24 @@ public class MediaStream {
|
||||
removeMediaStreamTrack(videoTracks, nativeTrack);
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::MediaStreamInterface. */
|
||||
long getNativeMediaStream() {
|
||||
checkMediaStreamExists();
|
||||
return nativeStream;
|
||||
}
|
||||
|
||||
private void checkMediaStreamExists() {
|
||||
if (nativeStream == 0) {
|
||||
throw new IllegalStateException("MediaStream has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeMediaStreamTrack(
|
||||
List<? extends MediaStreamTrack> tracks, long nativeTrack) {
|
||||
final Iterator<? extends MediaStreamTrack> it = tracks.iterator();
|
||||
while (it.hasNext()) {
|
||||
MediaStreamTrack track = it.next();
|
||||
if (track.nativeTrack == nativeTrack) {
|
||||
if (track.getNativeMediaStreamTrack() == nativeTrack) {
|
||||
track.dispose();
|
||||
it.remove();
|
||||
return;
|
||||
|
@ -70,34 +70,52 @@ public class MediaStreamTrack {
|
||||
}
|
||||
}
|
||||
|
||||
final long nativeTrack;
|
||||
private long nativeTrack;
|
||||
|
||||
public MediaStreamTrack(long nativeTrack) {
|
||||
this.nativeTrack = nativeTrack;
|
||||
}
|
||||
|
||||
public String id() {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeGetId(nativeTrack);
|
||||
}
|
||||
|
||||
public String kind() {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeGetKind(nativeTrack);
|
||||
}
|
||||
|
||||
public boolean enabled() {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeGetEnabled(nativeTrack);
|
||||
}
|
||||
|
||||
public boolean setEnabled(boolean enable) {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeSetEnabled(nativeTrack, enable);
|
||||
}
|
||||
|
||||
public State state() {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeGetState(nativeTrack);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkMediaStreamTrackExists();
|
||||
JniCommon.nativeReleaseRef(nativeTrack);
|
||||
nativeTrack = 0;
|
||||
}
|
||||
|
||||
long getNativeMediaStreamTrack() {
|
||||
checkMediaStreamTrackExists();
|
||||
return nativeTrack;
|
||||
}
|
||||
|
||||
private void checkMediaStreamTrackExists() {
|
||||
if (nativeTrack == 0) {
|
||||
throw new IllegalStateException("MediaStreamTrack has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static native String nativeGetId(long track);
|
||||
|
@ -781,7 +781,7 @@ public class PeerConnection {
|
||||
* use addTrack instead.
|
||||
*/
|
||||
public boolean addStream(MediaStream stream) {
|
||||
boolean ret = nativeAddLocalStream(stream.nativeStream);
|
||||
boolean ret = nativeAddLocalStream(stream.getNativeMediaStream());
|
||||
if (!ret) {
|
||||
return false;
|
||||
}
|
||||
@ -795,7 +795,7 @@ public class PeerConnection {
|
||||
* removeTrack instead.
|
||||
*/
|
||||
public void removeStream(MediaStream stream) {
|
||||
nativeRemoveLocalStream(stream.nativeStream);
|
||||
nativeRemoveLocalStream(stream.getNativeMediaStream());
|
||||
localStreams.remove(stream);
|
||||
}
|
||||
|
||||
@ -905,7 +905,7 @@ public class PeerConnection {
|
||||
if (track == null || streamIds == null) {
|
||||
throw new NullPointerException("No MediaStreamTrack specified in addTrack.");
|
||||
}
|
||||
RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds);
|
||||
RtpSender newSender = nativeAddTrack(track.getNativeMediaStreamTrack(), streamIds);
|
||||
if (newSender == null) {
|
||||
throw new IllegalStateException("C++ addTrack failed.");
|
||||
}
|
||||
@ -922,7 +922,7 @@ public class PeerConnection {
|
||||
if (sender == null) {
|
||||
throw new NullPointerException("No RtpSender specified for removeTrack.");
|
||||
}
|
||||
return nativeRemoveTrack(sender.nativeRtpSender);
|
||||
return nativeRemoveTrack(sender.getNativeRtpSender());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -962,7 +962,8 @@ public class PeerConnection {
|
||||
if (init == null) {
|
||||
init = new RtpTransceiver.RtpTransceiverInit();
|
||||
}
|
||||
RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init);
|
||||
RtpTransceiver newTransceiver =
|
||||
nativeAddTransceiverWithTrack(track.getNativeMediaStreamTrack(), init);
|
||||
if (newTransceiver == null) {
|
||||
throw new IllegalStateException("C++ addTransceiver failed.");
|
||||
}
|
||||
@ -993,7 +994,7 @@ public class PeerConnection {
|
||||
// Older, non-standard implementation of getStats.
|
||||
@Deprecated
|
||||
public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) {
|
||||
return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack);
|
||||
return nativeOldGetStats(observer, (track == null) ? 0 : track.getNativeMediaStreamTrack());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1070,7 +1071,7 @@ public class PeerConnection {
|
||||
public void dispose() {
|
||||
close();
|
||||
for (MediaStream stream : localStreams) {
|
||||
nativeRemoveLocalStream(stream.nativeStream);
|
||||
nativeRemoveLocalStream(stream.getNativeMediaStream());
|
||||
stream.dispose();
|
||||
}
|
||||
localStreams.clear();
|
||||
|
@ -28,7 +28,7 @@ public class PeerConnectionFactory {
|
||||
private static final String TAG = "PeerConnectionFactory";
|
||||
private static final String VIDEO_CAPTURER_THREAD_NAME = "VideoCapturerThread";
|
||||
|
||||
private final long nativeFactory;
|
||||
private long nativeFactory;
|
||||
private static volatile boolean internalTracerInitialized;
|
||||
@Nullable private static Thread networkThread;
|
||||
@Nullable private static Thread workerThread;
|
||||
@ -307,6 +307,7 @@ public class PeerConnectionFactory {
|
||||
PeerConnection createPeerConnectionInternal(PeerConnection.RTCConfiguration rtcConfig,
|
||||
MediaConstraints constraints, PeerConnection.Observer observer,
|
||||
SSLCertificateVerifier sslCertificateVerifier) {
|
||||
checkPeerConnectionFactoryExists();
|
||||
long nativeObserver = PeerConnection.createNativePeerConnectionObserver(observer);
|
||||
if (nativeObserver == 0) {
|
||||
return null;
|
||||
@ -364,61 +365,80 @@ public class PeerConnectionFactory {
|
||||
}
|
||||
|
||||
public MediaStream createLocalMediaStream(String label) {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return new MediaStream(nativeCreateLocalMediaStream(nativeFactory, label));
|
||||
}
|
||||
|
||||
public VideoSource createVideoSource(boolean isScreencast) {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return new VideoSource(nativeCreateVideoSource(nativeFactory, isScreencast));
|
||||
}
|
||||
|
||||
public VideoTrack createVideoTrack(String id, VideoSource source) {
|
||||
return new VideoTrack(nativeCreateVideoTrack(nativeFactory, id, source.nativeSource));
|
||||
checkPeerConnectionFactoryExists();
|
||||
return new VideoTrack(
|
||||
nativeCreateVideoTrack(nativeFactory, id, source.getNativeVideoTrackSource()));
|
||||
}
|
||||
|
||||
public AudioSource createAudioSource(MediaConstraints constraints) {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return new AudioSource(nativeCreateAudioSource(nativeFactory, constraints));
|
||||
}
|
||||
|
||||
public AudioTrack createAudioTrack(String id, AudioSource source) {
|
||||
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.nativeSource));
|
||||
checkPeerConnectionFactoryExists();
|
||||
return new AudioTrack(nativeCreateAudioTrack(nativeFactory, id, source.getNativeAudioSource()));
|
||||
}
|
||||
|
||||
// Starts recording an AEC dump. Ownership of the file is transfered to the
|
||||
// native code. If an AEC dump is already in progress, it will be stopped and
|
||||
// a new one will start using the provided file.
|
||||
public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
|
||||
}
|
||||
|
||||
// Stops recording an AEC dump. If no AEC dump is currently being recorded,
|
||||
// this call will have no effect.
|
||||
public void stopAecDump() {
|
||||
checkPeerConnectionFactoryExists();
|
||||
nativeStopAecDump(nativeFactory);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkPeerConnectionFactoryExists();
|
||||
nativeFreeFactory(nativeFactory);
|
||||
networkThread = null;
|
||||
workerThread = null;
|
||||
signalingThread = null;
|
||||
MediaCodecVideoEncoder.disposeEglContext();
|
||||
MediaCodecVideoDecoder.disposeEglContext();
|
||||
nativeFactory = 0;
|
||||
}
|
||||
|
||||
public void threadsCallbacks() {
|
||||
checkPeerConnectionFactoryExists();
|
||||
nativeInvokeThreadsCallbacks(nativeFactory);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the native webrtc::PeerConnectionFactoryInterface. */
|
||||
public long getNativePeerConnectionFactory() {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return nativeGetNativePeerConnectionFactory(nativeFactory);
|
||||
}
|
||||
|
||||
/** Returns a pointer to the native OwnedFactoryAndThreads object */
|
||||
public long getNativeOwnedFactoryAndThreads() {
|
||||
checkPeerConnectionFactoryExists();
|
||||
return nativeFactory;
|
||||
}
|
||||
|
||||
private void checkPeerConnectionFactoryExists() {
|
||||
if (nativeFactory == 0) {
|
||||
throw new IllegalStateException("PeerConnectionFactory has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static void printStackTrace(@Nullable Thread thread, String threadName) {
|
||||
if (thread != null) {
|
||||
StackTraceElement[] stackTraces = thread.getStackTrace();
|
||||
|
@ -22,7 +22,7 @@ public class RtpReceiver {
|
||||
public void onFirstPacketReceived(MediaStreamTrack.MediaType media_type);
|
||||
}
|
||||
|
||||
final long nativeRtpReceiver;
|
||||
private long nativeRtpReceiver;
|
||||
private long nativeObserver;
|
||||
|
||||
@Nullable private MediaStreamTrack cachedTrack;
|
||||
@ -40,28 +40,34 @@ public class RtpReceiver {
|
||||
}
|
||||
|
||||
public boolean setParameters(@Nullable RtpParameters parameters) {
|
||||
checkRtpReceiverExists();
|
||||
return parameters == null ? false : nativeSetParameters(nativeRtpReceiver, parameters);
|
||||
}
|
||||
|
||||
public RtpParameters getParameters() {
|
||||
checkRtpReceiverExists();
|
||||
return nativeGetParameters(nativeRtpReceiver);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
checkRtpReceiverExists();
|
||||
return nativeGetId(nativeRtpReceiver);
|
||||
}
|
||||
|
||||
@CalledByNative
|
||||
public void dispose() {
|
||||
checkRtpReceiverExists();
|
||||
cachedTrack.dispose();
|
||||
if (nativeObserver != 0) {
|
||||
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
|
||||
nativeObserver = 0;
|
||||
}
|
||||
JniCommon.nativeReleaseRef(nativeRtpReceiver);
|
||||
nativeRtpReceiver = 0;
|
||||
}
|
||||
|
||||
public void SetObserver(Observer observer) {
|
||||
checkRtpReceiverExists();
|
||||
// Unset the existing one before setting a new one.
|
||||
if (nativeObserver != 0) {
|
||||
nativeUnsetObserver(nativeRtpReceiver, nativeObserver);
|
||||
@ -70,9 +76,16 @@ public class RtpReceiver {
|
||||
}
|
||||
|
||||
public void setFrameDecryptor(FrameDecryptor frameDecryptor) {
|
||||
checkRtpReceiverExists();
|
||||
nativeSetFrameDecryptor(nativeRtpReceiver, frameDecryptor.getNativeFrameDecryptor());
|
||||
}
|
||||
|
||||
private void checkRtpReceiverExists() {
|
||||
if (nativeRtpReceiver == 0) {
|
||||
throw new IllegalStateException("RtpReceiver has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
// This should increment the reference count of the track.
|
||||
// Will be released in dispose().
|
||||
private static native long nativeGetTrack(long rtpReceiver);
|
||||
|
@ -14,7 +14,7 @@ import javax.annotation.Nullable;
|
||||
|
||||
/** Java wrapper for a C++ RtpSenderInterface. */
|
||||
public class RtpSender {
|
||||
final long nativeRtpSender;
|
||||
private long nativeRtpSender;
|
||||
|
||||
@Nullable private MediaStreamTrack cachedTrack;
|
||||
private boolean ownsTrack = true;
|
||||
@ -45,7 +45,8 @@ public class RtpSender {
|
||||
* @return true on success and false on failure.
|
||||
*/
|
||||
public boolean setTrack(@Nullable MediaStreamTrack track, boolean takeOwnership) {
|
||||
if (!nativeSetTrack(nativeRtpSender, (track == null) ? 0 : track.nativeTrack)) {
|
||||
checkRtpSenderExists();
|
||||
if (!nativeSetTrack(nativeRtpSender, (track == null) ? 0 : track.getNativeMediaStreamTrack())) {
|
||||
return false;
|
||||
}
|
||||
if (cachedTrack != null && ownsTrack) {
|
||||
@ -62,14 +63,17 @@ public class RtpSender {
|
||||
}
|
||||
|
||||
public boolean setParameters(RtpParameters parameters) {
|
||||
checkRtpSenderExists();
|
||||
return nativeSetParameters(nativeRtpSender, parameters);
|
||||
}
|
||||
|
||||
public RtpParameters getParameters() {
|
||||
checkRtpSenderExists();
|
||||
return nativeGetParameters(nativeRtpSender);
|
||||
}
|
||||
|
||||
public String id() {
|
||||
checkRtpSenderExists();
|
||||
return nativeGetId(nativeRtpSender);
|
||||
}
|
||||
|
||||
@ -79,10 +83,12 @@ public class RtpSender {
|
||||
}
|
||||
|
||||
public void setFrameEncryptor(FrameEncryptor frameEncryptor) {
|
||||
checkRtpSenderExists();
|
||||
nativeSetFrameEncryptor(nativeRtpSender, frameEncryptor.getNativeFrameEncryptor());
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkRtpSenderExists();
|
||||
if (dtmfSender != null) {
|
||||
dtmfSender.dispose();
|
||||
}
|
||||
@ -90,6 +96,19 @@ public class RtpSender {
|
||||
cachedTrack.dispose();
|
||||
}
|
||||
JniCommon.nativeReleaseRef(nativeRtpSender);
|
||||
nativeRtpSender = 0;
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::RtpSenderInterface. */
|
||||
long getNativeRtpSender() {
|
||||
checkRtpSenderExists();
|
||||
return nativeRtpSender;
|
||||
}
|
||||
|
||||
private void checkRtpSenderExists() {
|
||||
if (nativeRtpSender == 0) {
|
||||
throw new IllegalStateException("RtpSender has been disposed.");
|
||||
}
|
||||
}
|
||||
|
||||
private static native boolean nativeSetTrack(long rtpSender, long nativeTrack);
|
||||
|
@ -13,7 +13,6 @@ 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.
|
||||
@ -96,7 +95,7 @@ public class RtpTransceiver {
|
||||
}
|
||||
}
|
||||
|
||||
private final long nativeRtpTransceiver;
|
||||
private long nativeRtpTransceiver;
|
||||
private RtpSender cachedSender;
|
||||
private RtpReceiver cachedReceiver;
|
||||
|
||||
@ -112,6 +111,7 @@ public class RtpTransceiver {
|
||||
* type as well.
|
||||
*/
|
||||
public MediaStreamTrack.MediaType getMediaType() {
|
||||
checkRtpTransceiverExists();
|
||||
return nativeGetMediaType(nativeRtpTransceiver);
|
||||
}
|
||||
|
||||
@ -122,6 +122,7 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-mid
|
||||
*/
|
||||
public String getMid() {
|
||||
checkRtpTransceiverExists();
|
||||
return nativeGetMid(nativeRtpTransceiver);
|
||||
}
|
||||
|
||||
@ -153,6 +154,7 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stopped
|
||||
*/
|
||||
public boolean isStopped() {
|
||||
checkRtpTransceiverExists();
|
||||
return nativeStopped(nativeRtpTransceiver);
|
||||
}
|
||||
|
||||
@ -162,6 +164,7 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
|
||||
*/
|
||||
public RtpTransceiverDirection getDirection() {
|
||||
checkRtpTransceiverExists();
|
||||
return nativeDirection(nativeRtpTransceiver);
|
||||
}
|
||||
|
||||
@ -172,6 +175,7 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-currentdirection
|
||||
*/
|
||||
public RtpTransceiverDirection getCurrentDirection() {
|
||||
checkRtpTransceiverExists();
|
||||
return nativeCurrentDirection(nativeRtpTransceiver);
|
||||
}
|
||||
|
||||
@ -183,6 +187,7 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-direction
|
||||
*/
|
||||
public void setDirection(RtpTransceiverDirection rtpTransceiverDirection) {
|
||||
checkRtpTransceiverExists();
|
||||
nativeSetDirection(nativeRtpTransceiver, rtpTransceiverDirection);
|
||||
}
|
||||
|
||||
@ -192,14 +197,23 @@ public class RtpTransceiver {
|
||||
* https://w3c.github.io/webrtc-pc/#dom-rtcrtptransceiver-stop
|
||||
*/
|
||||
public void stop() {
|
||||
checkRtpTransceiverExists();
|
||||
nativeStop(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);
|
||||
|
@ -12,20 +12,30 @@ package org.webrtc;
|
||||
|
||||
/** Java wrapper for a C++ TurnCustomizer. */
|
||||
public class TurnCustomizer {
|
||||
final long nativeTurnCustomizer;
|
||||
private long nativeTurnCustomizer;
|
||||
|
||||
public TurnCustomizer(long nativeTurnCustomizer) {
|
||||
this.nativeTurnCustomizer = nativeTurnCustomizer;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
checkTurnCustomizerExists();
|
||||
nativeFreeTurnCustomizer(nativeTurnCustomizer);
|
||||
nativeTurnCustomizer = 0;
|
||||
}
|
||||
|
||||
private static native void nativeFreeTurnCustomizer(long turnCustomizer);
|
||||
|
||||
/** Return a pointer to webrtc::TurnCustomizer. */
|
||||
@CalledByNative
|
||||
long getNativeTurnCustomizer() {
|
||||
checkTurnCustomizerExists();
|
||||
return nativeTurnCustomizer;
|
||||
}
|
||||
|
||||
private void checkTurnCustomizerExists() {
|
||||
if (nativeTurnCustomizer == 0) {
|
||||
throw new IllegalStateException("TurnCustomizer has been disposed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,13 +30,18 @@ public class VideoSource extends MediaSource {
|
||||
* maintain the input orientation, so it doesn't matter if e.g. 1280x720 or 720x1280 is requested.
|
||||
*/
|
||||
public void adaptOutputFormat(int width, int height, int fps) {
|
||||
nativeAdaptOutputFormat(nativeSource, width, height, fps);
|
||||
nativeAdaptOutputFormat(getNativeVideoTrackSource(), width, height, fps);
|
||||
}
|
||||
|
||||
public CapturerObserver getCapturerObserver() {
|
||||
return capturerObserver;
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::VideoTrackSourceInterface. */
|
||||
long getNativeVideoTrackSource() {
|
||||
return getNativeMediaSource();
|
||||
}
|
||||
|
||||
// Returns source->internal() from webrtc::VideoTrackSourceProxy.
|
||||
private static native long nativeGetInternalSource(long source);
|
||||
private static native void nativeAdaptOutputFormat(long source, int width, int height, int fps);
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
package org.webrtc;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
||||
/** Java version of VideoTrackInterface. */
|
||||
@ -39,7 +39,7 @@ public class VideoTrack extends MediaStreamTrack {
|
||||
if (!sinks.containsKey(sink)) {
|
||||
final long nativeSink = nativeWrapSink(sink);
|
||||
sinks.put(sink, nativeSink);
|
||||
nativeAddSink(nativeTrack, nativeSink);
|
||||
nativeAddSink(getNativeMediaStreamTrack(), nativeSink);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public class VideoTrack extends MediaStreamTrack {
|
||||
public void removeSink(VideoSink sink) {
|
||||
final Long nativeSink = sinks.remove(sink);
|
||||
if (nativeSink != null) {
|
||||
nativeRemoveSink(nativeTrack, nativeSink);
|
||||
nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
|
||||
nativeFreeSink(nativeSink);
|
||||
}
|
||||
}
|
||||
@ -59,13 +59,18 @@ public class VideoTrack extends MediaStreamTrack {
|
||||
@Override
|
||||
public void dispose() {
|
||||
for (long nativeSink : sinks.values()) {
|
||||
nativeRemoveSink(nativeTrack, nativeSink);
|
||||
nativeRemoveSink(getNativeMediaStreamTrack(), nativeSink);
|
||||
nativeFreeSink(nativeSink);
|
||||
}
|
||||
sinks.clear();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/** Returns a pointer to webrtc::VideoTrackInterface. */
|
||||
long getNativeVideoTrack() {
|
||||
return getNativeMediaStreamTrack();
|
||||
}
|
||||
|
||||
private static native void nativeAddSink(long track, long nativeSink);
|
||||
private static native void nativeRemoveSink(long track, long nativeSink);
|
||||
private static native long nativeWrapSink(VideoSink sink);
|
||||
|
Reference in New Issue
Block a user