Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Side by Side Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java

Issue 2077663003: Camera2 in AppRTC Android Demo. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@camera2_only
Patch Set: Rebase. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 android.content.Context; 13 import android.content.Context;
14 import android.os.ParcelFileDescriptor; 14 import android.os.ParcelFileDescriptor;
15 import android.os.Environment; 15 import android.os.Environment;
16 import android.util.Log; 16 import android.util.Log;
17 17
18 import org.appspot.apprtc.AppRTCClient.SignalingParameters; 18 import org.appspot.apprtc.AppRTCClient.SignalingParameters;
19 import org.webrtc.AudioTrack; 19 import org.webrtc.AudioTrack;
20 import org.webrtc.Camera1Enumerator;
21 import org.webrtc.Camera2Enumerator;
22 import org.webrtc.CameraEnumerator;
20 import org.webrtc.CameraEnumerationAndroid; 23 import org.webrtc.CameraEnumerationAndroid;
24 import org.webrtc.CameraVideoCapturer;
21 import org.webrtc.DataChannel; 25 import org.webrtc.DataChannel;
22 import org.webrtc.EglBase; 26 import org.webrtc.EglBase;
23 import org.webrtc.IceCandidate; 27 import org.webrtc.IceCandidate;
24 import org.webrtc.Logging; 28 import org.webrtc.Logging;
25 import org.webrtc.MediaCodecVideoEncoder; 29 import org.webrtc.MediaCodecVideoEncoder;
26 import org.webrtc.MediaConstraints; 30 import org.webrtc.MediaConstraints;
27 import org.webrtc.MediaConstraints.KeyValuePair; 31 import org.webrtc.MediaConstraints.KeyValuePair;
28 import org.webrtc.MediaStream; 32 import org.webrtc.MediaStream;
29 import org.webrtc.PeerConnection; 33 import org.webrtc.PeerConnection;
30 import org.webrtc.PeerConnection.IceConnectionState; 34 import org.webrtc.PeerConnection.IceConnectionState;
31 import org.webrtc.PeerConnectionFactory; 35 import org.webrtc.PeerConnectionFactory;
32 import org.webrtc.SdpObserver; 36 import org.webrtc.SdpObserver;
33 import org.webrtc.SessionDescription; 37 import org.webrtc.SessionDescription;
34 import org.webrtc.StatsObserver; 38 import org.webrtc.StatsObserver;
35 import org.webrtc.StatsReport; 39 import org.webrtc.StatsReport;
36 import org.webrtc.VideoCapturerAndroid; 40 import org.webrtc.VideoCapturer;
37 import org.webrtc.VideoRenderer; 41 import org.webrtc.VideoRenderer;
38 import org.webrtc.VideoSource; 42 import org.webrtc.VideoSource;
39 import org.webrtc.VideoTrack; 43 import org.webrtc.VideoTrack;
40 import org.webrtc.voiceengine.WebRtcAudioManager; 44 import org.webrtc.voiceengine.WebRtcAudioManager;
41 import org.webrtc.voiceengine.WebRtcAudioUtils; 45 import org.webrtc.voiceengine.WebRtcAudioUtils;
42 46
43 import java.io.File; 47 import java.io.File;
44 import java.io.IOException; 48 import java.io.IOException;
45 import java.util.EnumSet; 49 import java.util.EnumSet;
46 import java.util.LinkedList; 50 import java.util.LinkedList;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 private static final int HD_VIDEO_HEIGHT = 720; 90 private static final int HD_VIDEO_HEIGHT = 720;
87 private static final int MAX_VIDEO_WIDTH = 1280; 91 private static final int MAX_VIDEO_WIDTH = 1280;
88 private static final int MAX_VIDEO_HEIGHT = 1280; 92 private static final int MAX_VIDEO_HEIGHT = 1280;
89 private static final int MAX_VIDEO_FPS = 30; 93 private static final int MAX_VIDEO_FPS = 30;
90 94
91 private static final PeerConnectionClient instance = new PeerConnectionClient( ); 95 private static final PeerConnectionClient instance = new PeerConnectionClient( );
92 private final PCObserver pcObserver = new PCObserver(); 96 private final PCObserver pcObserver = new PCObserver();
93 private final SDPObserver sdpObserver = new SDPObserver(); 97 private final SDPObserver sdpObserver = new SDPObserver();
94 private final ScheduledExecutorService executor; 98 private final ScheduledExecutorService executor;
95 99
100 private Context context;
96 private PeerConnectionFactory factory; 101 private PeerConnectionFactory factory;
97 private PeerConnection peerConnection; 102 private PeerConnection peerConnection;
98 PeerConnectionFactory.Options options = null; 103 PeerConnectionFactory.Options options = null;
99 private VideoSource videoSource; 104 private VideoSource videoSource;
100 private boolean videoCallEnabled; 105 private boolean videoCallEnabled;
101 private boolean preferIsac; 106 private boolean preferIsac;
102 private String preferredVideoCodec; 107 private String preferredVideoCodec;
103 private boolean videoSourceStopped; 108 private boolean videoSourceStopped;
104 private boolean isError; 109 private boolean isError;
105 private Timer statsTimer; 110 private Timer statsTimer;
106 private VideoRenderer.Callbacks localRender; 111 private VideoRenderer.Callbacks localRender;
107 private VideoRenderer.Callbacks remoteRender; 112 private VideoRenderer.Callbacks remoteRender;
108 private SignalingParameters signalingParameters; 113 private SignalingParameters signalingParameters;
109 private MediaConstraints pcConstraints; 114 private MediaConstraints pcConstraints;
110 private MediaConstraints videoConstraints; 115 private MediaConstraints videoConstraints;
111 private MediaConstraints audioConstraints; 116 private MediaConstraints audioConstraints;
112 private ParcelFileDescriptor aecDumpFileDescriptor; 117 private ParcelFileDescriptor aecDumpFileDescriptor;
113 private MediaConstraints sdpMediaConstraints; 118 private MediaConstraints sdpMediaConstraints;
114 private PeerConnectionParameters peerConnectionParameters; 119 private PeerConnectionParameters peerConnectionParameters;
115 // Queued remote ICE candidates are consumed only after both local and 120 // Queued remote ICE candidates are consumed only after both local and
116 // remote descriptions are set. Similarly local ICE candidates are sent to 121 // remote descriptions are set. Similarly local ICE candidates are sent to
117 // remote peer after both local and remote description are set. 122 // remote peer after both local and remote description are set.
118 private LinkedList<IceCandidate> queuedRemoteCandidates; 123 private LinkedList<IceCandidate> queuedRemoteCandidates;
119 private PeerConnectionEvents events; 124 private PeerConnectionEvents events;
120 private boolean isInitiator; 125 private boolean isInitiator;
121 private SessionDescription localSdp; // either offer or answer SDP 126 private SessionDescription localSdp; // either offer or answer SDP
122 private MediaStream mediaStream; 127 private MediaStream mediaStream;
123 private int numberOfCameras; 128 private int numberOfCameras;
124 private VideoCapturerAndroid videoCapturer; 129 private CameraVideoCapturer videoCapturer;
125 // enableVideo is set to true if video should be rendered and sent. 130 // enableVideo is set to true if video should be rendered and sent.
126 private boolean renderVideo; 131 private boolean renderVideo;
127 private VideoTrack localVideoTrack; 132 private VideoTrack localVideoTrack;
128 private VideoTrack remoteVideoTrack; 133 private VideoTrack remoteVideoTrack;
129 // enableAudio is set to true if audio should be sent. 134 // enableAudio is set to true if audio should be sent.
130 private boolean enableAudio; 135 private boolean enableAudio;
131 private AudioTrack localAudioTrack; 136 private AudioTrack localAudioTrack;
132 137
133 /** 138 /**
134 * Peer connection parameters. 139 * Peer connection parameters.
135 */ 140 */
136 public static class PeerConnectionParameters { 141 public static class PeerConnectionParameters {
137 public final boolean videoCallEnabled; 142 public final boolean videoCallEnabled;
138 public final boolean loopback; 143 public final boolean loopback;
139 public final boolean tracing; 144 public final boolean tracing;
145 public final boolean camera2Enabled;
146 public final boolean camera1Enabled;
140 public final int videoWidth; 147 public final int videoWidth;
141 public final int videoHeight; 148 public final int videoHeight;
142 public final int videoFps; 149 public final int videoFps;
143 public final int videoStartBitrate; 150 public final int videoStartBitrate;
144 public final String videoCodec; 151 public final String videoCodec;
145 public final boolean videoCodecHwAcceleration; 152 public final boolean videoCodecHwAcceleration;
146 public final boolean captureToTexture; 153 public final boolean captureToTexture;
147 public final int audioStartBitrate; 154 public final int audioStartBitrate;
148 public final String audioCodec; 155 public final String audioCodec;
149 public final boolean noAudioProcessing; 156 public final boolean noAudioProcessing;
150 public final boolean aecDump; 157 public final boolean aecDump;
151 public final boolean useOpenSLES; 158 public final boolean useOpenSLES;
152 public final boolean disableBuiltInAEC; 159 public final boolean disableBuiltInAEC;
153 160
154 public PeerConnectionParameters( 161 public PeerConnectionParameters(
155 boolean videoCallEnabled, boolean loopback, boolean tracing, 162 boolean videoCallEnabled, boolean loopback, boolean tracing, boolean cam era2Enabled,
156 int videoWidth, int videoHeight, int videoFps, int videoStartBitrate, 163 boolean camera1Enabled, int videoWidth, int videoHeight, int videoFps,
157 String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTe xture, 164 int videoStartBitrate, String videoCodec, boolean videoCodecHwAccelerati on,
158 int audioStartBitrate, String audioCodec, 165 boolean captureToTexture, int audioStartBitrate, String audioCodec,
159 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, 166 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES,
160 boolean disableBuiltInAEC) { 167 boolean disableBuiltInAEC) {
161 this.videoCallEnabled = videoCallEnabled; 168 this.videoCallEnabled = videoCallEnabled;
169 this.camera2Enabled = camera2Enabled;
170 this.camera1Enabled = camera1Enabled;
162 this.loopback = loopback; 171 this.loopback = loopback;
163 this.tracing = tracing; 172 this.tracing = tracing;
164 this.videoWidth = videoWidth; 173 this.videoWidth = videoWidth;
165 this.videoHeight = videoHeight; 174 this.videoHeight = videoHeight;
166 this.videoFps = videoFps; 175 this.videoFps = videoFps;
167 this.videoStartBitrate = videoStartBitrate; 176 this.videoStartBitrate = videoStartBitrate;
168 this.videoCodec = videoCodec; 177 this.videoCodec = videoCodec;
169 this.videoCodecHwAcceleration = videoCodecHwAcceleration; 178 this.videoCodecHwAcceleration = videoCodecHwAcceleration;
170 this.captureToTexture = captureToTexture; 179 this.captureToTexture = captureToTexture;
171 this.audioStartBitrate = audioStartBitrate; 180 this.audioStartBitrate = audioStartBitrate;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 } 249 }
241 250
242 public void createPeerConnectionFactory( 251 public void createPeerConnectionFactory(
243 final Context context, 252 final Context context,
244 final PeerConnectionParameters peerConnectionParameters, 253 final PeerConnectionParameters peerConnectionParameters,
245 final PeerConnectionEvents events) { 254 final PeerConnectionEvents events) {
246 this.peerConnectionParameters = peerConnectionParameters; 255 this.peerConnectionParameters = peerConnectionParameters;
247 this.events = events; 256 this.events = events;
248 videoCallEnabled = peerConnectionParameters.videoCallEnabled; 257 videoCallEnabled = peerConnectionParameters.videoCallEnabled;
249 // Reset variables to initial states. 258 // Reset variables to initial states.
259 this.context = null;
250 factory = null; 260 factory = null;
251 peerConnection = null; 261 peerConnection = null;
252 preferIsac = false; 262 preferIsac = false;
253 videoSourceStopped = false; 263 videoSourceStopped = false;
254 isError = false; 264 isError = false;
255 queuedRemoteCandidates = null; 265 queuedRemoteCandidates = null;
256 localSdp = null; // either offer or answer SDP 266 localSdp = null; // either offer or answer SDP
257 mediaStream = null; 267 mediaStream = null;
258 videoCapturer = null; 268 videoCapturer = null;
259 renderVideo = true; 269 renderVideo = true;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 367 }
358 368
359 // Create peer connection factory. 369 // Create peer connection factory.
360 if (!PeerConnectionFactory.initializeAndroidGlobals(context, true, true, 370 if (!PeerConnectionFactory.initializeAndroidGlobals(context, true, true,
361 peerConnectionParameters.videoCodecHwAcceleration)) { 371 peerConnectionParameters.videoCodecHwAcceleration)) {
362 events.onPeerConnectionError("Failed to initializeAndroidGlobals"); 372 events.onPeerConnectionError("Failed to initializeAndroidGlobals");
363 } 373 }
364 if (options != null) { 374 if (options != null) {
365 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas k); 375 Log.d(TAG, "Factory networkIgnoreMask option: " + options.networkIgnoreMas k);
366 } 376 }
377 this.context = context;
367 factory = new PeerConnectionFactory(options); 378 factory = new PeerConnectionFactory(options);
368 Log.d(TAG, "Peer connection factory created."); 379 Log.d(TAG, "Peer connection factory created.");
369 } 380 }
370 381
371 private void createMediaConstraintsInternal() { 382 private void createMediaConstraintsInternal() {
372 // Create peer connection constraints. 383 // Create peer connection constraints.
373 pcConstraints = new MediaConstraints(); 384 pcConstraints = new MediaConstraints();
374 // Enable DTLS for normal calls and disable for loopback calls. 385 // Enable DTLS for normal calls and disable for loopback calls.
375 if (peerConnectionParameters.loopback) { 386 if (peerConnectionParameters.loopback) {
376 pcConstraints.optional.add( 387 pcConstraints.optional.add(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 "OfferToReceiveAudio", "true")); 457 "OfferToReceiveAudio", "true"));
447 if (videoCallEnabled || peerConnectionParameters.loopback) { 458 if (videoCallEnabled || peerConnectionParameters.loopback) {
448 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( 459 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
449 "OfferToReceiveVideo", "true")); 460 "OfferToReceiveVideo", "true"));
450 } else { 461 } else {
451 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair( 462 sdpMediaConstraints.mandatory.add(new MediaConstraints.KeyValuePair(
452 "OfferToReceiveVideo", "false")); 463 "OfferToReceiveVideo", "false"));
453 } 464 }
454 } 465 }
455 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) {
magjed_webrtc 2016/06/29 13:36:45 There is no need for this null check (with the cur
sakal 2016/06/30 09:14:52 I'd rather keep it. It used to be Camera2Enumerato
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
456 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) { 497 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) {
457 if (factory == null || isError) { 498 if (factory == null || isError) {
458 Log.e(TAG, "Peerconnection factory is not created"); 499 Log.e(TAG, "Peerconnection factory is not created");
459 return; 500 return;
460 } 501 }
461 Log.d(TAG, "Create peer connection."); 502 Log.d(TAG, "Create peer connection.");
462 503
463 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); 504 Log.d(TAG, "PCConstraints: " + pcConstraints.toString());
464 if (videoConstraints != null) { 505 if (videoConstraints != null) {
465 Log.d(TAG, "VideoConstraints: " + videoConstraints.toString()); 506 Log.d(TAG, "VideoConstraints: " + videoConstraints.toString());
(...skipping 22 matching lines...) Expand all
488 529
489 // Set default WebRTC tracing and INFO libjingle logging. 530 // Set default WebRTC tracing and INFO libjingle logging.
490 // NOTE: this _must_ happen while |factory| is alive! 531 // NOTE: this _must_ happen while |factory| is alive!
491 Logging.enableTracing( 532 Logging.enableTracing(
492 "logcat:", 533 "logcat:",
493 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT), 534 EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT),
494 Logging.Severity.LS_INFO); 535 Logging.Severity.LS_INFO);
495 536
496 mediaStream = factory.createLocalMediaStream("ARDAMS"); 537 mediaStream = factory.createLocalMediaStream("ARDAMS");
497 if (videoCallEnabled) { 538 if (videoCallEnabled) {
498 String cameraDeviceName = CameraEnumerationAndroid.getDeviceName(0); 539 if (Camera2Enumerator.isSupported() && peerConnectionParameters.camera2Ena bled) {
499 String frontCameraDeviceName = 540 Logging.d(TAG, "Creating capturer using camera2 API.");
500 CameraEnumerationAndroid.getNameOfFrontFacingDevice(); 541 createCapturer(new Camera2Enumerator(context));
501 if (numberOfCameras > 1 && frontCameraDeviceName != null) {
502 cameraDeviceName = frontCameraDeviceName;
503 } 542 }
504 Log.d(TAG, "Opening camera: " + cameraDeviceName); 543
505 videoCapturer = VideoCapturerAndroid.create(cameraDeviceName, null, 544 if (videoCapturer == null && peerConnectionParameters.camera1Enabled) {
506 peerConnectionParameters.captureToTexture); 545 Logging.d(TAG, "Creating capturer using camera1 API.");
546 createCapturer(new Camera1Enumerator());
547 }
548
507 if (videoCapturer == null) { 549 if (videoCapturer == null) {
508 reportError("Failed to open camera"); 550 reportError("Failed to open camera");
509 return; 551 return;
510 } 552 }
511 mediaStream.addTrack(createVideoTrack(videoCapturer)); 553 mediaStream.addTrack(createVideoTrack(videoCapturer));
512 } 554 }
513 555
514 mediaStream.addTrack(createAudioTrack()); 556 mediaStream.addTrack(createAudioTrack());
515 peerConnection.addStream(mediaStream); 557 peerConnection.addStream(mediaStream);
516 558
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 } 819 }
778 820
779 private AudioTrack createAudioTrack() { 821 private AudioTrack createAudioTrack() {
780 localAudioTrack = factory.createAudioTrack( 822 localAudioTrack = factory.createAudioTrack(
781 AUDIO_TRACK_ID, 823 AUDIO_TRACK_ID,
782 factory.createAudioSource(audioConstraints)); 824 factory.createAudioSource(audioConstraints));
783 localAudioTrack.setEnabled(enableAudio); 825 localAudioTrack.setEnabled(enableAudio);
784 return localAudioTrack; 826 return localAudioTrack;
785 } 827 }
786 828
787 private VideoTrack createVideoTrack(VideoCapturerAndroid capturer) { 829 private VideoTrack createVideoTrack(VideoCapturer capturer) {
788 videoSource = factory.createVideoSource(capturer, videoConstraints); 830 videoSource = factory.createVideoSource(capturer, videoConstraints);
789 831
790 localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource); 832 localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource);
791 localVideoTrack.setEnabled(renderVideo); 833 localVideoTrack.setEnabled(renderVideo);
792 localVideoTrack.addRenderer(new VideoRenderer(localRender)); 834 localVideoTrack.addRenderer(new VideoRenderer(localRender));
793 return localVideoTrack; 835 return localVideoTrack;
794 } 836 }
795 837
796 private static String setStartBitrate(String codec, boolean isVideoCodec, 838 private static String setStartBitrate(String codec, boolean isVideoCodec,
797 String sdpDescription, int bitrateKbps) { 839 String sdpDescription, int bitrateKbps) {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 public void onCreateFailure(final String error) { 1184 public void onCreateFailure(final String error) {
1143 reportError("createSDP error: " + error); 1185 reportError("createSDP error: " + error);
1144 } 1186 }
1145 1187
1146 @Override 1188 @Override
1147 public void onSetFailure(final String error) { 1189 public void onSetFailure(final String error) {
1148 reportError("setSDP error: " + error); 1190 reportError("setSDP error: " + error);
1149 } 1191 }
1150 } 1192 }
1151 } 1193 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698