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 |
11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
12 | 12 |
13 import org.appspot.apprtc.AppRTCClient.SignalingParameters; | 13 import org.appspot.apprtc.AppRTCClient.SignalingParameters; |
14 | 14 |
15 import android.content.Context; | 15 import android.content.Context; |
16 import android.os.Environment; | 16 import android.os.Environment; |
17 import android.os.ParcelFileDescriptor; | 17 import android.os.ParcelFileDescriptor; |
18 import android.util.Log; | 18 import android.util.Log; |
19 | 19 |
20 import org.webrtc.AudioSource; | 20 import org.webrtc.AudioSource; |
21 import org.webrtc.AudioTrack; | 21 import org.webrtc.AudioTrack; |
| 22 import org.webrtc.Camera1Enumerator; |
| 23 import org.webrtc.Camera2Enumerator; |
22 import org.webrtc.CameraEnumerationAndroid; | 24 import org.webrtc.CameraEnumerationAndroid; |
| 25 import org.webrtc.CameraEnumerator; |
| 26 import org.webrtc.CameraVideoCapturer; |
23 import org.webrtc.DataChannel; | 27 import org.webrtc.DataChannel; |
24 import org.webrtc.EglBase; | 28 import org.webrtc.EglBase; |
25 import org.webrtc.IceCandidate; | 29 import org.webrtc.IceCandidate; |
26 import org.webrtc.Logging; | 30 import org.webrtc.Logging; |
27 import org.webrtc.MediaCodecVideoEncoder; | 31 import org.webrtc.MediaCodecVideoEncoder; |
28 import org.webrtc.MediaConstraints; | 32 import org.webrtc.MediaConstraints; |
29 import org.webrtc.MediaConstraints.KeyValuePair; | 33 import org.webrtc.MediaConstraints.KeyValuePair; |
30 import org.webrtc.MediaStream; | 34 import org.webrtc.MediaStream; |
31 import org.webrtc.PeerConnection; | 35 import org.webrtc.PeerConnection; |
32 import org.webrtc.PeerConnection.IceConnectionState; | 36 import org.webrtc.PeerConnection.IceConnectionState; |
33 import org.webrtc.PeerConnectionFactory; | 37 import org.webrtc.PeerConnectionFactory; |
34 import org.webrtc.SdpObserver; | 38 import org.webrtc.SdpObserver; |
35 import org.webrtc.SessionDescription; | 39 import org.webrtc.SessionDescription; |
36 import org.webrtc.StatsObserver; | 40 import org.webrtc.StatsObserver; |
37 import org.webrtc.StatsReport; | 41 import org.webrtc.StatsReport; |
38 import org.webrtc.VideoCapturerAndroid; | 42 import org.webrtc.VideoCapturer; |
39 import org.webrtc.VideoRenderer; | 43 import org.webrtc.VideoRenderer; |
40 import org.webrtc.VideoSource; | 44 import org.webrtc.VideoSource; |
41 import org.webrtc.VideoTrack; | 45 import org.webrtc.VideoTrack; |
42 import org.webrtc.voiceengine.WebRtcAudioManager; | 46 import org.webrtc.voiceengine.WebRtcAudioManager; |
43 import org.webrtc.voiceengine.WebRtcAudioUtils; | 47 import org.webrtc.voiceengine.WebRtcAudioUtils; |
44 | 48 |
45 import java.io.File; | 49 import java.io.File; |
46 import java.io.IOException; | 50 import java.io.IOException; |
47 import java.util.EnumSet; | 51 import java.util.EnumSet; |
48 import java.util.LinkedList; | 52 import java.util.LinkedList; |
49 import java.util.Timer; | 53 import java.util.Timer; |
50 import java.util.TimerTask; | 54 import java.util.TimerTask; |
51 import java.util.concurrent.ExecutorService; | |
52 import java.util.concurrent.Executors; | 55 import java.util.concurrent.Executors; |
53 import java.util.concurrent.ScheduledExecutorService; | 56 import java.util.concurrent.ScheduledExecutorService; |
54 import java.util.regex.Matcher; | 57 import java.util.regex.Matcher; |
55 import java.util.regex.Pattern; | 58 import java.util.regex.Pattern; |
56 | 59 |
57 /** | 60 /** |
58 * Peer connection client implementation. | 61 * Peer connection client implementation. |
59 * | 62 * |
60 * <p>All public methods are routed to local looper thread. | 63 * <p>All public methods are routed to local looper thread. |
61 * All PeerConnectionEvents callbacks are invoked from the same looper thread. | 64 * All PeerConnectionEvents callbacks are invoked from the same looper thread. |
(...skipping 26 matching lines...) Expand all Loading... |
88 private static final int HD_VIDEO_HEIGHT = 720; | 91 private static final int HD_VIDEO_HEIGHT = 720; |
89 private static final int MAX_VIDEO_WIDTH = 1280; | 92 private static final int MAX_VIDEO_WIDTH = 1280; |
90 private static final int MAX_VIDEO_HEIGHT = 1280; | 93 private static final int MAX_VIDEO_HEIGHT = 1280; |
91 private static final int MAX_VIDEO_FPS = 30; | 94 private static final int MAX_VIDEO_FPS = 30; |
92 | 95 |
93 private static final PeerConnectionClient instance = new PeerConnectionClient(
); | 96 private static final PeerConnectionClient instance = new PeerConnectionClient(
); |
94 private final PCObserver pcObserver = new PCObserver(); | 97 private final PCObserver pcObserver = new PCObserver(); |
95 private final SDPObserver sdpObserver = new SDPObserver(); | 98 private final SDPObserver sdpObserver = new SDPObserver(); |
96 private final ScheduledExecutorService executor; | 99 private final ScheduledExecutorService executor; |
97 | 100 |
| 101 private Context context; |
98 private PeerConnectionFactory factory; | 102 private PeerConnectionFactory factory; |
99 private PeerConnection peerConnection; | 103 private PeerConnection peerConnection; |
100 PeerConnectionFactory.Options options = null; | 104 PeerConnectionFactory.Options options = null; |
101 private AudioSource audioSource; | 105 private AudioSource audioSource; |
102 private VideoSource videoSource; | 106 private VideoSource videoSource; |
103 private boolean videoCallEnabled; | 107 private boolean videoCallEnabled; |
104 private boolean preferIsac; | 108 private boolean preferIsac; |
105 private String preferredVideoCodec; | 109 private String preferredVideoCodec; |
106 private boolean videoSourceStopped; | 110 private boolean videoSourceStopped; |
107 private boolean isError; | 111 private boolean isError; |
108 private Timer statsTimer; | 112 private Timer statsTimer; |
109 private VideoRenderer.Callbacks localRender; | 113 private VideoRenderer.Callbacks localRender; |
110 private VideoRenderer.Callbacks remoteRender; | 114 private VideoRenderer.Callbacks remoteRender; |
111 private SignalingParameters signalingParameters; | 115 private SignalingParameters signalingParameters; |
112 private MediaConstraints pcConstraints; | 116 private MediaConstraints pcConstraints; |
113 private MediaConstraints videoConstraints; | 117 private MediaConstraints videoConstraints; |
114 private MediaConstraints audioConstraints; | 118 private MediaConstraints audioConstraints; |
115 private ParcelFileDescriptor aecDumpFileDescriptor; | 119 private ParcelFileDescriptor aecDumpFileDescriptor; |
116 private MediaConstraints sdpMediaConstraints; | 120 private MediaConstraints sdpMediaConstraints; |
117 private PeerConnectionParameters peerConnectionParameters; | 121 private PeerConnectionParameters peerConnectionParameters; |
118 // Queued remote ICE candidates are consumed only after both local and | 122 // Queued remote ICE candidates are consumed only after both local and |
119 // remote descriptions are set. Similarly local ICE candidates are sent to | 123 // remote descriptions are set. Similarly local ICE candidates are sent to |
120 // remote peer after both local and remote description are set. | 124 // remote peer after both local and remote description are set. |
121 private LinkedList<IceCandidate> queuedRemoteCandidates; | 125 private LinkedList<IceCandidate> queuedRemoteCandidates; |
122 private PeerConnectionEvents events; | 126 private PeerConnectionEvents events; |
123 private boolean isInitiator; | 127 private boolean isInitiator; |
124 private SessionDescription localSdp; // either offer or answer SDP | 128 private SessionDescription localSdp; // either offer or answer SDP |
125 private MediaStream mediaStream; | 129 private MediaStream mediaStream; |
126 private int numberOfCameras; | 130 private int numberOfCameras; |
127 private VideoCapturerAndroid videoCapturer; | 131 private CameraVideoCapturer videoCapturer; |
128 // enableVideo is set to true if video should be rendered and sent. | 132 // enableVideo is set to true if video should be rendered and sent. |
129 private boolean renderVideo; | 133 private boolean renderVideo; |
130 private VideoTrack localVideoTrack; | 134 private VideoTrack localVideoTrack; |
131 private VideoTrack remoteVideoTrack; | 135 private VideoTrack remoteVideoTrack; |
132 // enableAudio is set to true if audio should be sent. | 136 // enableAudio is set to true if audio should be sent. |
133 private boolean enableAudio; | 137 private boolean enableAudio; |
134 private AudioTrack localAudioTrack; | 138 private AudioTrack localAudioTrack; |
135 | 139 |
136 /** | 140 /** |
137 * Peer connection parameters. | 141 * Peer connection parameters. |
138 */ | 142 */ |
139 public static class PeerConnectionParameters { | 143 public static class PeerConnectionParameters { |
140 public final boolean videoCallEnabled; | 144 public final boolean videoCallEnabled; |
141 public final boolean loopback; | 145 public final boolean loopback; |
142 public final boolean tracing; | 146 public final boolean tracing; |
| 147 public final boolean useCamera2; |
143 public final int videoWidth; | 148 public final int videoWidth; |
144 public final int videoHeight; | 149 public final int videoHeight; |
145 public final int videoFps; | 150 public final int videoFps; |
146 public final int videoStartBitrate; | 151 public final int videoStartBitrate; |
147 public final String videoCodec; | 152 public final String videoCodec; |
148 public final boolean videoCodecHwAcceleration; | 153 public final boolean videoCodecHwAcceleration; |
149 public final boolean captureToTexture; | 154 public final boolean captureToTexture; |
150 public final int audioStartBitrate; | 155 public final int audioStartBitrate; |
151 public final String audioCodec; | 156 public final String audioCodec; |
152 public final boolean noAudioProcessing; | 157 public final boolean noAudioProcessing; |
153 public final boolean aecDump; | 158 public final boolean aecDump; |
154 public final boolean useOpenSLES; | 159 public final boolean useOpenSLES; |
155 public final boolean disableBuiltInAEC; | 160 public final boolean disableBuiltInAEC; |
156 | 161 |
157 public PeerConnectionParameters( | 162 public PeerConnectionParameters( |
158 boolean videoCallEnabled, boolean loopback, boolean tracing, | 163 boolean videoCallEnabled, boolean loopback, boolean tracing, boolean use
Camera2, |
159 int videoWidth, int videoHeight, int videoFps, int videoStartBitrate, | 164 int videoWidth, int videoHeight, int videoFps, |
160 String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTe
xture, | 165 int videoStartBitrate, String videoCodec, boolean videoCodecHwAccelerati
on, |
161 int audioStartBitrate, String audioCodec, | 166 boolean captureToTexture, int audioStartBitrate, String audioCodec, |
162 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, | 167 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, |
163 boolean disableBuiltInAEC) { | 168 boolean disableBuiltInAEC) { |
164 this.videoCallEnabled = videoCallEnabled; | 169 this.videoCallEnabled = videoCallEnabled; |
| 170 this.useCamera2 = useCamera2; |
165 this.loopback = loopback; | 171 this.loopback = loopback; |
166 this.tracing = tracing; | 172 this.tracing = tracing; |
167 this.videoWidth = videoWidth; | 173 this.videoWidth = videoWidth; |
168 this.videoHeight = videoHeight; | 174 this.videoHeight = videoHeight; |
169 this.videoFps = videoFps; | 175 this.videoFps = videoFps; |
170 this.videoStartBitrate = videoStartBitrate; | 176 this.videoStartBitrate = videoStartBitrate; |
171 this.videoCodec = videoCodec; | 177 this.videoCodec = videoCodec; |
172 this.videoCodecHwAcceleration = videoCodecHwAcceleration; | 178 this.videoCodecHwAcceleration = videoCodecHwAcceleration; |
173 this.captureToTexture = captureToTexture; | 179 this.captureToTexture = captureToTexture; |
174 this.audioStartBitrate = audioStartBitrate; | 180 this.audioStartBitrate = audioStartBitrate; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 } | 249 } |
244 | 250 |
245 public void createPeerConnectionFactory( | 251 public void createPeerConnectionFactory( |
246 final Context context, | 252 final Context context, |
247 final PeerConnectionParameters peerConnectionParameters, | 253 final PeerConnectionParameters peerConnectionParameters, |
248 final PeerConnectionEvents events) { | 254 final PeerConnectionEvents events) { |
249 this.peerConnectionParameters = peerConnectionParameters; | 255 this.peerConnectionParameters = peerConnectionParameters; |
250 this.events = events; | 256 this.events = events; |
251 videoCallEnabled = peerConnectionParameters.videoCallEnabled; | 257 videoCallEnabled = peerConnectionParameters.videoCallEnabled; |
252 // Reset variables to initial states. | 258 // Reset variables to initial states. |
| 259 this.context = null; |
253 factory = null; | 260 factory = null; |
254 peerConnection = null; | 261 peerConnection = null; |
255 preferIsac = false; | 262 preferIsac = false; |
256 videoSourceStopped = false; | 263 videoSourceStopped = false; |
257 isError = false; | 264 isError = false; |
258 queuedRemoteCandidates = null; | 265 queuedRemoteCandidates = null; |
259 localSdp = null; // either offer or answer SDP | 266 localSdp = null; // either offer or answer SDP |
260 mediaStream = null; | 267 mediaStream = null; |
261 videoCapturer = null; | 268 videoCapturer = null; |
262 renderVideo = true; | 269 renderVideo = true; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 367 } |
361 | 368 |
362 // Create peer connection factory. | 369 // Create peer connection factory. |
363 if (!PeerConnectionFactory.initializeAndroidGlobals(context, true, true, | 370 if (!PeerConnectionFactory.initializeAndroidGlobals(context, true, true, |
364 peerConnectionParameters.videoCodecHwAcceleration)) { | 371 peerConnectionParameters.videoCodecHwAcceleration)) { |
365 events.onPeerConnectionError("Failed to initializeAndroidGlobals"); | 372 events.onPeerConnectionError("Failed to initializeAndroidGlobals"); |
366 } | 373 } |
367 if (options != null) { | 374 if (options != null) { |
368 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas
k); | 375 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas
k); |
369 } | 376 } |
| 377 this.context = context; |
370 factory = new PeerConnectionFactory(options); | 378 factory = new PeerConnectionFactory(options); |
371 Log.d(TAG, "Peer connection factory created."); | 379 Log.d(TAG, "Peer connection factory created."); |
372 } | 380 } |
373 | 381 |
374 private void createMediaConstraintsInternal() { | 382 private void createMediaConstraintsInternal() { |
375 // Create peer connection constraints. | 383 // Create peer connection constraints. |
376 pcConstraints = new MediaConstraints(); | 384 pcConstraints = new MediaConstraints(); |
377 // Enable DTLS for normal calls and disable for loopback calls. | 385 // Enable DTLS for normal calls and disable for loopback calls. |
378 if (peerConnectionParameters.loopback) { | 386 if (peerConnectionParameters.loopback) { |
379 pcConstraints.optional.add( | 387 pcConstraints.optional.add( |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 "OfferToReceiveAudio", "true")); | 457 "OfferToReceiveAudio", "true")); |
450 if (videoCallEnabled || peerConnectionParameters.loopback) { | 458 if (videoCallEnabled || peerConnectionParameters.loopback) { |
451 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 459 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( |
452 "OfferToReceiveVideo", "true")); | 460 "OfferToReceiveVideo", "true")); |
453 } else { | 461 } else { |
454 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( | 462 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( |
455 "OfferToReceiveVideo", "false")); | 463 "OfferToReceiveVideo", "false")); |
456 } | 464 } |
457 } | 465 } |
458 | 466 |
| 467 private void createCapturer(CameraEnumerator enumerator) { |
| 468 final String[] deviceNames = enumerator.getDeviceNames(); |
| 469 |
| 470 // First, try to find front facing camera |
| 471 Logging.d(TAG, "Looking for front facing cameras."); |
| 472 for (String deviceName : deviceNames) { |
| 473 if (enumerator.isFrontFacing(deviceName)) { |
| 474 Logging.d(TAG, "Creating front facing camera capturer."); |
| 475 videoCapturer = enumerator.createCapturer(deviceName, null); |
| 476 |
| 477 if (videoCapturer != null) { |
| 478 return; |
| 479 } |
| 480 } |
| 481 } |
| 482 |
| 483 // Front facing camera not found, try something else |
| 484 Logging.d(TAG, "Looking for other cameras."); |
| 485 for (String deviceName : deviceNames) { |
| 486 if (!enumerator.isFrontFacing(deviceName)) { |
| 487 Logging.d(TAG, "Creating other camera capturer."); |
| 488 videoCapturer = enumerator.createCapturer(deviceName, null); |
| 489 |
| 490 if (videoCapturer != null) { |
| 491 return; |
| 492 } |
| 493 } |
| 494 } |
| 495 } |
| 496 |
459 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { | 497 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { |
460 if (factory == null || isError) { | 498 if (factory == null || isError) { |
461 Log.e(TAG, "Peerconnection factory is not created"); | 499 Log.e(TAG, "Peerconnection factory is not created"); |
462 return; | 500 return; |
463 } | 501 } |
464 Log.d(TAG, "Create peer connection."); | 502 Log.d(TAG, "Create peer connection."); |
465 | 503 |
466 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); | 504 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); |
467 if (videoConstraints != null) { | 505 if (videoConstraints != null) { |
468 Log.d(TAG, "VideoConstraints: " + videoConstraints.toString()); | 506 Log.d(TAG, "VideoConstraints: " + videoConstraints.toString()); |
(...skipping 22 matching lines...) Expand all Loading... |
491 | 529 |
492 // Set default WebRTC tracing and INFO libjingle logging. | 530 // Set default WebRTC tracing and INFO libjingle logging. |
493 // NOTE: this _must_ happen while |factory| is alive! | 531 // NOTE: this _must_ happen while |factory| is alive! |
494 Logging.enableTracing( | 532 Logging.enableTracing( |
495 "logcat:", | 533 "logcat:", |
496 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT)); | 534 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT)); |
497 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); | 535 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); |
498 | 536 |
499 mediaStream = factory.createLocalMediaStream("ARDAMS"); | 537 mediaStream = factory.createLocalMediaStream("ARDAMS"); |
500 if (videoCallEnabled) { | 538 if (videoCallEnabled) { |
501 String cameraDeviceName = CameraEnumerationAndroid.getDeviceName(0); | 539 if (peerConnectionParameters.useCamera2) { |
502 String frontCameraDeviceName = | 540 if (!peerConnectionParameters.captureToTexture) { |
503 CameraEnumerationAndroid.getNameOfFrontFacingDevice(); | 541 reportError(context.getString(R.string.camera2_texture_only_error)); |
504 if (numberOfCameras > 1 && frontCameraDeviceName != null) { | 542 return; |
505 cameraDeviceName = frontCameraDeviceName; | 543 } |
| 544 |
| 545 Logging.d(TAG, "Creating capturer using camera2 API."); |
| 546 createCapturer(new Camera2Enumerator(context)); |
| 547 } else { |
| 548 Logging.d(TAG, "Creating capturer using camera1 API."); |
| 549 createCapturer(new Camera1Enumerator(peerConnectionParameters.captureToT
exture)); |
506 } | 550 } |
507 Log.d(TAG, "Opening camera: " + cameraDeviceName); | 551 |
508 videoCapturer = VideoCapturerAndroid.create(cameraDeviceName, null, | |
509 peerConnectionParameters.captureToTexture); | |
510 if (videoCapturer == null) { | 552 if (videoCapturer == null) { |
511 reportError("Failed to open camera"); | 553 reportError("Failed to open camera"); |
512 return; | 554 return; |
513 } | 555 } |
514 mediaStream.addTrack(createVideoTrack(videoCapturer)); | 556 mediaStream.addTrack(createVideoTrack(videoCapturer)); |
515 } | 557 } |
516 | 558 |
517 mediaStream.addTrack(createAudioTrack()); | 559 mediaStream.addTrack(createAudioTrack()); |
518 peerConnection.addStream(mediaStream); | 560 peerConnection.addStream(mediaStream); |
519 | 561 |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 }); | 826 }); |
785 } | 827 } |
786 | 828 |
787 private AudioTrack createAudioTrack() { | 829 private AudioTrack createAudioTrack() { |
788 audioSource = factory.createAudioSource(audioConstraints); | 830 audioSource = factory.createAudioSource(audioConstraints); |
789 localAudioTrack = factory.createAudioTrack(AUDIO_TRACK_ID, audioSource); | 831 localAudioTrack = factory.createAudioTrack(AUDIO_TRACK_ID, audioSource); |
790 localAudioTrack.setEnabled(enableAudio); | 832 localAudioTrack.setEnabled(enableAudio); |
791 return localAudioTrack; | 833 return localAudioTrack; |
792 } | 834 } |
793 | 835 |
794 private VideoTrack createVideoTrack(VideoCapturerAndroid capturer) { | 836 private VideoTrack createVideoTrack(VideoCapturer capturer) { |
795 videoSource = factory.createVideoSource(capturer, videoConstraints); | 837 videoSource = factory.createVideoSource(capturer, videoConstraints); |
796 | 838 |
797 localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource); | 839 localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource); |
798 localVideoTrack.setEnabled(renderVideo); | 840 localVideoTrack.setEnabled(renderVideo); |
799 localVideoTrack.addRenderer(new VideoRenderer(localRender)); | 841 localVideoTrack.addRenderer(new VideoRenderer(localRender)); |
800 return localVideoTrack; | 842 return localVideoTrack; |
801 } | 843 } |
802 | 844 |
803 private static String setStartBitrate(String codec, boolean isVideoCodec, | 845 private static String setStartBitrate(String codec, boolean isVideoCodec, |
804 String sdpDescription, int bitrateKbps) { | 846 String sdpDescription, int bitrateKbps) { |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 public void onCreateFailure(final String error) { | 1191 public void onCreateFailure(final String error) { |
1150 reportError("createSDP error: " + error); | 1192 reportError("createSDP error: " + error); |
1151 } | 1193 } |
1152 | 1194 |
1153 @Override | 1195 @Override |
1154 public void onSetFailure(final String error) { | 1196 public void onSetFailure(final String error) { |
1155 reportError("setSDP error: " + error); | 1197 reportError("setSDP error: " + error); |
1156 } | 1198 } |
1157 } | 1199 } |
1158 } | 1200 } |
OLD | NEW |