OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 import org.webrtc.StatsReport; | 37 import org.webrtc.StatsReport; |
38 import org.webrtc.VideoCapturer; | 38 import org.webrtc.VideoCapturer; |
39 import org.webrtc.VideoRenderer; | 39 import org.webrtc.VideoRenderer; |
40 import org.webrtc.VideoSource; | 40 import org.webrtc.VideoSource; |
41 import org.webrtc.VideoTrack; | 41 import org.webrtc.VideoTrack; |
42 import org.webrtc.voiceengine.WebRtcAudioManager; | 42 import org.webrtc.voiceengine.WebRtcAudioManager; |
43 import org.webrtc.voiceengine.WebRtcAudioUtils; | 43 import org.webrtc.voiceengine.WebRtcAudioUtils; |
44 | 44 |
45 import java.io.File; | 45 import java.io.File; |
46 import java.io.IOException; | 46 import java.io.IOException; |
| 47 import java.nio.ByteBuffer; |
47 import java.util.Collections; | 48 import java.util.Collections; |
48 import java.util.EnumSet; | 49 import java.util.EnumSet; |
49 import java.util.LinkedList; | 50 import java.util.LinkedList; |
50 import java.util.List; | 51 import java.util.List; |
51 import java.util.Timer; | 52 import java.util.Timer; |
52 import java.util.TimerTask; | 53 import java.util.TimerTask; |
53 import java.util.concurrent.Executors; | 54 import java.util.concurrent.Executors; |
54 import java.util.concurrent.ScheduledExecutorService; | 55 import java.util.concurrent.ScheduledExecutorService; |
55 import java.util.regex.Matcher; | 56 import java.util.regex.Matcher; |
56 import java.util.regex.Pattern; | 57 import java.util.regex.Pattern; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 private MediaStream mediaStream; | 126 private MediaStream mediaStream; |
126 private VideoCapturer videoCapturer; | 127 private VideoCapturer videoCapturer; |
127 // enableVideo is set to true if video should be rendered and sent. | 128 // enableVideo is set to true if video should be rendered and sent. |
128 private boolean renderVideo; | 129 private boolean renderVideo; |
129 private VideoTrack localVideoTrack; | 130 private VideoTrack localVideoTrack; |
130 private VideoTrack remoteVideoTrack; | 131 private VideoTrack remoteVideoTrack; |
131 private RtpSender localVideoSender; | 132 private RtpSender localVideoSender; |
132 // enableAudio is set to true if audio should be sent. | 133 // enableAudio is set to true if audio should be sent. |
133 private boolean enableAudio; | 134 private boolean enableAudio; |
134 private AudioTrack localAudioTrack; | 135 private AudioTrack localAudioTrack; |
| 136 private DataChannel dataChannel; |
| 137 private boolean dataChannelEnabled; |
135 | 138 |
136 /** | 139 /** |
137 * Peer connection parameters. | 140 * Peer connection parameters. |
| 141 */ |
| 142 public static class DataChannelParameters { |
| 143 public final boolean ordered; |
| 144 public final int maxRetransmitTimeMs; |
| 145 public final int maxRetransmits; |
| 146 public final String protocol; |
| 147 public final boolean negotiated; |
| 148 public final int id; |
| 149 |
| 150 public DataChannelParameters( |
| 151 boolean ordered, int maxRetransmitTimeMs, int maxRetransmits, String
protocol, |
| 152 boolean negotiated, int id) { |
| 153 this.ordered = ordered; |
| 154 this.maxRetransmitTimeMs = maxRetransmitTimeMs; |
| 155 this.maxRetransmits = maxRetransmits; |
| 156 this.protocol = protocol; |
| 157 this.negotiated = negotiated; |
| 158 this.id = id; |
| 159 } |
| 160 } |
| 161 |
| 162 /** |
| 163 * Peer connection parameters. |
138 */ | 164 */ |
139 public static class PeerConnectionParameters { | 165 public static class PeerConnectionParameters { |
140 public final boolean videoCallEnabled; | 166 public final boolean videoCallEnabled; |
141 public final boolean loopback; | 167 public final boolean loopback; |
142 public final boolean tracing; | 168 public final boolean tracing; |
143 public final int videoWidth; | 169 public final int videoWidth; |
144 public final int videoHeight; | 170 public final int videoHeight; |
145 public final int videoFps; | 171 public final int videoFps; |
146 public final int videoMaxBitrate; | 172 public final int videoMaxBitrate; |
147 public final String videoCodec; | 173 public final String videoCodec; |
148 public final boolean videoCodecHwAcceleration; | 174 public final boolean videoCodecHwAcceleration; |
149 public final int audioStartBitrate; | 175 public final int audioStartBitrate; |
150 public final String audioCodec; | 176 public final String audioCodec; |
151 public final boolean noAudioProcessing; | 177 public final boolean noAudioProcessing; |
152 public final boolean aecDump; | 178 public final boolean aecDump; |
153 public final boolean useOpenSLES; | 179 public final boolean useOpenSLES; |
154 public final boolean disableBuiltInAEC; | 180 public final boolean disableBuiltInAEC; |
155 public final boolean disableBuiltInAGC; | 181 public final boolean disableBuiltInAGC; |
156 public final boolean disableBuiltInNS; | 182 public final boolean disableBuiltInNS; |
157 public final boolean enableLevelControl; | 183 public final boolean enableLevelControl; |
| 184 private final DataChannelParameters dataChannelParameters; |
158 | 185 |
159 public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback,
boolean tracing, | 186 public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback,
boolean tracing, |
160 int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, Stri
ng videoCodec, | 187 int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, Stri
ng videoCodec, |
161 boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCod
ec, | 188 boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCod
ec, |
162 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean
disableBuiltInAEC, | 189 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean
disableBuiltInAEC, |
163 boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevel
Control) { | 190 boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevel
Control) { |
| 191 this(videoCallEnabled, loopback, tracing, videoWidth, videoHeight, videoFp
s, |
| 192 videoMaxBitrate, videoCodec, videoCodecHwAcceleration, audioStartBitrate, |
| 193 audioCodec, noAudioProcessing, aecDump, useOpenSLES, disableBuiltInAEC, di
sableBuiltInAGC, |
| 194 disableBuiltInNS, enableLevelControl, null); |
| 195 } |
| 196 |
| 197 public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback,
boolean tracing, |
| 198 int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, Stri
ng videoCodec, |
| 199 boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCod
ec, |
| 200 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean
disableBuiltInAEC, |
| 201 boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevel
Control, |
| 202 DataChannelParameters dataChannelParameters) { |
164 this.videoCallEnabled = videoCallEnabled; | 203 this.videoCallEnabled = videoCallEnabled; |
165 this.loopback = loopback; | 204 this.loopback = loopback; |
166 this.tracing = tracing; | 205 this.tracing = tracing; |
167 this.videoWidth = videoWidth; | 206 this.videoWidth = videoWidth; |
168 this.videoHeight = videoHeight; | 207 this.videoHeight = videoHeight; |
169 this.videoFps = videoFps; | 208 this.videoFps = videoFps; |
170 this.videoMaxBitrate = videoMaxBitrate; | 209 this.videoMaxBitrate = videoMaxBitrate; |
171 this.videoCodec = videoCodec; | 210 this.videoCodec = videoCodec; |
172 this.videoCodecHwAcceleration = videoCodecHwAcceleration; | 211 this.videoCodecHwAcceleration = videoCodecHwAcceleration; |
173 this.audioStartBitrate = audioStartBitrate; | 212 this.audioStartBitrate = audioStartBitrate; |
174 this.audioCodec = audioCodec; | 213 this.audioCodec = audioCodec; |
175 this.noAudioProcessing = noAudioProcessing; | 214 this.noAudioProcessing = noAudioProcessing; |
176 this.aecDump = aecDump; | 215 this.aecDump = aecDump; |
177 this.useOpenSLES = useOpenSLES; | 216 this.useOpenSLES = useOpenSLES; |
178 this.disableBuiltInAEC = disableBuiltInAEC; | 217 this.disableBuiltInAEC = disableBuiltInAEC; |
179 this.disableBuiltInAGC = disableBuiltInAGC; | 218 this.disableBuiltInAGC = disableBuiltInAGC; |
180 this.disableBuiltInNS = disableBuiltInNS; | 219 this.disableBuiltInNS = disableBuiltInNS; |
181 this.enableLevelControl = enableLevelControl; | 220 this.enableLevelControl = enableLevelControl; |
| 221 this.dataChannelParameters = dataChannelParameters; |
182 } | 222 } |
183 } | 223 } |
184 | 224 |
185 /** | 225 /** |
186 * Peer connection events. | 226 * Peer connection events. |
187 */ | 227 */ |
188 public interface PeerConnectionEvents { | 228 public interface PeerConnectionEvents { |
189 /** | 229 /** |
190 * Callback fired once local SDP is created and set. | 230 * Callback fired once local SDP is created and set. |
191 */ | 231 */ |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
242 | 282 |
243 public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options opti
ons) { | 283 public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options opti
ons) { |
244 this.options = options; | 284 this.options = options; |
245 } | 285 } |
246 | 286 |
247 public void createPeerConnectionFactory(final Context context, | 287 public void createPeerConnectionFactory(final Context context, |
248 final PeerConnectionParameters peerConnectionParameters, final PeerConnect
ionEvents events) { | 288 final PeerConnectionParameters peerConnectionParameters, final PeerConnect
ionEvents events) { |
249 this.peerConnectionParameters = peerConnectionParameters; | 289 this.peerConnectionParameters = peerConnectionParameters; |
250 this.events = events; | 290 this.events = events; |
251 videoCallEnabled = peerConnectionParameters.videoCallEnabled; | 291 videoCallEnabled = peerConnectionParameters.videoCallEnabled; |
| 292 dataChannelEnabled = peerConnectionParameters.dataChannelParameters != null; |
252 // Reset variables to initial states. | 293 // Reset variables to initial states. |
253 this.context = null; | 294 this.context = null; |
254 factory = null; | 295 factory = null; |
255 peerConnection = null; | 296 peerConnection = null; |
256 preferIsac = false; | 297 preferIsac = false; |
257 videoCapturerStopped = false; | 298 videoCapturerStopped = false; |
258 isError = false; | 299 isError = false; |
259 queuedRemoteCandidates = null; | 300 queuedRemoteCandidates = null; |
260 localSdp = null; // either offer or answer SDP | 301 localSdp = null; // either offer or answer SDP |
261 mediaStream = null; | 302 mediaStream = null; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 // TCP candidates are only useful when connecting to a server that supports | 527 // TCP candidates are only useful when connecting to a server that supports |
487 // ICE-TCP. | 528 // ICE-TCP. |
488 rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; | 529 rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; |
489 rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE; | 530 rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE; |
490 rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE; | 531 rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE; |
491 rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy
.GATHER_CONTINUALLY; | 532 rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy
.GATHER_CONTINUALLY; |
492 // Use ECDSA encryption. | 533 // Use ECDSA encryption. |
493 rtcConfig.keyType = PeerConnection.KeyType.ECDSA; | 534 rtcConfig.keyType = PeerConnection.KeyType.ECDSA; |
494 | 535 |
495 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb
server); | 536 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb
server); |
| 537 |
| 538 if (dataChannelEnabled) { |
| 539 DataChannel.Init init = new DataChannel.Init(); |
| 540 init.ordered = peerConnectionParameters.dataChannelParameters.ordered; |
| 541 init.negotiated = peerConnectionParameters.dataChannelParameters.negotiate
d; |
| 542 init.maxRetransmits = peerConnectionParameters.dataChannelParameters.maxRe
transmits; |
| 543 init.maxRetransmitTimeMs = peerConnectionParameters.dataChannelParameters.
maxRetransmitTimeMs; |
| 544 init.id = peerConnectionParameters.dataChannelParameters.id; |
| 545 init.protocol = peerConnectionParameters.dataChannelParameters.protocol; |
| 546 dataChannel = peerConnection.createDataChannel("ApprtcDemo data", init); |
| 547 } |
496 isInitiator = false; | 548 isInitiator = false; |
497 | 549 |
498 // Set default WebRTC tracing and INFO libjingle logging. | 550 // Set default WebRTC tracing and INFO libjingle logging. |
499 // NOTE: this _must_ happen while |factory| is alive! | 551 // NOTE: this _must_ happen while |factory| is alive! |
500 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT
)); | 552 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT
)); |
501 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); | 553 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); |
502 | 554 |
503 mediaStream = factory.createLocalMediaStream("ARDAMS"); | 555 mediaStream = factory.createLocalMediaStream("ARDAMS"); |
504 if (videoCallEnabled) { | 556 if (videoCallEnabled) { |
505 mediaStream.addTrack(createVideoTrack(videoCapturer)); | 557 mediaStream.addTrack(createVideoTrack(videoCapturer)); |
(...skipping 20 matching lines...) Expand all Loading... |
526 | 578 |
527 Log.d(TAG, "Peer connection created."); | 579 Log.d(TAG, "Peer connection created."); |
528 } | 580 } |
529 | 581 |
530 private void closeInternal() { | 582 private void closeInternal() { |
531 if (factory != null && peerConnectionParameters.aecDump) { | 583 if (factory != null && peerConnectionParameters.aecDump) { |
532 factory.stopAecDump(); | 584 factory.stopAecDump(); |
533 } | 585 } |
534 Log.d(TAG, "Closing peer connection."); | 586 Log.d(TAG, "Closing peer connection."); |
535 statsTimer.cancel(); | 587 statsTimer.cancel(); |
| 588 if (dataChannel != null) { |
| 589 dataChannel.dispose(); |
| 590 dataChannel = null; |
| 591 } |
536 if (peerConnection != null) { | 592 if (peerConnection != null) { |
537 peerConnection.dispose(); | 593 peerConnection.dispose(); |
538 peerConnection = null; | 594 peerConnection = null; |
539 } | 595 } |
540 Log.d(TAG, "Closing audio source."); | 596 Log.d(TAG, "Closing audio source."); |
541 if (audioSource != null) { | 597 if (audioSource != null) { |
542 audioSource.dispose(); | 598 audioSource.dispose(); |
543 audioSource = null; | 599 audioSource = null; |
544 } | 600 } |
545 Log.d(TAG, "Stopping capture."); | 601 Log.d(TAG, "Stopping capture."); |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1077 executor.execute(new Runnable() { | 1133 executor.execute(new Runnable() { |
1078 @Override | 1134 @Override |
1079 public void run() { | 1135 public void run() { |
1080 remoteVideoTrack = null; | 1136 remoteVideoTrack = null; |
1081 } | 1137 } |
1082 }); | 1138 }); |
1083 } | 1139 } |
1084 | 1140 |
1085 @Override | 1141 @Override |
1086 public void onDataChannel(final DataChannel dc) { | 1142 public void onDataChannel(final DataChannel dc) { |
1087 reportError("AppRTC doesn't use data channels, but got: " + dc.label() + "
anyway!"); | 1143 Log.d(TAG, "New Data channel " + dc.label()); |
| 1144 |
| 1145 if (!dataChannelEnabled) |
| 1146 return; |
| 1147 |
| 1148 dc.registerObserver(new DataChannel.Observer() { |
| 1149 public void onBufferedAmountChange(long previousAmount) { |
| 1150 Log.d(TAG, |
| 1151 "Data channel buffered amount changed: " + dc.label() + ": " +
dc.state()); |
| 1152 } |
| 1153 |
| 1154 @Override |
| 1155 public void onStateChange() { |
| 1156 Log.d(TAG, |
| 1157 "Data channel state changed: " + dc.label() + ": " + dc.state(
)); |
| 1158 } |
| 1159 |
| 1160 @Override |
| 1161 public void onMessage(final DataChannel.Buffer buffer) { |
| 1162 if (buffer.binary) { |
| 1163 Log.d(TAG, "Received binary msg over " + dc); |
| 1164 return; |
| 1165 } |
| 1166 ByteBuffer data = buffer.data; |
| 1167 final byte[] bytes = new byte[ data.capacity() ]; |
| 1168 data.get(bytes); |
| 1169 Runnable command = new Runnable() { |
| 1170 @Override |
| 1171 public void run() { |
| 1172 // Get DC message as String. |
| 1173 String strData = new String(bytes); |
| 1174 Log.d(TAG, "Got msg: " + strData + " over " + dc); |
| 1175 } |
| 1176 }; |
| 1177 executor.execute(command); |
| 1178 } |
| 1179 }); |
1088 } | 1180 } |
1089 | 1181 |
1090 @Override | 1182 @Override |
1091 public void onRenegotiationNeeded() { | 1183 public void onRenegotiationNeeded() { |
1092 // No need to do anything; AppRTC follows a pre-agreed-upon | 1184 // No need to do anything; AppRTC follows a pre-agreed-upon |
1093 // signaling/negotiation protocol. | 1185 // signaling/negotiation protocol. |
1094 } | 1186 } |
1095 } | 1187 } |
1096 | 1188 |
1097 // Implementation detail: handle offer creation/signaling and answer setting, | 1189 // Implementation detail: handle offer creation/signaling and answer setting, |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 public void onCreateFailure(final String error) { | 1259 public void onCreateFailure(final String error) { |
1168 reportError("createSDP error: " + error); | 1260 reportError("createSDP error: " + error); |
1169 } | 1261 } |
1170 | 1262 |
1171 @Override | 1263 @Override |
1172 public void onSetFailure(final String error) { | 1264 public void onSetFailure(final String error) { |
1173 reportError("setSDP error: " + error); | 1265 reportError("setSDP error: " + error); |
1174 } | 1266 } |
1175 } | 1267 } |
1176 } | 1268 } |
OLD | NEW |