From 9a58cc00e0b20e5d816e907beb5758bfa302003d Mon Sep 17 00:00:00 2001 From: Seth Hampson Date: Tue, 6 Mar 2018 17:24:06 -0800 Subject: [PATCH] Update the android AppRTC to use PeerConnection Unified Plan API. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This updates AppRTC to use addTrack instead of addStream, and removes the use of onAddStream, because we no longer have to wait for this to be fired to set the remote track's video renderers. Bug: webrtc:8869 Change-Id: I1ecae684a9bc4b30512e8c5d717e72b52c589831 Reviewed-on: https://webrtc-review.googlesource.com/57840 Commit-Queue: Seth Hampson Reviewed-by: Sami Kalliomäki Reviewed-by: Steve Anton Cr-Commit-Position: refs/heads/master@{#22318} --- .../appspot/apprtc/PeerConnectionClient.java | 61 ++++++++----------- .../api/org/webrtc/MediaStreamTrack.java | 18 ++++++ sdk/android/api/org/webrtc/RtpReceiver.java | 5 +- sdk/android/api/org/webrtc/RtpSender.java | 5 +- sdk/android/src/jni/pc/rtpreceiver.cc | 2 + sdk/android/src/jni/pc/rtpsender.cc | 2 + 6 files changed, 53 insertions(+), 40 deletions(-) diff --git a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java index 4f93925e6b..a2b4c102c1 100644 --- a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java @@ -47,12 +47,15 @@ import org.webrtc.IceCandidate; import org.webrtc.Logging; import org.webrtc.MediaConstraints; import org.webrtc.MediaStream; +import org.webrtc.MediaStreamTrack; +import org.webrtc.MediaStreamTrack.MediaType; import org.webrtc.PeerConnection; import org.webrtc.PeerConnection.IceConnectionState; import org.webrtc.PeerConnectionFactory; import org.webrtc.RtpParameters; import org.webrtc.RtpReceiver; import org.webrtc.RtpSender; +import org.webrtc.RtpTransceiver; import org.webrtc.SdpObserver; import org.webrtc.SessionDescription; import org.webrtc.SoftwareVideoDecoderFactory; @@ -636,6 +639,7 @@ public class PeerConnectionClient { rtcConfig.keyType = PeerConnection.KeyType.ECDSA; // Enable DTLS for normal calls and disable for loopback calls. rtcConfig.enableDtlsSrtp = !peerConnectionParameters.loopback; + rtcConfig.sdpSemantics = PeerConnection.SdpSemantics.UNIFIED_PLAN; peerConnection = factory.createPeerConnection(rtcConfig, pcObserver); @@ -655,13 +659,18 @@ public class PeerConnectionClient { // NOTE: this _must_ happen while |factory| is alive! Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); - mediaStream = factory.createLocalMediaStream("ARDAMS"); + List mediaStreamLabels = Collections.singletonList("ARDAMS"); if (videoCallEnabled) { - mediaStream.addTrack(createVideoTrack(videoCapturer)); + peerConnection.addTrack(createVideoTrack(videoCapturer), mediaStreamLabels); + // We can add the renderers right away because we don't need to wait for an + // answer to get the remote track. + remoteVideoTrack = getRemoteVideoTrack(); + remoteVideoTrack.setEnabled(renderVideo); + for (VideoRenderer.Callbacks remoteRender : remoteRenders) { + remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); + } } - - mediaStream.addTrack(createAudioTrack()); - peerConnection.addStream(mediaStream); + peerConnection.addTrack(createAudioTrack(), mediaStreamLabels); if (videoCallEnabled) { findVideoSender(); } @@ -1024,6 +1033,17 @@ public class PeerConnectionClient { } } + // Returns the remote VideoTrack, assuming there is only one. + private VideoTrack getRemoteVideoTrack() { + for (RtpTransceiver transceiver : peerConnection.getTransceivers()) { + MediaStreamTrack track = transceiver.getReceiver().track(); + if (track instanceof VideoTrack) { + return (VideoTrack) track; + } + } + return null; + } + @SuppressWarnings("StringSplitter") private static String setStartBitrate( String codec, boolean isVideoCodec, String sdpDescription, int bitrateKbps) { @@ -1274,37 +1294,10 @@ public class PeerConnectionClient { } @Override - public void onAddStream(final MediaStream stream) { - executor.execute(new Runnable() { - @Override - public void run() { - if (peerConnection == null || isError) { - return; - } - if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { - reportError("Weird-looking stream: " + stream); - return; - } - if (stream.videoTracks.size() == 1) { - remoteVideoTrack = stream.videoTracks.get(0); - remoteVideoTrack.setEnabled(renderVideo); - for (VideoRenderer.Callbacks remoteRender : remoteRenders) { - remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); - } - } - } - }); - } + public void onAddStream(final MediaStream stream) {} @Override - public void onRemoveStream(final MediaStream stream) { - executor.execute(new Runnable() { - @Override - public void run() { - remoteVideoTrack = null; - } - }); - } + public void onRemoveStream(final MediaStream stream) {} @Override public void onDataChannel(final DataChannel dc) { diff --git a/sdk/android/api/org/webrtc/MediaStreamTrack.java b/sdk/android/api/org/webrtc/MediaStreamTrack.java index 449ca75dbd..0a020ae72c 100644 --- a/sdk/android/api/org/webrtc/MediaStreamTrack.java +++ b/sdk/android/api/org/webrtc/MediaStreamTrack.java @@ -13,6 +13,9 @@ package org.webrtc; /** Java wrapper for a C++ MediaStreamTrackInterface. */ @JNINamespace("webrtc::jni") public class MediaStreamTrack { + public static final String AUDIO_TRACK_KIND = "audio"; + public static final String VIDEO_TRACK_KIND = "video"; + /** Tracks MediaStreamTrackInterface.TrackState */ public enum State { LIVE, @@ -51,6 +54,21 @@ public class MediaStreamTrack { } } + /** Factory method to create an AudioTrack or VideoTrack subclass. */ + static MediaStreamTrack createMediaStreamTrack(long nativeTrack) { + if (nativeTrack == 0) { + return null; + } + String trackKind = nativeGetKind(nativeTrack); + if (trackKind.equals(AUDIO_TRACK_KIND)) { + return new AudioTrack(nativeTrack); + } else if (trackKind.equals(VIDEO_TRACK_KIND)) { + return new VideoTrack(nativeTrack); + } else { + return null; + } + } + final long nativeTrack; public MediaStreamTrack(long nativeTrack) { diff --git a/sdk/android/api/org/webrtc/RtpReceiver.java b/sdk/android/api/org/webrtc/RtpReceiver.java index 0c9de5649a..f33fa58fb5 100644 --- a/sdk/android/api/org/webrtc/RtpReceiver.java +++ b/sdk/android/api/org/webrtc/RtpReceiver.java @@ -30,9 +30,8 @@ public class RtpReceiver { @CalledByNative public RtpReceiver(long nativeRtpReceiver) { this.nativeRtpReceiver = nativeRtpReceiver; - long track = nativeGetTrack(nativeRtpReceiver); - // We can assume that an RtpReceiver always has an associated track. - cachedTrack = new MediaStreamTrack(track); + long nativeTrack = nativeGetTrack(nativeRtpReceiver); + cachedTrack = MediaStreamTrack.createMediaStreamTrack(nativeTrack); } public MediaStreamTrack track() { diff --git a/sdk/android/api/org/webrtc/RtpSender.java b/sdk/android/api/org/webrtc/RtpSender.java index 9675d9d2e6..33ac3af9ec 100644 --- a/sdk/android/api/org/webrtc/RtpSender.java +++ b/sdk/android/api/org/webrtc/RtpSender.java @@ -23,9 +23,8 @@ public class RtpSender { @CalledByNative public RtpSender(long nativeRtpSender) { this.nativeRtpSender = nativeRtpSender; - long track = nativeGetTrack(nativeRtpSender); - // It may be possible for an RtpSender to be created without a track. - cachedTrack = (track != 0) ? new MediaStreamTrack(track) : null; + long nativeTrack = nativeGetTrack(nativeRtpSender); + cachedTrack = MediaStreamTrack.createMediaStreamTrack(nativeTrack); long nativeDtmfSender = nativeGetDtmfSender(nativeRtpSender); dtmfSender = (nativeDtmfSender != 0) ? new DtmfSender(nativeDtmfSender) : null; diff --git a/sdk/android/src/jni/pc/rtpreceiver.cc b/sdk/android/src/jni/pc/rtpreceiver.cc index 9487f404bd..049df49e7d 100644 --- a/sdk/android/src/jni/pc/rtpreceiver.cc +++ b/sdk/android/src/jni/pc/rtpreceiver.cc @@ -67,6 +67,8 @@ JavaRtpReceiverGlobalOwner::~JavaRtpReceiverGlobalOwner() { static jlong JNI_RtpReceiver_GetTrack(JNIEnv* jni, const JavaParamRef&, jlong j_rtp_receiver_pointer) { + // MediaStreamTrack will have shared ownership by the MediaStreamTrack Java + // object. return jlongFromPointer( reinterpret_cast(j_rtp_receiver_pointer) ->track() diff --git a/sdk/android/src/jni/pc/rtpsender.cc b/sdk/android/src/jni/pc/rtpsender.cc index 3a00383753..772dbcd613 100644 --- a/sdk/android/src/jni/pc/rtpsender.cc +++ b/sdk/android/src/jni/pc/rtpsender.cc @@ -39,6 +39,8 @@ static jboolean JNI_RtpSender_SetTrack(JNIEnv* jni, jlong JNI_RtpSender_GetTrack(JNIEnv* jni, const JavaParamRef&, jlong j_rtp_sender_pointer) { + // MediaStreamTrack will have shared ownership by the MediaStreamTrack Java + // object. return jlongFromPointer( reinterpret_cast(j_rtp_sender_pointer) ->track()