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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 PeerConnectionFactory.Options options = null; | 105 PeerConnectionFactory.Options options = null; |
101 private AudioSource audioSource; | 106 private AudioSource audioSource; |
102 private VideoSource videoSource; | 107 private VideoSource videoSource; |
103 private boolean videoCallEnabled; | 108 private boolean videoCallEnabled; |
104 private boolean preferIsac; | 109 private boolean preferIsac; |
105 private String preferredVideoCodec; | 110 private String preferredVideoCodec; |
106 private boolean videoCapturerStopped; | 111 private boolean videoCapturerStopped; |
107 private boolean isError; | 112 private boolean isError; |
108 private Timer statsTimer; | 113 private Timer statsTimer; |
109 private VideoRenderer.Callbacks localRender; | 114 private VideoRenderer.Callbacks localRender; |
110 private VideoRenderer.Callbacks remoteRender; | 115 private List<VideoRenderer.Callbacks> remoteRenders; |
111 private SignalingParameters signalingParameters; | 116 private SignalingParameters signalingParameters; |
112 private MediaConstraints pcConstraints; | 117 private MediaConstraints pcConstraints; |
113 private int videoWidth; | 118 private int videoWidth; |
114 private int videoHeight; | 119 private int videoHeight; |
115 private int videoFps; | 120 private int videoFps; |
116 private MediaConstraints audioConstraints; | 121 private MediaConstraints audioConstraints; |
117 private ParcelFileDescriptor aecDumpFileDescriptor; | 122 private ParcelFileDescriptor aecDumpFileDescriptor; |
118 private MediaConstraints sdpMediaConstraints; | 123 private MediaConstraints sdpMediaConstraints; |
119 private PeerConnectionParameters peerConnectionParameters; | 124 private PeerConnectionParameters peerConnectionParameters; |
120 // Queued remote ICE candidates are consumed only after both local and | 125 // Queued remote ICE candidates are consumed only after both local and |
121 // remote descriptions are set. Similarly local ICE candidates are sent to | 126 // remote descriptions are set. Similarly local ICE candidates are sent to |
122 // remote peer after both local and remote description are set. | 127 // remote peer after both local and remote description are set. |
123 private LinkedList<IceCandidate> queuedRemoteCandidates; | 128 private LinkedList<IceCandidate> queuedRemoteCandidates; |
124 private PeerConnectionEvents events; | 129 private PeerConnectionEvents events; |
125 private boolean isInitiator; | 130 private boolean isInitiator; |
126 private SessionDescription localSdp; // either offer or answer SDP | 131 private SessionDescription localSdp; // either offer or answer SDP |
127 private MediaStream mediaStream; | 132 private MediaStream mediaStream; |
128 private int numberOfCameras; | 133 private int numberOfCameras; |
129 private CameraVideoCapturer videoCapturer; | 134 private VideoCapturer videoCapturer; |
130 // enableVideo is set to true if video should be rendered and sent. | 135 // enableVideo is set to true if video should be rendered and sent. |
131 private boolean renderVideo; | 136 private boolean renderVideo; |
132 private VideoTrack localVideoTrack; | 137 private VideoTrack localVideoTrack; |
133 private VideoTrack remoteVideoTrack; | 138 private VideoTrack remoteVideoTrack; |
134 private RtpSender localVideoSender; | 139 private RtpSender localVideoSender; |
135 // enableAudio is set to true if audio should be sent. | 140 // enableAudio is set to true if audio should be sent. |
136 private boolean enableAudio; | 141 private boolean enableAudio; |
137 private AudioTrack localAudioTrack; | 142 private AudioTrack localAudioTrack; |
138 | 143 |
139 /** | 144 /** |
140 * Peer connection parameters. | 145 * Peer connection parameters. |
141 */ | 146 */ |
142 public static class PeerConnectionParameters { | 147 public static class PeerConnectionParameters { |
143 public final boolean videoCallEnabled; | 148 public final boolean videoCallEnabled; |
144 public final boolean loopback; | 149 public final boolean loopback; |
145 public final boolean tracing; | 150 public final boolean tracing; |
146 public final boolean useCamera2; | |
147 public final int videoWidth; | 151 public final int videoWidth; |
148 public final int videoHeight; | 152 public final int videoHeight; |
149 public final int videoFps; | 153 public final int videoFps; |
150 public final int videoMaxBitrate; | 154 public final int videoMaxBitrate; |
151 public final String videoCodec; | 155 public final String videoCodec; |
152 public final boolean videoCodecHwAcceleration; | 156 public final boolean videoCodecHwAcceleration; |
153 public final boolean captureToTexture; | |
154 public final int audioStartBitrate; | 157 public final int audioStartBitrate; |
155 public final String audioCodec; | 158 public final String audioCodec; |
156 public final boolean noAudioProcessing; | 159 public final boolean noAudioProcessing; |
157 public final boolean aecDump; | 160 public final boolean aecDump; |
158 public final boolean useOpenSLES; | 161 public final boolean useOpenSLES; |
159 public final boolean disableBuiltInAEC; | 162 public final boolean disableBuiltInAEC; |
160 public final boolean disableBuiltInAGC; | 163 public final boolean disableBuiltInAGC; |
161 public final boolean disableBuiltInNS; | 164 public final boolean disableBuiltInNS; |
162 public final boolean enableLevelControl; | 165 public final boolean enableLevelControl; |
163 | 166 |
164 public PeerConnectionParameters(boolean videoCallEnabled, boolean loopback,
boolean tracing, | 167 public PeerConnectionParameters( |
165 boolean useCamera2, int videoWidth, int videoHeight, int videoFps, int v
ideoMaxBitrate, | 168 boolean videoCallEnabled, boolean loopback, boolean tracing, |
166 String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTe
xture, | 169 int videoWidth, int videoHeight, int videoFps, |
167 int audioStartBitrate, String audioCodec, boolean noAudioProcessing, boo
lean aecDump, | 170 int videoMaxBitrate, String videoCodec, boolean videoCodecHwAcceleration
, |
168 boolean useOpenSLES, boolean disableBuiltInAEC, boolean disableBuiltInAG
C, | 171 int audioStartBitrate, String audioCodec, |
169 boolean disableBuiltInNS, boolean enableLevelControl) { | 172 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, |
| 173 boolean disableBuiltInAEC, boolean disableBuiltInAGC, boolean disableBui
ltInNS, |
| 174 boolean enableLevelControl) { |
| 175 |
170 this.videoCallEnabled = videoCallEnabled; | 176 this.videoCallEnabled = videoCallEnabled; |
171 this.useCamera2 = useCamera2; | |
172 this.loopback = loopback; | 177 this.loopback = loopback; |
173 this.tracing = tracing; | 178 this.tracing = tracing; |
174 this.videoWidth = videoWidth; | 179 this.videoWidth = videoWidth; |
175 this.videoHeight = videoHeight; | 180 this.videoHeight = videoHeight; |
176 this.videoFps = videoFps; | 181 this.videoFps = videoFps; |
177 this.videoMaxBitrate = videoMaxBitrate; | 182 this.videoMaxBitrate = videoMaxBitrate; |
178 this.videoCodec = videoCodec; | 183 this.videoCodec = videoCodec; |
179 this.videoCodecHwAcceleration = videoCodecHwAcceleration; | 184 this.videoCodecHwAcceleration = videoCodecHwAcceleration; |
180 this.captureToTexture = captureToTexture; | |
181 this.audioStartBitrate = audioStartBitrate; | 185 this.audioStartBitrate = audioStartBitrate; |
182 this.audioCodec = audioCodec; | 186 this.audioCodec = audioCodec; |
183 this.noAudioProcessing = noAudioProcessing; | 187 this.noAudioProcessing = noAudioProcessing; |
184 this.aecDump = aecDump; | 188 this.aecDump = aecDump; |
185 this.useOpenSLES = useOpenSLES; | 189 this.useOpenSLES = useOpenSLES; |
186 this.disableBuiltInAEC = disableBuiltInAEC; | 190 this.disableBuiltInAEC = disableBuiltInAEC; |
187 this.disableBuiltInAGC = disableBuiltInAGC; | 191 this.disableBuiltInAGC = disableBuiltInAGC; |
188 this.disableBuiltInNS = disableBuiltInNS; | 192 this.disableBuiltInNS = disableBuiltInNS; |
189 this.enableLevelControl = enableLevelControl; | 193 this.enableLevelControl = enableLevelControl; |
190 } | 194 } |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
277 statsTimer = new Timer(); | 281 statsTimer = new Timer(); |
278 | 282 |
279 executor.execute(new Runnable() { | 283 executor.execute(new Runnable() { |
280 @Override | 284 @Override |
281 public void run() { | 285 public void run() { |
282 createPeerConnectionFactoryInternal(context); | 286 createPeerConnectionFactoryInternal(context); |
283 } | 287 } |
284 }); | 288 }); |
285 } | 289 } |
286 | 290 |
287 public void createPeerConnection(final EglBase.Context renderEGLContext, | 291 public void createPeerConnection( |
288 final VideoRenderer.Callbacks localRender, final VideoRenderer.Callbacks r
emoteRender, | 292 final EglBase.Context renderEGLContext, |
| 293 final VideoRenderer.Callbacks localRender, |
| 294 final VideoRenderer.Callbacks remoteRender, |
| 295 final VideoCapturer videoCapturer, |
| 296 final SignalingParameters signalingParameters) { |
| 297 createPeerConnection( |
| 298 renderEGLContext, |
| 299 localRender, |
| 300 Collections.singletonList(remoteRender), |
| 301 videoCapturer, |
| 302 signalingParameters); |
| 303 } |
| 304 public void createPeerConnection( |
| 305 final EglBase.Context renderEGLContext, |
| 306 final VideoRenderer.Callbacks localRender, |
| 307 final List<VideoRenderer.Callbacks> remoteRenders, |
| 308 final VideoCapturer videoCapturer, |
289 final SignalingParameters signalingParameters) { | 309 final SignalingParameters signalingParameters) { |
290 if (peerConnectionParameters == null) { | 310 if (peerConnectionParameters == null) { |
291 Log.e(TAG, "Creating peer connection without initializing factory."); | 311 Log.e(TAG, "Creating peer connection without initializing factory."); |
292 return; | 312 return; |
293 } | 313 } |
294 this.localRender = localRender; | 314 this.localRender = localRender; |
295 this.remoteRender = remoteRender; | 315 this.remoteRenders = remoteRenders; |
| 316 this.videoCapturer = videoCapturer; |
296 this.signalingParameters = signalingParameters; | 317 this.signalingParameters = signalingParameters; |
297 executor.execute(new Runnable() { | 318 executor.execute(new Runnable() { |
298 @Override | 319 @Override |
299 public void run() { | 320 public void run() { |
300 try { | 321 try { |
301 createMediaConstraintsInternal(); | 322 createMediaConstraintsInternal(); |
302 createPeerConnectionInternal(renderEGLContext); | 323 createPeerConnectionInternal(renderEGLContext); |
303 } catch (Exception e) { | 324 } catch (Exception e) { |
304 reportError("Failed to create peer connection: " + e.getMessage()); | 325 reportError("Failed to create peer connection: " + e.getMessage()); |
305 throw e; | 326 throw e; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); | 482 new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); |
462 if (videoCallEnabled || peerConnectionParameters.loopback) { | 483 if (videoCallEnabled || peerConnectionParameters.loopback) { |
463 sdpMediaConstraints.mandatory.add( | 484 sdpMediaConstraints.mandatory.add( |
464 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); | 485 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); |
465 } else { | 486 } else { |
466 sdpMediaConstraints.mandatory.add( | 487 sdpMediaConstraints.mandatory.add( |
467 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false")); | 488 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false")); |
468 } | 489 } |
469 } | 490 } |
470 | 491 |
471 private void createCapturer(CameraEnumerator enumerator) { | |
472 final String[] deviceNames = enumerator.getDeviceNames(); | |
473 | |
474 // First, try to find front facing camera | |
475 Logging.d(TAG, "Looking for front facing cameras."); | |
476 for (String deviceName : deviceNames) { | |
477 if (enumerator.isFrontFacing(deviceName)) { | |
478 Logging.d(TAG, "Creating front facing camera capturer."); | |
479 videoCapturer = enumerator.createCapturer(deviceName, null); | |
480 | |
481 if (videoCapturer != null) { | |
482 return; | |
483 } | |
484 } | |
485 } | |
486 | |
487 // Front facing camera not found, try something else | |
488 Logging.d(TAG, "Looking for other cameras."); | |
489 for (String deviceName : deviceNames) { | |
490 if (!enumerator.isFrontFacing(deviceName)) { | |
491 Logging.d(TAG, "Creating other camera capturer."); | |
492 videoCapturer = enumerator.createCapturer(deviceName, null); | |
493 | |
494 if (videoCapturer != null) { | |
495 return; | |
496 } | |
497 } | |
498 } | |
499 } | |
500 | |
501 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { | 492 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { |
502 if (factory == null || isError) { | 493 if (factory == null || isError) { |
503 Log.e(TAG, "Peerconnection factory is not created"); | 494 Log.e(TAG, "Peerconnection factory is not created"); |
504 return; | 495 return; |
505 } | 496 } |
506 Log.d(TAG, "Create peer connection."); | 497 Log.d(TAG, "Create peer connection."); |
507 | 498 |
508 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); | 499 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); |
509 queuedRemoteCandidates = new LinkedList<IceCandidate>(); | 500 queuedRemoteCandidates = new LinkedList<IceCandidate>(); |
510 | 501 |
(...skipping 16 matching lines...) Expand all Loading... |
527 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb
server); | 518 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb
server); |
528 isInitiator = false; | 519 isInitiator = false; |
529 | 520 |
530 // Set default WebRTC tracing and INFO libjingle logging. | 521 // Set default WebRTC tracing and INFO libjingle logging. |
531 // NOTE: this _must_ happen while |factory| is alive! | 522 // NOTE: this _must_ happen while |factory| is alive! |
532 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT
)); | 523 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT
)); |
533 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); | 524 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); |
534 | 525 |
535 mediaStream = factory.createLocalMediaStream("ARDAMS"); | 526 mediaStream = factory.createLocalMediaStream("ARDAMS"); |
536 if (videoCallEnabled) { | 527 if (videoCallEnabled) { |
537 if (peerConnectionParameters.useCamera2) { | |
538 if (!peerConnectionParameters.captureToTexture) { | |
539 reportError(context.getString(R.string.camera2_texture_only_error)); | |
540 return; | |
541 } | |
542 | |
543 Logging.d(TAG, "Creating capturer using camera2 API."); | |
544 createCapturer(new Camera2Enumerator(context)); | |
545 } else { | |
546 Logging.d(TAG, "Creating capturer using camera1 API."); | |
547 createCapturer(new Camera1Enumerator(peerConnectionParameters.captureToT
exture)); | |
548 } | |
549 | |
550 if (videoCapturer == null) { | |
551 reportError("Failed to open camera"); | |
552 return; | |
553 } | |
554 mediaStream.addTrack(createVideoTrack(videoCapturer)); | 528 mediaStream.addTrack(createVideoTrack(videoCapturer)); |
555 } | 529 } |
556 | 530 |
557 mediaStream.addTrack(createAudioTrack()); | 531 mediaStream.addTrack(createAudioTrack()); |
558 peerConnection.addStream(mediaStream); | 532 peerConnection.addStream(mediaStream); |
559 if (videoCallEnabled) { | 533 if (videoCallEnabled) { |
560 findVideoSender(); | 534 findVideoSender(); |
561 } | 535 } |
562 | 536 |
563 if (peerConnectionParameters.aecDump) { | 537 if (peerConnectionParameters.aecDump) { |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
996 if (queuedRemoteCandidates != null) { | 970 if (queuedRemoteCandidates != null) { |
997 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); | 971 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); |
998 for (IceCandidate candidate : queuedRemoteCandidates) { | 972 for (IceCandidate candidate : queuedRemoteCandidates) { |
999 peerConnection.addIceCandidate(candidate); | 973 peerConnection.addIceCandidate(candidate); |
1000 } | 974 } |
1001 queuedRemoteCandidates = null; | 975 queuedRemoteCandidates = null; |
1002 } | 976 } |
1003 } | 977 } |
1004 | 978 |
1005 private void switchCameraInternal() { | 979 private void switchCameraInternal() { |
1006 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer ==
null) { | 980 if (videoCapturer instanceof CameraVideoCapturer) { |
1007 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Erro
r : " + isError | 981 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer =
= null) { |
1008 + ". Number of cameras: " + numberOfCameras); | 982 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + |
1009 return; // No video is sent or only one camera is available or error happe
ned. | 983 ". Error : " + isError + ". Number of cameras: " + numberOfCameras); |
| 984 return; // No video is sent or only one camera is available or error hap
pened. |
| 985 } |
| 986 Log.d(TAG, "Switch camera"); |
| 987 CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer)videoCaptur
er; |
| 988 cameraVideoCapturer.switchCamera(null); |
| 989 } else { |
| 990 Log.d(TAG, "Will not switch camera, video caputurer is not a camera"); |
1010 } | 991 } |
1011 Log.d(TAG, "Switch camera"); | |
1012 videoCapturer.switchCamera(null); | |
1013 } | 992 } |
1014 | 993 |
1015 public void switchCamera() { | 994 public void switchCamera() { |
1016 executor.execute(new Runnable() { | 995 executor.execute(new Runnable() { |
1017 @Override | 996 @Override |
1018 public void run() { | 997 public void run() { |
1019 switchCameraInternal(); | 998 switchCameraInternal(); |
1020 } | 999 } |
1021 }); | 1000 }); |
1022 } | 1001 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 if (peerConnection == null || isError) { | 1081 if (peerConnection == null || isError) { |
1103 return; | 1082 return; |
1104 } | 1083 } |
1105 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { | 1084 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { |
1106 reportError("Weird-looking stream: " + stream); | 1085 reportError("Weird-looking stream: " + stream); |
1107 return; | 1086 return; |
1108 } | 1087 } |
1109 if (stream.videoTracks.size() == 1) { | 1088 if (stream.videoTracks.size() == 1) { |
1110 remoteVideoTrack = stream.videoTracks.get(0); | 1089 remoteVideoTrack = stream.videoTracks.get(0); |
1111 remoteVideoTrack.setEnabled(renderVideo); | 1090 remoteVideoTrack.setEnabled(renderVideo); |
1112 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); | 1091 for (VideoRenderer.Callbacks remoteRender : remoteRenders) { |
| 1092 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); |
| 1093 } |
1113 } | 1094 } |
1114 } | 1095 } |
1115 }); | 1096 }); |
1116 } | 1097 } |
1117 | 1098 |
1118 @Override | 1099 @Override |
1119 public void onRemoveStream(final MediaStream stream) { | 1100 public void onRemoveStream(final MediaStream stream) { |
1120 executor.execute(new Runnable() { | 1101 executor.execute(new Runnable() { |
1121 @Override | 1102 @Override |
1122 public void run() { | 1103 public void run() { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1210 public void onCreateFailure(final String error) { | 1191 public void onCreateFailure(final String error) { |
1211 reportError("createSDP error: " + error); | 1192 reportError("createSDP error: " + error); |
1212 } | 1193 } |
1213 | 1194 |
1214 @Override | 1195 @Override |
1215 public void onSetFailure(final String error) { | 1196 public void onSetFailure(final String error) { |
1216 reportError("setSDP error: " + error); | 1197 reportError("setSDP error: " + error); |
1217 } | 1198 } |
1218 } | 1199 } |
1219 } | 1200 } |
OLD | NEW |