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