Chromium Code Reviews| 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 23 matching lines...) Expand all Loading... | |
| 34 import org.webrtc.PeerConnection.IceConnectionState; | 34 import org.webrtc.PeerConnection.IceConnectionState; |
| 35 import org.webrtc.PeerConnectionFactory; | 35 import org.webrtc.PeerConnectionFactory; |
| 36 import org.webrtc.RtpParameters; | 36 import org.webrtc.RtpParameters; |
| 37 import org.webrtc.RtpSender; | 37 import org.webrtc.RtpSender; |
| 38 import org.webrtc.SdpObserver; | 38 import org.webrtc.SdpObserver; |
| 39 import org.webrtc.SessionDescription; | 39 import org.webrtc.SessionDescription; |
| 40 import org.webrtc.StatsObserver; | 40 import org.webrtc.StatsObserver; |
| 41 import org.webrtc.StatsReport; | 41 import org.webrtc.StatsReport; |
| 42 import org.webrtc.VideoCapturer; | 42 import org.webrtc.VideoCapturer; |
| 43 import org.webrtc.VideoRenderer; | 43 import org.webrtc.VideoRenderer; |
| 44 import org.webrtc.VideoCapturerAndroid; | |
| 45 import org.webrtc.CameraVideoCapturer; | |
| 46 import org.webrtc.FileVideoCapturer; | |
| 44 import org.webrtc.VideoSource; | 47 import org.webrtc.VideoSource; |
| 45 import org.webrtc.VideoTrack; | 48 import org.webrtc.VideoTrack; |
| 46 import org.webrtc.voiceengine.WebRtcAudioManager; | 49 import org.webrtc.voiceengine.WebRtcAudioManager; |
| 47 import org.webrtc.voiceengine.WebRtcAudioUtils; | 50 import org.webrtc.voiceengine.WebRtcAudioUtils; |
| 48 | 51 |
| 49 import java.io.File; | 52 import java.io.File; |
| 50 import java.io.IOException; | 53 import java.io.IOException; |
| 54 import java.util.Collections; | |
| 51 import java.util.EnumSet; | 55 import java.util.EnumSet; |
| 52 import java.util.LinkedList; | 56 import java.util.LinkedList; |
| 57 import java.util.List; | |
| 53 import java.util.Timer; | 58 import java.util.Timer; |
| 54 import java.util.TimerTask; | 59 import java.util.TimerTask; |
| 55 import java.util.concurrent.Executors; | 60 import java.util.concurrent.Executors; |
| 56 import java.util.concurrent.ScheduledExecutorService; | 61 import java.util.concurrent.ScheduledExecutorService; |
| 57 import java.util.regex.Matcher; | 62 import java.util.regex.Matcher; |
| 58 import java.util.regex.Pattern; | 63 import java.util.regex.Pattern; |
| 59 | 64 |
| 60 /** | 65 /** |
| 61 * Peer connection client implementation. | 66 * Peer connection client implementation. |
| 62 * | 67 * |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 PeerConnectionFactory.Options options = null; | 106 PeerConnectionFactory.Options options = null; |
| 102 private AudioSource audioSource; | 107 private AudioSource audioSource; |
| 103 private VideoSource videoSource; | 108 private VideoSource videoSource; |
| 104 private boolean videoCallEnabled; | 109 private boolean videoCallEnabled; |
| 105 private boolean preferIsac; | 110 private boolean preferIsac; |
| 106 private String preferredVideoCodec; | 111 private String preferredVideoCodec; |
| 107 private boolean videoCapturerStopped; | 112 private boolean videoCapturerStopped; |
| 108 private boolean isError; | 113 private boolean isError; |
| 109 private Timer statsTimer; | 114 private Timer statsTimer; |
| 110 private VideoRenderer.Callbacks localRender; | 115 private VideoRenderer.Callbacks localRender; |
| 111 private VideoRenderer.Callbacks remoteRender; | 116 private List<VideoRenderer.Callbacks> remoteRenders; |
| 112 private SignalingParameters signalingParameters; | 117 private SignalingParameters signalingParameters; |
| 113 private MediaConstraints pcConstraints; | 118 private MediaConstraints pcConstraints; |
| 114 private int videoWidth; | 119 private int videoWidth; |
| 115 private int videoHeight; | 120 private int videoHeight; |
| 116 private int videoFps; | 121 private int videoFps; |
| 117 private MediaConstraints audioConstraints; | 122 private MediaConstraints audioConstraints; |
| 118 private ParcelFileDescriptor aecDumpFileDescriptor; | 123 private ParcelFileDescriptor aecDumpFileDescriptor; |
| 119 private MediaConstraints sdpMediaConstraints; | 124 private MediaConstraints sdpMediaConstraints; |
| 120 private PeerConnectionParameters peerConnectionParameters; | 125 private PeerConnectionParameters peerConnectionParameters; |
| 121 // Queued remote ICE candidates are consumed only after both local and | 126 // Queued remote ICE candidates are consumed only after both local and |
| 122 // remote descriptions are set. Similarly local ICE candidates are sent to | 127 // remote descriptions are set. Similarly local ICE candidates are sent to |
| 123 // remote peer after both local and remote description are set. | 128 // remote peer after both local and remote description are set. |
| 124 private LinkedList<IceCandidate> queuedRemoteCandidates; | 129 private LinkedList<IceCandidate> queuedRemoteCandidates; |
| 125 private PeerConnectionEvents events; | 130 private PeerConnectionEvents events; |
| 126 private boolean isInitiator; | 131 private boolean isInitiator; |
| 127 private SessionDescription localSdp; // either offer or answer SDP | 132 private SessionDescription localSdp; // either offer or answer SDP |
| 128 private MediaStream mediaStream; | 133 private MediaStream mediaStream; |
| 129 private int numberOfCameras; | 134 private int numberOfCameras; |
| 130 private CameraVideoCapturer videoCapturer; | 135 private VideoCapturer videoCapturer; |
| 131 // enableVideo is set to true if video should be rendered and sent. | 136 // enableVideo is set to true if video should be rendered and sent. |
| 132 private boolean renderVideo; | 137 private boolean renderVideo; |
| 133 private VideoTrack localVideoTrack; | 138 private VideoTrack localVideoTrack; |
| 134 private VideoTrack remoteVideoTrack; | 139 private VideoTrack remoteVideoTrack; |
| 135 private RtpSender localVideoSender; | 140 private RtpSender localVideoSender; |
| 136 // enableAudio is set to true if audio should be sent. | 141 // enableAudio is set to true if audio should be sent. |
| 137 private boolean enableAudio; | 142 private boolean enableAudio; |
| 138 private AudioTrack localAudioTrack; | 143 private AudioTrack localAudioTrack; |
| 139 | 144 |
| 140 /** | 145 /** |
| 141 * Peer connection parameters. | 146 * Peer connection parameters. |
| 142 */ | 147 */ |
| 143 public static class PeerConnectionParameters { | 148 public static class PeerConnectionParameters { |
| 144 public final boolean videoCallEnabled; | 149 public final boolean videoCallEnabled; |
| 145 public final boolean loopback; | 150 public final boolean loopback; |
| 146 public final boolean tracing; | 151 public final boolean tracing; |
| 147 public final boolean useCamera2; | |
| 148 public final int videoWidth; | 152 public final int videoWidth; |
| 149 public final int videoHeight; | 153 public final int videoHeight; |
| 150 public final int videoFps; | 154 public final int videoFps; |
| 151 public final int videoMaxBitrate; | 155 public final int videoMaxBitrate; |
| 152 public final String videoCodec; | 156 public final String videoCodec; |
| 153 public final boolean videoCodecHwAcceleration; | 157 public final boolean videoCodecHwAcceleration; |
| 154 public final boolean captureToTexture; | |
| 155 public final int audioStartBitrate; | 158 public final int audioStartBitrate; |
| 156 public final String audioCodec; | 159 public final String audioCodec; |
| 157 public final boolean noAudioProcessing; | 160 public final boolean noAudioProcessing; |
| 158 public final boolean aecDump; | 161 public final boolean aecDump; |
| 159 public final boolean useOpenSLES; | 162 public final boolean useOpenSLES; |
| 160 public final boolean disableBuiltInAEC; | 163 public final boolean disableBuiltInAEC; |
| 161 public final boolean disableBuiltInAGC; | 164 public final boolean disableBuiltInAGC; |
| 162 public final boolean disableBuiltInNS; | 165 public final boolean disableBuiltInNS; |
| 163 public final boolean enableLevelControl; | 166 public final boolean enableLevelControl; |
| 164 | 167 |
| 165 public PeerConnectionParameters( | 168 public PeerConnectionParameters( |
| 166 boolean videoCallEnabled, boolean loopback, boolean tracing, boolean use Camera2, | 169 boolean videoCallEnabled, boolean loopback, boolean tracing, |
| 167 int videoWidth, int videoHeight, int videoFps, | 170 int videoWidth, int videoHeight, int videoFps, |
| 168 int videoMaxBitrate, String videoCodec, boolean videoCodecHwAcceleration , | 171 int videoMaxBitrate, String videoCodec, boolean videoCodecHwAcceleration , |
| 169 boolean captureToTexture, int audioStartBitrate, String audioCodec, | 172 int audioStartBitrate, String audioCodec, |
| 170 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, | 173 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, |
| 171 boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBui ltInNS, | 174 boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBui ltInNS, |
| 172 boolean enableLevelControl) { | 175 boolean enableLevelControl) { |
| 176 | |
| 173 this.videoCallEnabled = videoCallEnabled; | 177 this.videoCallEnabled = videoCallEnabled; |
| 174 this.useCamera2 = useCamera2; | |
| 175 this.loopback = loopback; | 178 this.loopback = loopback; |
| 176 this.tracing = tracing; | 179 this.tracing = tracing; |
| 177 this.videoWidth = videoWidth; | 180 this.videoWidth = videoWidth; |
| 178 this.videoHeight = videoHeight; | 181 this.videoHeight = videoHeight; |
| 179 this.videoFps = videoFps; | 182 this.videoFps = videoFps; |
| 180 this.videoMaxBitrate = videoMaxBitrate; | 183 this.videoMaxBitrate = videoMaxBitrate; |
| 181 this.videoCodec = videoCodec; | 184 this.videoCodec = videoCodec; |
| 182 this.videoCodecHwAcceleration = videoCodecHwAcceleration; | 185 this.videoCodecHwAcceleration = videoCodecHwAcceleration; |
| 183 this.captureToTexture = captureToTexture; | |
| 184 this.audioStartBitrate = audioStartBitrate; | 186 this.audioStartBitrate = audioStartBitrate; |
| 185 this.audioCodec = audioCodec; | 187 this.audioCodec = audioCodec; |
| 186 this.noAudioProcessing = noAudioProcessing; | 188 this.noAudioProcessing = noAudioProcessing; |
| 187 this.aecDump = aecDump; | 189 this.aecDump = aecDump; |
| 188 this.useOpenSLES = useOpenSLES; | 190 this.useOpenSLES = useOpenSLES; |
| 189 this.disableBuiltInAEC = disableBuiltInAEC; | 191 this.disableBuiltInAEC = disableBuiltInAEC; |
| 190 this.disableBuiltInAGC = disableBuiltInAGC; | 192 this.disableBuiltInAGC = disableBuiltInAGC; |
| 191 this.disableBuiltInNS = disableBuiltInNS; | 193 this.disableBuiltInNS = disableBuiltInNS; |
| 192 this.enableLevelControl = enableLevelControl; | 194 this.enableLevelControl = enableLevelControl; |
| 193 } | 195 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 public void run() { | 288 public void run() { |
| 287 createPeerConnectionFactoryInternal(context); | 289 createPeerConnectionFactoryInternal(context); |
| 288 } | 290 } |
| 289 }); | 291 }); |
| 290 } | 292 } |
| 291 | 293 |
| 292 public void createPeerConnection( | 294 public void createPeerConnection( |
| 293 final EglBase.Context renderEGLContext, | 295 final EglBase.Context renderEGLContext, |
| 294 final VideoRenderer.Callbacks localRender, | 296 final VideoRenderer.Callbacks localRender, |
| 295 final VideoRenderer.Callbacks remoteRender, | 297 final VideoRenderer.Callbacks remoteRender, |
| 298 final VideoCapturer videoCapturer, | |
| 299 final SignalingParameters signalingParameters) { | |
| 300 createPeerConnection( | |
| 301 renderEGLContext, | |
| 302 localRender, | |
| 303 Collections.singletonList(remoteRender), | |
| 304 videoCapturer, | |
| 305 signalingParameters); | |
| 306 } | |
| 307 public void createPeerConnection( | |
| 308 final EglBase.Context renderEGLContext, | |
| 309 final VideoRenderer.Callbacks localRender, | |
| 310 final List<VideoRenderer.Callbacks> remoteRenders, | |
| 311 final VideoCapturer videoCapturer, | |
| 296 final SignalingParameters signalingParameters) { | 312 final SignalingParameters signalingParameters) { |
| 297 if (peerConnectionParameters == null) { | 313 if (peerConnectionParameters == null) { |
| 298 Log.e(TAG, "Creating peer connection without initializing factory."); | 314 Log.e(TAG, "Creating peer connection without initializing factory."); |
| 299 return; | 315 return; |
| 300 } | 316 } |
| 301 this.localRender = localRender; | 317 this.localRender = localRender; |
| 302 this.remoteRender = remoteRender; | 318 this.remoteRenders = remoteRenders; |
| 319 this.videoCapturer = videoCapturer; | |
| 303 this.signalingParameters = signalingParameters; | 320 this.signalingParameters = signalingParameters; |
| 304 executor.execute(new Runnable() { | 321 executor.execute(new Runnable() { |
| 305 @Override | 322 @Override |
| 306 public void run() { | 323 public void run() { |
| 307 try { | 324 try { |
| 308 createMediaConstraintsInternal(); | 325 createMediaConstraintsInternal(); |
| 309 createPeerConnectionInternal(renderEGLContext); | 326 createPeerConnectionInternal(renderEGLContext); |
| 310 } catch (Exception e) { | 327 } catch (Exception e) { |
| 311 reportError("Failed to create peer connection: " + e.getMessage()); | 328 reportError("Failed to create peer connection: " + e.getMessage()); |
| 312 throw e; | 329 throw e; |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 468 "OfferToReceiveAudio", "true")); | 485 "OfferToReceiveAudio", "true")); |
| 469 if (videoCallEnabled || peerConnectionParameters.loopback) { | 486 if (videoCallEnabled || peerConnectionParameters.loopback) { |
| 470 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 487 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( |
| 471 "OfferToReceiveVideo", "true")); | 488 "OfferToReceiveVideo", "true")); |
| 472 } else { | 489 } else { |
| 473 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 490 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( |
| 474 "OfferToReceiveVideo", "false")); | 491 "OfferToReceiveVideo", "false")); |
| 475 } | 492 } |
| 476 } | 493 } |
| 477 | 494 |
| 478 private void createCapturer(CameraEnumerator enumerator) { | |
| 479 final String[] deviceNames = enumerator.getDeviceNames(); | |
| 480 | |
| 481 // First, try to find front facing camera | |
| 482 Logging.d(TAG, "Looking for front facing cameras."); | |
| 483 for (String deviceName : deviceNames) { | |
| 484 if (enumerator.isFrontFacing(deviceName)) { | |
| 485 Logging.d(TAG, "Creating front facing camera capturer."); | |
| 486 videoCapturer = enumerator.createCapturer(deviceName, null); | |
| 487 | |
| 488 if (videoCapturer != null) { | |
| 489 return; | |
| 490 } | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 // Front facing camera not found, try something else | |
| 495 Logging.d(TAG, "Looking for other cameras."); | |
| 496 for (String deviceName : deviceNames) { | |
| 497 if (!enumerator.isFrontFacing(deviceName)) { | |
| 498 Logging.d(TAG, "Creating other camera capturer."); | |
| 499 videoCapturer = enumerator.createCapturer(deviceName, null); | |
| 500 | |
| 501 if (videoCapturer != null) { | |
| 502 return; | |
| 503 } | |
| 504 } | |
| 505 } | |
| 506 } | |
| 507 | |
| 508 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { | 495 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { |
| 509 if (factory == null || isError) { | 496 if (factory == null || isError) { |
| 510 Log.e(TAG, "Peerconnection factory is not created"); | 497 Log.e(TAG, "Peerconnection factory is not created"); |
| 511 return; | 498 return; |
| 512 } | 499 } |
| 513 Log.d(TAG, "Create peer connection."); | 500 Log.d(TAG, "Create peer connection."); |
| 514 | 501 |
| 515 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); | 502 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); |
| 516 queuedRemoteCandidates = new LinkedList<IceCandidate>(); | 503 queuedRemoteCandidates = new LinkedList<IceCandidate>(); |
| 517 | 504 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 537 | 524 |
| 538 // Set default WebRTC tracing and INFO libjingle logging. | 525 // Set default WebRTC tracing and INFO libjingle logging. |
| 539 // NOTE: this _must_ happen while |factory| is alive! | 526 // NOTE: this _must_ happen while |factory| is alive! |
| 540 Logging.enableTracing( | 527 Logging.enableTracing( |
| 541 "logcat:", | 528 "logcat:", |
| 542 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT)); | 529 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT)); |
| 543 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); | 530 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); |
| 544 | 531 |
| 545 mediaStream = factory.createLocalMediaStream("ARDAMS"); | 532 mediaStream = factory.createLocalMediaStream("ARDAMS"); |
| 546 if (videoCallEnabled) { | 533 if (videoCallEnabled) { |
| 547 if (peerConnectionParameters.useCamera2) { | |
| 548 if (!peerConnectionParameters.captureToTexture) { | |
| 549 reportError(context.getString(R.string.camera2_texture_only_error)); | |
| 550 return; | |
| 551 } | |
| 552 | |
| 553 Logging.d(TAG, "Creating capturer using camera2 API."); | |
| 554 createCapturer(new Camera2Enumerator(context)); | |
| 555 } else { | |
| 556 Logging.d(TAG, "Creating capturer using camera1 API."); | |
| 557 createCapturer(new Camera1Enumerator(peerConnectionParameters.captureToT exture)); | |
| 558 } | |
| 559 | |
| 560 if (videoCapturer == null) { | |
| 561 reportError("Failed to open camera"); | |
| 562 return; | |
| 563 } | |
| 564 mediaStream.addTrack(createVideoTrack(videoCapturer)); | 534 mediaStream.addTrack(createVideoTrack(videoCapturer)); |
| 565 } | 535 } |
| 566 | 536 |
| 567 mediaStream.addTrack(createAudioTrack()); | 537 mediaStream.addTrack(createAudioTrack()); |
| 568 peerConnection.addStream(mediaStream); | 538 peerConnection.addStream(mediaStream); |
| 569 if (videoCallEnabled) { | 539 if (videoCallEnabled) { |
| 570 findVideoSender(); | 540 findVideoSender(); |
| 571 } | 541 } |
| 572 | 542 |
| 573 if (peerConnectionParameters.aecDump) { | 543 if (peerConnectionParameters.aecDump) { |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1017 if (queuedRemoteCandidates != null) { | 987 if (queuedRemoteCandidates != null) { |
| 1018 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); | 988 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); |
| 1019 for (IceCandidate candidate : queuedRemoteCandidates) { | 989 for (IceCandidate candidate : queuedRemoteCandidates) { |
| 1020 peerConnection.addIceCandidate(candidate); | 990 peerConnection.addIceCandidate(candidate); |
| 1021 } | 991 } |
| 1022 queuedRemoteCandidates = null; | 992 queuedRemoteCandidates = null; |
| 1023 } | 993 } |
| 1024 } | 994 } |
| 1025 | 995 |
| 1026 private void switchCameraInternal() { | 996 private void switchCameraInternal() { |
| 1027 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer == null) { | 997 if (videoCapturer instanceof CameraVideoCapturer) { |
| 1028 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Erro r : " | 998 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer = = null) { |
| 1029 + isError + ". Number of cameras: " + numberOfCameras); | 999 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Er ror : " |
| 1030 return; // No video is sent or only one camera is available or error happ ened. | 1000 + isError + ". Number of cameras: " + numberOfCameras); |
| 1001 return; // No video is sent or only one camera is available or error ha ppened. | |
| 1002 } | |
| 1003 Log.d(TAG, "Switch camera"); | |
| 1004 CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer)videoCaptur er; | |
| 1005 cameraVideoCapturer.switchCamera(null); | |
| 1031 } | 1006 } |
| 1032 Log.d(TAG, "Switch camera"); | 1007 else { |
|
sakal
2016/10/05 13:28:42
move else to the line above
mandermo
2016/10/07 11:33:41
Done.
| |
| 1033 videoCapturer.switchCamera(null); | 1008 Log.d(TAG, "Will not switch camera, video caputurer is not a camera"); |
| 1009 } | |
| 1034 } | 1010 } |
| 1035 | 1011 |
| 1036 public void switchCamera() { | 1012 public void switchCamera() { |
| 1037 executor.execute(new Runnable() { | 1013 executor.execute(new Runnable() { |
| 1038 @Override | 1014 @Override |
| 1039 public void run() { | 1015 public void run() { |
| 1040 switchCameraInternal(); | 1016 switchCameraInternal(); |
| 1041 } | 1017 } |
| 1042 }); | 1018 }); |
| 1043 } | 1019 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 for (VideoRenderer.Callbacks remoteRender : remoteRenders) { |
| 1113 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); | |
| 1114 } | |
| 1137 } | 1115 } |
| 1138 } | 1116 } |
| 1139 }); | 1117 }); |
| 1140 } | 1118 } |
| 1141 | 1119 |
| 1142 @Override | 1120 @Override |
| 1143 public void onRemoveStream(final MediaStream stream){ | 1121 public void onRemoveStream(final MediaStream stream){ |
| 1144 executor.execute(new Runnable() { | 1122 executor.execute(new Runnable() { |
| 1145 @Override | 1123 @Override |
| 1146 public void run() { | 1124 public void run() { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1236 public void onCreateFailure(final String error) { | 1214 public void onCreateFailure(final String error) { |
| 1237 reportError("createSDP error: " + error); | 1215 reportError("createSDP error: " + error); |
| 1238 } | 1216 } |
| 1239 | 1217 |
| 1240 @Override | 1218 @Override |
| 1241 public void onSetFailure(final String error) { | 1219 public void onSetFailure(final String error) { |
| 1242 reportError("setSDP error: " + error); | 1220 reportError("setSDP error: " + error); |
| 1243 } | 1221 } |
| 1244 } | 1222 } |
| 1245 } | 1223 } |
| OLD | NEW |