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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 public class PeerConnectionClient { | 67 public class PeerConnectionClient { |
68 public static final String VIDEO_TRACK_ID = "ARDAMSv0"; | 68 public static final String VIDEO_TRACK_ID = "ARDAMSv0"; |
69 public static final String AUDIO_TRACK_ID = "ARDAMSa0"; | 69 public static final String AUDIO_TRACK_ID = "ARDAMSa0"; |
70 public static final String VIDEO_TRACK_TYPE = "video"; | 70 public static final String VIDEO_TRACK_TYPE = "video"; |
71 private static final String TAG = "PCRTCClient"; | 71 private static final String TAG = "PCRTCClient"; |
72 private static final String VIDEO_CODEC_VP8 = "VP8"; | 72 private static final String VIDEO_CODEC_VP8 = "VP8"; |
73 private static final String VIDEO_CODEC_VP9 = "VP9"; | 73 private static final String VIDEO_CODEC_VP9 = "VP9"; |
74 private static final String VIDEO_CODEC_H264 = "H264"; | 74 private static final String VIDEO_CODEC_H264 = "H264"; |
75 private static final String AUDIO_CODEC_OPUS = "opus"; | 75 private static final String AUDIO_CODEC_OPUS = "opus"; |
76 private static final String AUDIO_CODEC_ISAC = "ISAC"; | 76 private static final String AUDIO_CODEC_ISAC = "ISAC"; |
77 private static final String VIDEO_CODEC_PARAM_START_BITRATE = | 77 private static final String VIDEO_CODEC_PARAM_START_BITRATE = "x-google-start-
bitrate"; |
78 "x-google-start-bitrate"; | |
79 private static final String AUDIO_CODEC_PARAM_BITRATE = "maxaveragebitrate"; | 78 private static final String AUDIO_CODEC_PARAM_BITRATE = "maxaveragebitrate"; |
80 private static final String AUDIO_ECHO_CANCELLATION_CONSTRAINT = "googEchoCanc
ellation"; | 79 private static final String AUDIO_ECHO_CANCELLATION_CONSTRAINT = "googEchoCanc
ellation"; |
81 private static final String AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT= "googAutoGainC
ontrol"; | 80 private static final String AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT = "googAutoGain
Control"; |
82 private static final String AUDIO_HIGH_PASS_FILTER_CONSTRAINT = "googHighpass
Filter"; | 81 private static final String AUDIO_HIGH_PASS_FILTER_CONSTRAINT = "googHighpassF
ilter"; |
83 private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSup
pression"; | 82 private static final String AUDIO_NOISE_SUPPRESSION_CONSTRAINT = "googNoiseSup
pression"; |
84 private static final String AUDIO_LEVEL_CONTROL_CONSTRAINT = "levelControl"; | 83 private static final String AUDIO_LEVEL_CONTROL_CONSTRAINT = "levelControl"; |
85 private static final String DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT = "DtlsSrtpKeyA
greement"; | 84 private static final String DTLS_SRTP_KEY_AGREEMENT_CONSTRAINT = "DtlsSrtpKeyA
greement"; |
86 private static final int HD_VIDEO_WIDTH = 1280; | 85 private static final int HD_VIDEO_WIDTH = 1280; |
87 private static final int HD_VIDEO_HEIGHT = 720; | 86 private static final int HD_VIDEO_HEIGHT = 720; |
88 private static final int MAX_VIDEO_WIDTH = 1280; | 87 private static final int MAX_VIDEO_WIDTH = 1280; |
89 private static final int MAX_VIDEO_HEIGHT = 1280; | 88 private static final int MAX_VIDEO_HEIGHT = 1280; |
90 private static final int MAX_VIDEO_FPS = 30; | 89 private static final int MAX_VIDEO_FPS = 30; |
91 private static final int BPS_IN_KBPS = 1000; | 90 private static final int BPS_IN_KBPS = 1000; |
92 | 91 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 public final int audioStartBitrate; | 154 public final int audioStartBitrate; |
156 public final String audioCodec; | 155 public final String audioCodec; |
157 public final boolean noAudioProcessing; | 156 public final boolean noAudioProcessing; |
158 public final boolean aecDump; | 157 public final boolean aecDump; |
159 public final boolean useOpenSLES; | 158 public final boolean useOpenSLES; |
160 public final boolean disableBuiltInAEC; | 159 public final boolean disableBuiltInAEC; |
161 public final boolean disableBuiltInAGC; | 160 public final boolean disableBuiltInAGC; |
162 public final boolean disableBuiltInNS; | 161 public final boolean disableBuiltInNS; |
163 public final boolean enableLevelControl; | 162 public final boolean enableLevelControl; |
164 | 163 |
165 public PeerConnectionParameters( | 164 public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback,
boolean tracing, |
166 boolean videoCallEnabled, boolean loopback, boolean tracing, boolean use
Camera2, | 165 boolean useCamera2, int videoWidth, int videoHeight, int videoFps, int v
ideoMaxBitrate, |
167 int videoWidth, int videoHeight, int videoFps, | 166 String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTe
xture, |
168 int videoMaxBitrate, String videoCodec, boolean videoCodecHwAcceleration
, | 167 int audioStartBitrate, String audioCodec, boolean noAudioProcessing, boo
lean aecDump, |
169 boolean captureToTexture, int audioStartBitrate, String audioCodec, | 168 boolean useOpenSLES, boolean disableBuiltInAEC, boolean disableBuiltInAG
C, |
170 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, | 169 boolean disableBuiltInNS, boolean enableLevelControl) { |
171 boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBui
ltInNS, | |
172 boolean enableLevelControl) { | |
173 this.videoCallEnabled = videoCallEnabled; | 170 this.videoCallEnabled = videoCallEnabled; |
174 this.useCamera2 = useCamera2; | 171 this.useCamera2 = useCamera2; |
175 this.loopback = loopback; | 172 this.loopback = loopback; |
176 this.tracing = tracing; | 173 this.tracing = tracing; |
177 this.videoWidth = videoWidth; | 174 this.videoWidth = videoWidth; |
178 this.videoHeight = videoHeight; | 175 this.videoHeight = videoHeight; |
179 this.videoFps = videoFps; | 176 this.videoFps = videoFps; |
180 this.videoMaxBitrate = videoMaxBitrate; | 177 this.videoMaxBitrate = videoMaxBitrate; |
181 this.videoCodec = videoCodec; | 178 this.videoCodec = videoCodec; |
182 this.videoCodecHwAcceleration = videoCodecHwAcceleration; | 179 this.videoCodecHwAcceleration = videoCodecHwAcceleration; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 } | 245 } |
249 | 246 |
250 public static PeerConnectionClient getInstance() { | 247 public static PeerConnectionClient getInstance() { |
251 return instance; | 248 return instance; |
252 } | 249 } |
253 | 250 |
254 public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options opti
ons) { | 251 public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options opti
ons) { |
255 this.options = options; | 252 this.options = options; |
256 } | 253 } |
257 | 254 |
258 public void createPeerConnectionFactory( | 255 public void createPeerConnectionFactory(final Context context, |
259 final Context context, | 256 final PeerConnectionParameters peerConnectionParameters, final PeerConnect
ionEvents events) { |
260 final PeerConnectionParameters peerConnectionParameters, | |
261 final PeerConnectionEvents events) { | |
262 this.peerConnectionParameters = peerConnectionParameters; | 257 this.peerConnectionParameters = peerConnectionParameters; |
263 this.events = events; | 258 this.events = events; |
264 videoCallEnabled = peerConnectionParameters.videoCallEnabled; | 259 videoCallEnabled = peerConnectionParameters.videoCallEnabled; |
265 // Reset variables to initial states. | 260 // Reset variables to initial states. |
266 this.context = null; | 261 this.context = null; |
267 factory = null; | 262 factory = null; |
268 peerConnection = null; | 263 peerConnection = null; |
269 preferIsac = false; | 264 preferIsac = false; |
270 videoCapturerStopped = false; | 265 videoCapturerStopped = false; |
271 isError = false; | 266 isError = false; |
(...skipping 10 matching lines...) Expand all Loading... |
282 statsTimer = new Timer(); | 277 statsTimer = new Timer(); |
283 | 278 |
284 executor.execute(new Runnable() { | 279 executor.execute(new Runnable() { |
285 @Override | 280 @Override |
286 public void run() { | 281 public void run() { |
287 createPeerConnectionFactoryInternal(context); | 282 createPeerConnectionFactoryInternal(context); |
288 } | 283 } |
289 }); | 284 }); |
290 } | 285 } |
291 | 286 |
292 public void createPeerConnection( | 287 public void createPeerConnection(final EglBase.Context renderEGLContext, |
293 final EglBase.Context renderEGLContext, | 288 final VideoRenderer.Callbacks localRender, final VideoRenderer.Callbacks r
emoteRender, |
294 final VideoRenderer.Callbacks localRender, | |
295 final VideoRenderer.Callbacks remoteRender, | |
296 final SignalingParameters signalingParameters) { | 289 final SignalingParameters signalingParameters) { |
297 if (peerConnectionParameters == null) { | 290 if (peerConnectionParameters == null) { |
298 Log.e(TAG, "Creating peer connection without initializing factory."); | 291 Log.e(TAG, "Creating peer connection without initializing factory."); |
299 return; | 292 return; |
300 } | 293 } |
301 this.localRender = localRender; | 294 this.localRender = localRender; |
302 this.remoteRender = remoteRender; | 295 this.remoteRender = remoteRender; |
303 this.signalingParameters = signalingParameters; | 296 this.signalingParameters = signalingParameters; |
304 executor.execute(new Runnable() { | 297 executor.execute(new Runnable() { |
305 @Override | 298 @Override |
(...skipping 16 matching lines...) Expand all Loading... |
322 closeInternal(); | 315 closeInternal(); |
323 } | 316 } |
324 }); | 317 }); |
325 } | 318 } |
326 | 319 |
327 public boolean isVideoCallEnabled() { | 320 public boolean isVideoCallEnabled() { |
328 return videoCallEnabled; | 321 return videoCallEnabled; |
329 } | 322 } |
330 | 323 |
331 private void createPeerConnectionFactoryInternal(Context context) { | 324 private void createPeerConnectionFactoryInternal(Context context) { |
332 PeerConnectionFactory.initializeInternalTracer(); | 325 PeerConnectionFactory.initializeInternalTracer(); |
333 if (peerConnectionParameters.tracing) { | 326 if (peerConnectionParameters.tracing) { |
334 PeerConnectionFactory.startInternalTracingCapture( | 327 PeerConnectionFactory.startInternalTracingCapture( |
335 Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator | 328 Environment.getExternalStorageDirectory().getAbsolutePath() + File.sep
arator |
336 + "webrtc-trace.txt"); | 329 + "webrtc-trace.txt"); |
337 } | 330 } |
338 Log.d(TAG, "Create peer connection factory. Use video: " + | 331 Log.d(TAG, |
339 peerConnectionParameters.videoCallEnabled); | 332 "Create peer connection factory. Use video: " + peerConnectionParameters
.videoCallEnabled); |
340 isError = false; | 333 isError = false; |
341 | 334 |
342 // Initialize field trials. | 335 // Initialize field trials. |
343 PeerConnectionFactory.initializeFieldTrials(""); | 336 PeerConnectionFactory.initializeFieldTrials(""); |
344 | 337 |
345 // Check preferred video codec. | 338 // Check preferred video codec. |
346 preferredVideoCodec = VIDEO_CODEC_VP8; | 339 preferredVideoCodec = VIDEO_CODEC_VP8; |
347 if (videoCallEnabled && peerConnectionParameters.videoCodec != null) { | 340 if (videoCallEnabled && peerConnectionParameters.videoCodec != null) { |
348 if (peerConnectionParameters.videoCodec.equals(VIDEO_CODEC_VP9)) { | 341 if (peerConnectionParameters.videoCodec.equals(VIDEO_CODEC_VP9)) { |
349 preferredVideoCodec = VIDEO_CODEC_VP9; | 342 preferredVideoCodec = VIDEO_CODEC_VP9; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 | 377 |
385 if (peerConnectionParameters.disableBuiltInNS) { | 378 if (peerConnectionParameters.disableBuiltInNS) { |
386 Log.d(TAG, "Disable built-in NS even if device supports it"); | 379 Log.d(TAG, "Disable built-in NS even if device supports it"); |
387 WebRtcAudioUtils.setWebRtcBasedNoiseSuppressor(true); | 380 WebRtcAudioUtils.setWebRtcBasedNoiseSuppressor(true); |
388 } else { | 381 } else { |
389 Log.d(TAG, "Enable built-in NS if device supports it"); | 382 Log.d(TAG, "Enable built-in NS if device supports it"); |
390 WebRtcAudioUtils.setWebRtcBasedNoiseSuppressor(false); | 383 WebRtcAudioUtils.setWebRtcBasedNoiseSuppressor(false); |
391 } | 384 } |
392 | 385 |
393 // Create peer connection factory. | 386 // Create peer connection factory. |
394 if (!PeerConnectionFactory.initializeAndroidGlobals(context, true, true, | 387 if (!PeerConnectionFactory.initializeAndroidGlobals( |
395 peerConnectionParameters.videoCodecHwAcceleration)) { | 388 context, true, true, peerConnectionParameters.videoCodecHwAccelerati
on)) { |
396 events.onPeerConnectionError("Failed to initializeAndroidGlobals"); | 389 events.onPeerConnectionError("Failed to initializeAndroidGlobals"); |
397 } | 390 } |
398 if (options != null) { | 391 if (options != null) { |
399 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas
k); | 392 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas
k); |
400 } | 393 } |
401 this.context = context; | 394 this.context = context; |
402 factory = new PeerConnectionFactory(options); | 395 factory = new PeerConnectionFactory(options); |
403 Log.d(TAG, "Peer connection factory created."); | 396 Log.d(TAG, "Peer connection factory created."); |
404 } | 397 } |
405 | 398 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 videoWidth = Math.min(videoWidth, MAX_VIDEO_WIDTH); | 434 videoWidth = Math.min(videoWidth, MAX_VIDEO_WIDTH); |
442 videoHeight = Math.min(videoHeight, MAX_VIDEO_HEIGHT); | 435 videoHeight = Math.min(videoHeight, MAX_VIDEO_HEIGHT); |
443 videoFps = Math.min(videoFps, MAX_VIDEO_FPS); | 436 videoFps = Math.min(videoFps, MAX_VIDEO_FPS); |
444 } | 437 } |
445 | 438 |
446 // Create audio constraints. | 439 // Create audio constraints. |
447 audioConstraints = new MediaConstraints(); | 440 audioConstraints = new MediaConstraints(); |
448 // added for audio performance measurements | 441 // added for audio performance measurements |
449 if (peerConnectionParameters.noAudioProcessing) { | 442 if (peerConnectionParameters.noAudioProcessing) { |
450 Log.d(TAG, "Disabling audio processing"); | 443 Log.d(TAG, "Disabling audio processing"); |
451 audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 444 audioConstraints.mandatory.add( |
452 AUDIO_ECHO_CANCELLATION_CONSTRAINT, "false")); | 445 new MediaConstraints.KeyValuePair(AUDIO_ECHO_CANCELLATION_CONSTRAINT,
"false")); |
453 audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 446 audioConstraints.mandatory.add( |
454 AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT, "false")); | 447 new MediaConstraints.KeyValuePair(AUDIO_AUTO_GAIN_CONTROL_CONSTRAINT,
"false")); |
455 audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 448 audioConstraints.mandatory.add( |
456 AUDIO_HIGH_PASS_FILTER_CONSTRAINT, "false")); | 449 new MediaConstraints.KeyValuePair(AUDIO_HIGH_PASS_FILTER_CONSTRAINT, "
false")); |
457 audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 450 audioConstraints.mandatory.add( |
458 AUDIO_NOISE_SUPPRESSION_CONSTRAINT , "false")); | 451 new MediaConstraints.KeyValuePair(AUDIO_NOISE_SUPPRESSION_CONSTRAINT,
"false")); |
459 } | 452 } |
460 if (peerConnectionParameters.enableLevelControl) { | 453 if (peerConnectionParameters.enableLevelControl) { |
461 Log.d(TAG, "Enabling level control."); | 454 Log.d(TAG, "Enabling level control."); |
462 audioConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 455 audioConstraints.mandatory.add( |
463 AUDIO_LEVEL_CONTROL_CONSTRAINT, "true")); | 456 new MediaConstraints.KeyValuePair(AUDIO_LEVEL_CONTROL_CONSTRAINT, "tru
e")); |
464 } | 457 } |
465 // Create SDP constraints. | 458 // Create SDP constraints. |
466 sdpMediaConstraints = new MediaConstraints(); | 459 sdpMediaConstraints = new MediaConstraints(); |
467 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 460 sdpMediaConstraints.mandatory.add( |
468 "OfferToReceiveAudio", "true")); | 461 new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); |
469 if (videoCallEnabled || peerConnectionParameters.loopback) { | 462 if (videoCallEnabled || peerConnectionParameters.loopback) { |
470 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 463 sdpMediaConstraints.mandatory.add( |
471 "OfferToReceiveVideo", "true")); | 464 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); |
472 } else { | 465 } else { |
473 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 466 sdpMediaConstraints.mandatory.add( |
474 "OfferToReceiveVideo", "false")); | 467 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false")); |
475 } | 468 } |
476 } | 469 } |
477 | 470 |
478 private void createCapturer(CameraEnumerator enumerator) { | 471 private void createCapturer(CameraEnumerator enumerator) { |
479 final String[] deviceNames = enumerator.getDeviceNames(); | 472 final String[] deviceNames = enumerator.getDeviceNames(); |
480 | 473 |
481 // First, try to find front facing camera | 474 // First, try to find front facing camera |
482 Logging.d(TAG, "Looking for front facing cameras."); | 475 Logging.d(TAG, "Looking for front facing cameras."); |
483 for (String deviceName : deviceNames) { | 476 for (String deviceName : deviceNames) { |
484 if (enumerator.isFrontFacing(deviceName)) { | 477 if (enumerator.isFrontFacing(deviceName)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
524 new PeerConnection.RTCConfiguration(signalingParameters.iceServers); | 517 new PeerConnection.RTCConfiguration(signalingParameters.iceServers); |
525 // TCP candidates are only useful when connecting to a server that supports | 518 // TCP candidates are only useful when connecting to a server that supports |
526 // ICE-TCP. | 519 // ICE-TCP. |
527 rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; | 520 rtcConfig.tcpCandidatePolicy = PeerConnection.TcpCandidatePolicy.DISABLED; |
528 rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE; | 521 rtcConfig.bundlePolicy = PeerConnection.BundlePolicy.MAXBUNDLE; |
529 rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE; | 522 rtcConfig.rtcpMuxPolicy = PeerConnection.RtcpMuxPolicy.REQUIRE; |
530 rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy
.GATHER_CONTINUALLY; | 523 rtcConfig.continualGatheringPolicy = PeerConnection.ContinualGatheringPolicy
.GATHER_CONTINUALLY; |
531 // Use ECDSA encryption. | 524 // Use ECDSA encryption. |
532 rtcConfig.keyType = PeerConnection.KeyType.ECDSA; | 525 rtcConfig.keyType = PeerConnection.KeyType.ECDSA; |
533 | 526 |
534 peerConnection = factory.createPeerConnection( | 527 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb
server); |
535 rtcConfig, pcConstraints, pcObserver); | |
536 isInitiator = false; | 528 isInitiator = false; |
537 | 529 |
538 // Set default WebRTC tracing and INFO libjingle logging. | 530 // Set default WebRTC tracing and INFO libjingle logging. |
539 // NOTE: this _must_ happen while |factory| is alive! | 531 // NOTE: this _must_ happen while |factory| is alive! |
540 Logging.enableTracing( | 532 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT
)); |
541 "logcat:", | |
542 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT)); | |
543 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); | 533 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); |
544 | 534 |
545 mediaStream = factory.createLocalMediaStream("ARDAMS"); | 535 mediaStream = factory.createLocalMediaStream("ARDAMS"); |
546 if (videoCallEnabled) { | 536 if (videoCallEnabled) { |
547 if (peerConnectionParameters.useCamera2) { | 537 if (peerConnectionParameters.useCamera2) { |
548 if (!peerConnectionParameters.captureToTexture) { | 538 if (!peerConnectionParameters.captureToTexture) { |
549 reportError(context.getString(R.string.camera2_texture_only_error)); | 539 reportError(context.getString(R.string.camera2_texture_only_error)); |
550 return; | 540 return; |
551 } | 541 } |
552 | 542 |
(...skipping 12 matching lines...) Expand all Loading... |
565 } | 555 } |
566 | 556 |
567 mediaStream.addTrack(createAudioTrack()); | 557 mediaStream.addTrack(createAudioTrack()); |
568 peerConnection.addStream(mediaStream); | 558 peerConnection.addStream(mediaStream); |
569 if (videoCallEnabled) { | 559 if (videoCallEnabled) { |
570 findVideoSender(); | 560 findVideoSender(); |
571 } | 561 } |
572 | 562 |
573 if (peerConnectionParameters.aecDump) { | 563 if (peerConnectionParameters.aecDump) { |
574 try { | 564 try { |
575 aecDumpFileDescriptor = ParcelFileDescriptor.open( | 565 aecDumpFileDescriptor = |
576 new File(Environment.getExternalStorageDirectory().getPath() | 566 ParcelFileDescriptor.open(new File(Environment.getExternalStorageDir
ectory().getPath() |
577 + File.separator | 567 + File.separator + "Download/audio.aec
dump"), |
578 + "Download/audio.aecdump"), | 568 ParcelFileDescriptor.MODE_READ_WRITE | ParcelFileDescriptor.MODE
_CREATE |
579 ParcelFileDescriptor.MODE_READ_WRITE | | 569 | ParcelFileDescriptor.MODE_TRUNCATE); |
580 ParcelFileDescriptor.MODE_CREATE | | |
581 ParcelFileDescriptor.MODE_TRUNCATE); | |
582 factory.startAecDump(aecDumpFileDescriptor.getFd(), -1); | 570 factory.startAecDump(aecDumpFileDescriptor.getFd(), -1); |
583 } catch(IOException e) { | 571 } catch (IOException e) { |
584 Log.e(TAG, "Can not open aecdump file", e); | 572 Log.e(TAG, "Can not open aecdump file", e); |
585 } | 573 } |
586 } | 574 } |
587 | 575 |
588 Log.d(TAG, "Peer connection created."); | 576 Log.d(TAG, "Peer connection created."); |
589 } | 577 } |
590 | 578 |
591 private void closeInternal() { | 579 private void closeInternal() { |
592 if (factory != null && peerConnectionParameters.aecDump) { | 580 if (factory != null && peerConnectionParameters.aecDump) { |
593 factory.stopAecDump(); | 581 factory.stopAecDump(); |
594 } | 582 } |
595 Log.d(TAG, "Closing peer connection."); | 583 Log.d(TAG, "Closing peer connection."); |
596 statsTimer.cancel(); | 584 statsTimer.cancel(); |
597 if (peerConnection != null) { | 585 if (peerConnection != null) { |
598 peerConnection.dispose(); | 586 peerConnection.dispose(); |
599 peerConnection = null; | 587 peerConnection = null; |
600 } | 588 } |
601 Log.d(TAG, "Closing audio source."); | 589 Log.d(TAG, "Closing audio source."); |
602 if (audioSource != null) { | 590 if (audioSource != null) { |
603 audioSource.dispose(); | 591 audioSource.dispose(); |
604 audioSource = null; | 592 audioSource = null; |
605 } | 593 } |
606 Log.d(TAG, "Stopping capture."); | 594 Log.d(TAG, "Stopping capture."); |
607 if (videoCapturer != null) { | 595 if (videoCapturer != null) { |
608 try { | 596 try { |
609 videoCapturer.stopCapture(); | 597 videoCapturer.stopCapture(); |
610 } catch(InterruptedException e) { | 598 } catch (InterruptedException e) { |
611 throw new RuntimeException(e); | 599 throw new RuntimeException(e); |
612 } | 600 } |
613 videoCapturer.dispose(); | 601 videoCapturer.dispose(); |
614 videoCapturer = null; | 602 videoCapturer = null; |
615 } | 603 } |
616 Log.d(TAG, "Closing video source."); | 604 Log.d(TAG, "Closing video source."); |
617 if (videoSource != null) { | 605 if (videoSource != null) { |
618 videoSource.dispose(); | 606 videoSource.dispose(); |
619 videoSource = null; | 607 videoSource = null; |
620 } | 608 } |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 return; | 754 return; |
767 } | 755 } |
768 String sdpDescription = sdp.description; | 756 String sdpDescription = sdp.description; |
769 if (preferIsac) { | 757 if (preferIsac) { |
770 sdpDescription = preferCodec(sdpDescription, AUDIO_CODEC_ISAC, true); | 758 sdpDescription = preferCodec(sdpDescription, AUDIO_CODEC_ISAC, true); |
771 } | 759 } |
772 if (videoCallEnabled) { | 760 if (videoCallEnabled) { |
773 sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, fals
e); | 761 sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, fals
e); |
774 } | 762 } |
775 if (peerConnectionParameters.audioStartBitrate > 0) { | 763 if (peerConnectionParameters.audioStartBitrate > 0) { |
776 sdpDescription = setStartBitrate(AUDIO_CODEC_OPUS, false, | 764 sdpDescription = setStartBitrate( |
777 sdpDescription, peerConnectionParameters.audioStartBitrate); | 765 AUDIO_CODEC_OPUS, false, sdpDescription, peerConnectionParameters.
audioStartBitrate); |
778 } | 766 } |
779 Log.d(TAG, "Set remote SDP."); | 767 Log.d(TAG, "Set remote SDP."); |
780 SessionDescription sdpRemote = new SessionDescription( | 768 SessionDescription sdpRemote = new SessionDescription(sdp.type, sdpDescr
iption); |
781 sdp.type, sdpDescription); | |
782 peerConnection.setRemoteDescription(sdpObserver, sdpRemote); | 769 peerConnection.setRemoteDescription(sdpObserver, sdpRemote); |
783 } | 770 } |
784 }); | 771 }); |
785 } | 772 } |
786 | 773 |
787 public void stopVideoSource() { | 774 public void stopVideoSource() { |
788 executor.execute(new Runnable() { | 775 executor.execute(new Runnable() { |
789 @Override | 776 @Override |
790 public void run() { | 777 public void run() { |
791 if (videoCapturer != null && !videoCapturerStopped) { | 778 if (videoCapturer != null && !videoCapturerStopped) { |
792 Log.d(TAG, "Stop video source."); | 779 Log.d(TAG, "Stop video source."); |
793 try { | 780 try { |
794 videoCapturer.stopCapture(); | 781 videoCapturer.stopCapture(); |
795 } catch (InterruptedException e) {} | 782 } catch (InterruptedException e) { |
| 783 } |
796 videoCapturerStopped = true; | 784 videoCapturerStopped = true; |
797 } | 785 } |
798 } | 786 } |
799 }); | 787 }); |
800 } | 788 } |
801 | 789 |
802 public void startVideoSource() { | 790 public void startVideoSource() { |
803 executor.execute(new Runnable() { | 791 executor.execute(new Runnable() { |
804 @Override | 792 @Override |
805 public void run() { | 793 public void run() { |
(...skipping 20 matching lines...) Expand all Loading... |
826 } | 814 } |
827 | 815 |
828 RtpParameters parameters = localVideoSender.getParameters(); | 816 RtpParameters parameters = localVideoSender.getParameters(); |
829 if (parameters.encodings.size() == 0) { | 817 if (parameters.encodings.size() == 0) { |
830 Log.w(TAG, "RtpParameters are not ready."); | 818 Log.w(TAG, "RtpParameters are not ready."); |
831 return; | 819 return; |
832 } | 820 } |
833 | 821 |
834 for (RtpParameters.Encoding encoding : parameters.encodings) { | 822 for (RtpParameters.Encoding encoding : parameters.encodings) { |
835 // Null value means no limit. | 823 // Null value means no limit. |
836 encoding.maxBitrateBps = maxBitrateKbps == null | 824 encoding.maxBitrateBps = maxBitrateKbps == null ? null : maxBitrateKbp
s * BPS_IN_KBPS; |
837 ? null | |
838 : maxBitrateKbps * BPS_IN_KBPS; | |
839 } | 825 } |
840 if (!localVideoSender.setParameters(parameters)) { | 826 if (!localVideoSender.setParameters(parameters)) { |
841 Log.e(TAG, "RtpSender.setParameters failed."); | 827 Log.e(TAG, "RtpSender.setParameters failed."); |
842 } | 828 } |
843 Log.d(TAG, "Configured max video bitrate to: " + maxBitrateKbps); | 829 Log.d(TAG, "Configured max video bitrate to: " + maxBitrateKbps); |
844 } | 830 } |
845 }); | 831 }); |
846 } | 832 } |
847 | 833 |
848 private void reportError(final String errorMessage) { | 834 private void reportError(final String errorMessage) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 if (sender.track() != null) { | 866 if (sender.track() != null) { |
881 String trackType = sender.track().kind(); | 867 String trackType = sender.track().kind(); |
882 if (trackType.equals(VIDEO_TRACK_TYPE)) { | 868 if (trackType.equals(VIDEO_TRACK_TYPE)) { |
883 Log.d(TAG, "Found video sender."); | 869 Log.d(TAG, "Found video sender."); |
884 localVideoSender = sender; | 870 localVideoSender = sender; |
885 } | 871 } |
886 } | 872 } |
887 } | 873 } |
888 } | 874 } |
889 | 875 |
890 private static String setStartBitrate(String codec, boolean isVideoCodec, | 876 private static String setStartBitrate( |
891 String sdpDescription, int bitrateKbps) { | 877 String codec, boolean isVideoCodec, String sdpDescription, int bitrateKbps
) { |
892 String[] lines = sdpDescription.split("\r\n"); | 878 String[] lines = sdpDescription.split("\r\n"); |
893 int rtpmapLineIndex = -1; | 879 int rtpmapLineIndex = -1; |
894 boolean sdpFormatUpdated = false; | 880 boolean sdpFormatUpdated = false; |
895 String codecRtpMap = null; | 881 String codecRtpMap = null; |
896 // Search for codec rtpmap in format | 882 // Search for codec rtpmap in format |
897 // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding paramete
rs>] | 883 // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding paramete
rs>] |
898 String regex = "^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$"; | 884 String regex = "^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$"; |
899 Pattern codecPattern = Pattern.compile(regex); | 885 Pattern codecPattern = Pattern.compile(regex); |
900 for (int i = 0; i < lines.length; i++) { | 886 for (int i = 0; i < lines.length; i++) { |
901 Matcher codecMatcher = codecPattern.matcher(lines[i]); | 887 Matcher codecMatcher = codecPattern.matcher(lines[i]); |
902 if (codecMatcher.matches()) { | 888 if (codecMatcher.matches()) { |
903 codecRtpMap = codecMatcher.group(1); | 889 codecRtpMap = codecMatcher.group(1); |
904 rtpmapLineIndex = i; | 890 rtpmapLineIndex = i; |
905 break; | 891 break; |
906 } | 892 } |
907 } | 893 } |
908 if (codecRtpMap == null) { | 894 if (codecRtpMap == null) { |
909 Log.w(TAG, "No rtpmap for " + codec + " codec"); | 895 Log.w(TAG, "No rtpmap for " + codec + " codec"); |
910 return sdpDescription; | 896 return sdpDescription; |
911 } | 897 } |
912 Log.d(TAG, "Found " + codec + " rtpmap " + codecRtpMap | 898 Log.d(TAG, "Found " + codec + " rtpmap " + codecRtpMap + " at " + lines[rtpm
apLineIndex]); |
913 + " at " + lines[rtpmapLineIndex]); | |
914 | 899 |
915 // Check if a=fmtp string already exist in remote SDP for this codec and | 900 // Check if a=fmtp string already exist in remote SDP for this codec and |
916 // update it with new bitrate parameter. | 901 // update it with new bitrate parameter. |
917 regex = "^a=fmtp:" + codecRtpMap + " \\w+=\\d+.*[\r]?$"; | 902 regex = "^a=fmtp:" + codecRtpMap + " \\w+=\\d+.*[\r]?$"; |
918 codecPattern = Pattern.compile(regex); | 903 codecPattern = Pattern.compile(regex); |
919 for (int i = 0; i < lines.length; i++) { | 904 for (int i = 0; i < lines.length; i++) { |
920 Matcher codecMatcher = codecPattern.matcher(lines[i]); | 905 Matcher codecMatcher = codecPattern.matcher(lines[i]); |
921 if (codecMatcher.matches()) { | 906 if (codecMatcher.matches()) { |
922 Log.d(TAG, "Found " + codec + " " + lines[i]); | 907 Log.d(TAG, "Found " + codec + " " + lines[i]); |
923 if (isVideoCodec) { | 908 if (isVideoCodec) { |
924 lines[i] += "; " + VIDEO_CODEC_PARAM_START_BITRATE | 909 lines[i] += "; " + VIDEO_CODEC_PARAM_START_BITRATE + "=" + bitrateKbps
; |
925 + "=" + bitrateKbps; | |
926 } else { | 910 } else { |
927 lines[i] += "; " + AUDIO_CODEC_PARAM_BITRATE | 911 lines[i] += "; " + AUDIO_CODEC_PARAM_BITRATE + "=" + (bitrateKbps * 10
00); |
928 + "=" + (bitrateKbps * 1000); | |
929 } | 912 } |
930 Log.d(TAG, "Update remote SDP line: " + lines[i]); | 913 Log.d(TAG, "Update remote SDP line: " + lines[i]); |
931 sdpFormatUpdated = true; | 914 sdpFormatUpdated = true; |
932 break; | 915 break; |
933 } | 916 } |
934 } | 917 } |
935 | 918 |
936 StringBuilder newSdpDescription = new StringBuilder(); | 919 StringBuilder newSdpDescription = new StringBuilder(); |
937 for (int i = 0; i < lines.length; i++) { | 920 for (int i = 0; i < lines.length; i++) { |
938 newSdpDescription.append(lines[i]).append("\r\n"); | 921 newSdpDescription.append(lines[i]).append("\r\n"); |
939 // Append new a=fmtp line if no such line exist for a codec. | 922 // Append new a=fmtp line if no such line exist for a codec. |
940 if (!sdpFormatUpdated && i == rtpmapLineIndex) { | 923 if (!sdpFormatUpdated && i == rtpmapLineIndex) { |
941 String bitrateSet; | 924 String bitrateSet; |
942 if (isVideoCodec) { | 925 if (isVideoCodec) { |
943 bitrateSet = "a=fmtp:" + codecRtpMap + " " | 926 bitrateSet = |
944 + VIDEO_CODEC_PARAM_START_BITRATE + "=" + bitrateKbps; | 927 "a=fmtp:" + codecRtpMap + " " + VIDEO_CODEC_PARAM_START_BITRATE +
"=" + bitrateKbps; |
945 } else { | 928 } else { |
946 bitrateSet = "a=fmtp:" + codecRtpMap + " " | 929 bitrateSet = "a=fmtp:" + codecRtpMap + " " + AUDIO_CODEC_PARAM_BITRATE
+ "=" |
947 + AUDIO_CODEC_PARAM_BITRATE + "=" + (bitrateKbps * 1000); | 930 + (bitrateKbps * 1000); |
948 } | 931 } |
949 Log.d(TAG, "Add remote SDP line: " + bitrateSet); | 932 Log.d(TAG, "Add remote SDP line: " + bitrateSet); |
950 newSdpDescription.append(bitrateSet).append("\r\n"); | 933 newSdpDescription.append(bitrateSet).append("\r\n"); |
951 } | 934 } |
952 | |
953 } | 935 } |
954 return newSdpDescription.toString(); | 936 return newSdpDescription.toString(); |
955 } | 937 } |
956 | 938 |
957 private static String preferCodec( | 939 private static String preferCodec(String sdpDescription, String codec, boolean
isAudio) { |
958 String sdpDescription, String codec, boolean isAudio) { | |
959 String[] lines = sdpDescription.split("\r\n"); | 940 String[] lines = sdpDescription.split("\r\n"); |
960 int mLineIndex = -1; | 941 int mLineIndex = -1; |
961 String codecRtpMap = null; | 942 String codecRtpMap = null; |
962 // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding paramete
rs>] | 943 // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding paramete
rs>] |
963 String regex = "^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$"; | 944 String regex = "^a=rtpmap:(\\d+) " + codec + "(/\\d+)+[\r]?$"; |
964 Pattern codecPattern = Pattern.compile(regex); | 945 Pattern codecPattern = Pattern.compile(regex); |
965 String mediaDescription = "m=video "; | 946 String mediaDescription = "m=video "; |
966 if (isAudio) { | 947 if (isAudio) { |
967 mediaDescription = "m=audio "; | 948 mediaDescription = "m=audio "; |
968 } | 949 } |
969 for (int i = 0; (i < lines.length) | 950 for (int i = 0; (i < lines.length) && (mLineIndex == -1 || codecRtpMap == nu
ll); i++) { |
970 && (mLineIndex == -1 || codecRtpMap == null); i++) { | |
971 if (lines[i].startsWith(mediaDescription)) { | 951 if (lines[i].startsWith(mediaDescription)) { |
972 mLineIndex = i; | 952 mLineIndex = i; |
973 continue; | 953 continue; |
974 } | 954 } |
975 Matcher codecMatcher = codecPattern.matcher(lines[i]); | 955 Matcher codecMatcher = codecPattern.matcher(lines[i]); |
976 if (codecMatcher.matches()) { | 956 if (codecMatcher.matches()) { |
977 codecRtpMap = codecMatcher.group(1); | 957 codecRtpMap = codecMatcher.group(1); |
978 } | 958 } |
979 } | 959 } |
980 if (mLineIndex == -1) { | 960 if (mLineIndex == -1) { |
981 Log.w(TAG, "No " + mediaDescription + " line, so can't prefer " + codec); | 961 Log.w(TAG, "No " + mediaDescription + " line, so can't prefer " + codec); |
982 return sdpDescription; | 962 return sdpDescription; |
983 } | 963 } |
984 if (codecRtpMap == null) { | 964 if (codecRtpMap == null) { |
985 Log.w(TAG, "No rtpmap for " + codec); | 965 Log.w(TAG, "No rtpmap for " + codec); |
986 return sdpDescription; | 966 return sdpDescription; |
987 } | 967 } |
988 Log.d(TAG, "Found " + codec + " rtpmap " + codecRtpMap + ", prefer at " | 968 Log.d(TAG, "Found " + codec + " rtpmap " + codecRtpMap + ", prefer at " + li
nes[mLineIndex]); |
989 + lines[mLineIndex]); | |
990 String[] origMLineParts = lines[mLineIndex].split(" "); | 969 String[] origMLineParts = lines[mLineIndex].split(" "); |
991 if (origMLineParts.length > 3) { | 970 if (origMLineParts.length > 3) { |
992 StringBuilder newMLine = new StringBuilder(); | 971 StringBuilder newMLine = new StringBuilder(); |
993 int origPartIndex = 0; | 972 int origPartIndex = 0; |
994 // Format is: m=<media> <port> <proto> <fmt> ... | 973 // Format is: m=<media> <port> <proto> <fmt> ... |
995 newMLine.append(origMLineParts[origPartIndex++]).append(" "); | 974 newMLine.append(origMLineParts[origPartIndex++]).append(" "); |
996 newMLine.append(origMLineParts[origPartIndex++]).append(" "); | 975 newMLine.append(origMLineParts[origPartIndex++]).append(" "); |
997 newMLine.append(origMLineParts[origPartIndex++]).append(" "); | 976 newMLine.append(origMLineParts[origPartIndex++]).append(" "); |
998 newMLine.append(codecRtpMap); | 977 newMLine.append(codecRtpMap); |
999 for (; origPartIndex < origMLineParts.length; origPartIndex++) { | 978 for (; origPartIndex < origMLineParts.length; origPartIndex++) { |
(...skipping 18 matching lines...) Expand all Loading... |
1018 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); | 997 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); |
1019 for (IceCandidate candidate : queuedRemoteCandidates) { | 998 for (IceCandidate candidate : queuedRemoteCandidates) { |
1020 peerConnection.addIceCandidate(candidate); | 999 peerConnection.addIceCandidate(candidate); |
1021 } | 1000 } |
1022 queuedRemoteCandidates = null; | 1001 queuedRemoteCandidates = null; |
1023 } | 1002 } |
1024 } | 1003 } |
1025 | 1004 |
1026 private void switchCameraInternal() { | 1005 private void switchCameraInternal() { |
1027 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer ==
null) { | 1006 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer ==
null) { |
1028 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Erro
r : " | 1007 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Erro
r : " + isError |
1029 + isError + ". Number of cameras: " + numberOfCameras); | 1008 + ". Number of cameras: " + numberOfCameras); |
1030 return; // No video is sent or only one camera is available or error happ
ened. | 1009 return; // No video is sent or only one camera is available or error happe
ned. |
1031 } | 1010 } |
1032 Log.d(TAG, "Switch camera"); | 1011 Log.d(TAG, "Switch camera"); |
1033 videoCapturer.switchCamera(null); | 1012 videoCapturer.switchCamera(null); |
1034 } | 1013 } |
1035 | 1014 |
1036 public void switchCamera() { | 1015 public void switchCamera() { |
1037 executor.execute(new Runnable() { | 1016 executor.execute(new Runnable() { |
1038 @Override | 1017 @Override |
1039 public void run() { | 1018 public void run() { |
1040 switchCameraInternal(); | 1019 switchCameraInternal(); |
1041 } | 1020 } |
1042 }); | 1021 }); |
1043 } | 1022 } |
1044 | 1023 |
1045 public void changeCaptureFormat(final int width, final int height, final int f
ramerate) { | 1024 public void changeCaptureFormat(final int width, final int height, final int f
ramerate) { |
1046 executor.execute(new Runnable() { | 1025 executor.execute(new Runnable() { |
1047 @Override | 1026 @Override |
1048 public void run() { | 1027 public void run() { |
1049 changeCaptureFormatInternal(width, height, framerate); | 1028 changeCaptureFormatInternal(width, height, framerate); |
1050 } | 1029 } |
1051 }); | 1030 }); |
1052 } | 1031 } |
1053 | 1032 |
1054 private void changeCaptureFormatInternal(int width, int height, int framerate)
{ | 1033 private void changeCaptureFormatInternal(int width, int height, int framerate)
{ |
1055 if (!videoCallEnabled || isError || videoCapturer == null) { | 1034 if (!videoCallEnabled || isError || videoCapturer == null) { |
1056 Log.e(TAG, "Failed to change capture format. Video: " + videoCallEnabled +
". Error : " | 1035 Log.e(TAG, |
1057 + isError); | 1036 "Failed to change capture format. Video: " + videoCallEnabled + ". Err
or : " + isError); |
1058 return; | 1037 return; |
1059 } | 1038 } |
1060 Log.d(TAG, "changeCaptureFormat: " + width + "x" + height + "@" + framerate)
; | 1039 Log.d(TAG, "changeCaptureFormat: " + width + "x" + height + "@" + framerate)
; |
1061 videoSource.adaptOutputFormat(width, height, framerate); | 1040 videoSource.adaptOutputFormat(width, height, framerate); |
1062 } | 1041 } |
1063 | 1042 |
1064 // Implementation detail: observe ICE & stream changes and react accordingly. | 1043 // Implementation detail: observe ICE & stream changes and react accordingly. |
1065 private class PCObserver implements PeerConnection.Observer { | 1044 private class PCObserver implements PeerConnection.Observer { |
1066 @Override | 1045 @Override |
1067 public void onIceCandidate(final IceCandidate candidate){ | 1046 public void onIceCandidate(final IceCandidate candidate) { |
1068 executor.execute(new Runnable() { | 1047 executor.execute(new Runnable() { |
1069 @Override | 1048 @Override |
1070 public void run() { | 1049 public void run() { |
1071 events.onIceCandidate(candidate); | 1050 events.onIceCandidate(candidate); |
1072 } | 1051 } |
1073 }); | 1052 }); |
1074 } | 1053 } |
1075 | 1054 |
1076 @Override | 1055 @Override |
1077 public void onIceCandidatesRemoved(final IceCandidate[] candidates) { | 1056 public void onIceCandidatesRemoved(final IceCandidate[] candidates) { |
1078 executor.execute(new Runnable() { | 1057 executor.execute(new Runnable() { |
1079 @Override | 1058 @Override |
1080 public void run() { | 1059 public void run() { |
1081 events.onIceCandidatesRemoved(candidates); | 1060 events.onIceCandidatesRemoved(candidates); |
1082 } | 1061 } |
1083 }); | 1062 }); |
1084 } | 1063 } |
1085 | 1064 |
1086 @Override | 1065 @Override |
1087 public void onSignalingChange( | 1066 public void onSignalingChange(PeerConnection.SignalingState newState) { |
1088 PeerConnection.SignalingState newState) { | |
1089 Log.d(TAG, "SignalingState: " + newState); | 1067 Log.d(TAG, "SignalingState: " + newState); |
1090 } | 1068 } |
1091 | 1069 |
1092 @Override | 1070 @Override |
1093 public void onIceConnectionChange( | 1071 public void onIceConnectionChange(final PeerConnection.IceConnectionState ne
wState) { |
1094 final PeerConnection.IceConnectionState newState) { | |
1095 executor.execute(new Runnable() { | 1072 executor.execute(new Runnable() { |
1096 @Override | 1073 @Override |
1097 public void run() { | 1074 public void run() { |
1098 Log.d(TAG, "IceConnectionState: " + newState); | 1075 Log.d(TAG, "IceConnectionState: " + newState); |
1099 if (newState == IceConnectionState.CONNECTED) { | 1076 if (newState == IceConnectionState.CONNECTED) { |
1100 events.onIceConnected(); | 1077 events.onIceConnected(); |
1101 } else if (newState == IceConnectionState.DISCONNECTED) { | 1078 } else if (newState == IceConnectionState.DISCONNECTED) { |
1102 events.onIceDisconnected(); | 1079 events.onIceDisconnected(); |
1103 } else if (newState == IceConnectionState.FAILED) { | 1080 } else if (newState == IceConnectionState.FAILED) { |
1104 reportError("ICE connection failed."); | 1081 reportError("ICE connection failed."); |
1105 } | 1082 } |
1106 } | 1083 } |
1107 }); | 1084 }); |
1108 } | 1085 } |
1109 | 1086 |
1110 @Override | 1087 @Override |
1111 public void onIceGatheringChange( | 1088 public void onIceGatheringChange(PeerConnection.IceGatheringState newState)
{ |
1112 PeerConnection.IceGatheringState newState) { | |
1113 Log.d(TAG, "IceGatheringState: " + newState); | 1089 Log.d(TAG, "IceGatheringState: " + newState); |
1114 } | 1090 } |
1115 | 1091 |
1116 @Override | 1092 @Override |
1117 public void onIceConnectionReceivingChange(boolean receiving) { | 1093 public void onIceConnectionReceivingChange(boolean receiving) { |
1118 Log.d(TAG, "IceConnectionReceiving changed to " + receiving); | 1094 Log.d(TAG, "IceConnectionReceiving changed to " + receiving); |
1119 } | 1095 } |
1120 | 1096 |
1121 @Override | 1097 @Override |
1122 public void onAddStream(final MediaStream stream){ | 1098 public void onAddStream(final MediaStream stream) { |
1123 executor.execute(new Runnable() { | 1099 executor.execute(new Runnable() { |
1124 @Override | 1100 @Override |
1125 public void run() { | 1101 public void run() { |
1126 if (peerConnection == null || isError) { | 1102 if (peerConnection == null || isError) { |
1127 return; | 1103 return; |
1128 } | 1104 } |
1129 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { | 1105 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { |
1130 reportError("Weird-looking stream: " + stream); | 1106 reportError("Weird-looking stream: " + stream); |
1131 return; | 1107 return; |
1132 } | 1108 } |
1133 if (stream.videoTracks.size() == 1) { | 1109 if (stream.videoTracks.size() == 1) { |
1134 remoteVideoTrack = stream.videoTracks.get(0); | 1110 remoteVideoTrack = stream.videoTracks.get(0); |
1135 remoteVideoTrack.setEnabled(renderVideo); | 1111 remoteVideoTrack.setEnabled(renderVideo); |
1136 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); | 1112 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); |
1137 } | 1113 } |
1138 } | 1114 } |
1139 }); | 1115 }); |
1140 } | 1116 } |
1141 | 1117 |
1142 @Override | 1118 @Override |
1143 public void onRemoveStream(final MediaStream stream){ | 1119 public void onRemoveStream(final MediaStream stream) { |
1144 executor.execute(new Runnable() { | 1120 executor.execute(new Runnable() { |
1145 @Override | 1121 @Override |
1146 public void run() { | 1122 public void run() { |
1147 remoteVideoTrack = null; | 1123 remoteVideoTrack = null; |
1148 } | 1124 } |
1149 }); | 1125 }); |
1150 } | 1126 } |
1151 | 1127 |
1152 @Override | 1128 @Override |
1153 public void onDataChannel(final DataChannel dc) { | 1129 public void onDataChannel(final DataChannel dc) { |
1154 reportError("AppRTC doesn't use data channels, but got: " + dc.label() | 1130 reportError("AppRTC doesn't use data channels, but got: " + dc.label() + "
anyway!"); |
1155 + " anyway!"); | |
1156 } | 1131 } |
1157 | 1132 |
1158 @Override | 1133 @Override |
1159 public void onRenegotiationNeeded() { | 1134 public void onRenegotiationNeeded() { |
1160 // No need to do anything; AppRTC follows a pre-agreed-upon | 1135 // No need to do anything; AppRTC follows a pre-agreed-upon |
1161 // signaling/negotiation protocol. | 1136 // signaling/negotiation protocol. |
1162 } | 1137 } |
1163 } | 1138 } |
1164 | 1139 |
1165 // Implementation detail: handle offer creation/signaling and answer setting, | 1140 // Implementation detail: handle offer creation/signaling and answer setting, |
1166 // as well as adding remote ICE candidates once the answer SDP is set. | 1141 // as well as adding remote ICE candidates once the answer SDP is set. |
1167 private class SDPObserver implements SdpObserver { | 1142 private class SDPObserver implements SdpObserver { |
1168 @Override | 1143 @Override |
1169 public void onCreateSuccess(final SessionDescription origSdp) { | 1144 public void onCreateSuccess(final SessionDescription origSdp) { |
1170 if (localSdp != null) { | 1145 if (localSdp != null) { |
1171 reportError("Multiple SDP create."); | 1146 reportError("Multiple SDP create."); |
1172 return; | 1147 return; |
1173 } | 1148 } |
1174 String sdpDescription = origSdp.description; | 1149 String sdpDescription = origSdp.description; |
1175 if (preferIsac) { | 1150 if (preferIsac) { |
1176 sdpDescription = preferCodec(sdpDescription, AUDIO_CODEC_ISAC, true); | 1151 sdpDescription = preferCodec(sdpDescription, AUDIO_CODEC_ISAC, true); |
1177 } | 1152 } |
1178 if (videoCallEnabled) { | 1153 if (videoCallEnabled) { |
1179 sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, false)
; | 1154 sdpDescription = preferCodec(sdpDescription, preferredVideoCodec, false)
; |
1180 } | 1155 } |
1181 final SessionDescription sdp = new SessionDescription( | 1156 final SessionDescription sdp = new SessionDescription(origSdp.type, sdpDes
cription); |
1182 origSdp.type, sdpDescription); | |
1183 localSdp = sdp; | 1157 localSdp = sdp; |
1184 executor.execute(new Runnable() { | 1158 executor.execute(new Runnable() { |
1185 @Override | 1159 @Override |
1186 public void run() { | 1160 public void run() { |
1187 if (peerConnection != null && !isError) { | 1161 if (peerConnection != null && !isError) { |
1188 Log.d(TAG, "Set local SDP from " + sdp.type); | 1162 Log.d(TAG, "Set local SDP from " + sdp.type); |
1189 peerConnection.setLocalDescription(sdpObserver, sdp); | 1163 peerConnection.setLocalDescription(sdpObserver, sdp); |
1190 } | 1164 } |
1191 } | 1165 } |
1192 }); | 1166 }); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 public void onCreateFailure(final String error) { | 1210 public void onCreateFailure(final String error) { |
1237 reportError("createSDP error: " + error); | 1211 reportError("createSDP error: " + error); |
1238 } | 1212 } |
1239 | 1213 |
1240 @Override | 1214 @Override |
1241 public void onSetFailure(final String error) { | 1215 public void onSetFailure(final String error) { |
1242 reportError("setSDP error: " + error); | 1216 reportError("setSDP error: " + error); |
1243 } | 1217 } |
1244 } | 1218 } |
1245 } | 1219 } |
OLD | NEW |