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

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

Issue 2273573003: Support for video file instead of camera and output video out to file (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing review comments, except unittesting Created 4 years, 2 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
(...skipping 23 matching lines...) Expand all
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698