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

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: Fixed copyright header for start_loopback_stubbed_camera_saved_video_out.py 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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
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(boolean videoCallEnabled, boolean loopback, boolean tracing,
165 boolean useCamera2, int videoWidth, int videoHeight, int videoFps, int v ideoMaxBitrate, 168 int videoWidth, int videoHeight, int videoFps, int videoMaxBitrate, Stri ng videoCodec,
166 String videoCodec, boolean videoCodecHwAcceleration, boolean captureToTe xture, 169 boolean videoCodecHwAcceleration, int audioStartBitrate, String audioCod ec,
167 int audioStartBitrate, String audioCodec, boolean noAudioProcessing, boo lean aecDump, 170 boolean noAudioProcessing, boolean aecDump, boolean useOpenSLES, boolean disableBuiltInAEC,
168 boolean useOpenSLES, boolean disableBuiltInAEC, boolean disableBuiltInAG C, 171 boolean disableBuiltInAGC, boolean disableBuiltInNS, boolean enableLevel Control) {
169 boolean disableBuiltInNS, boolean enableLevelControl) {
170 this.videoCallEnabled = videoCallEnabled; 172 this.videoCallEnabled = videoCallEnabled;
171 this.useCamera2 = useCamera2;
172 this.loopback = loopback; 173 this.loopback = loopback;
173 this.tracing = tracing; 174 this.tracing = tracing;
174 this.videoWidth = videoWidth; 175 this.videoWidth = videoWidth;
175 this.videoHeight = videoHeight; 176 this.videoHeight = videoHeight;
176 this.videoFps = videoFps; 177 this.videoFps = videoFps;
177 this.videoMaxBitrate = videoMaxBitrate; 178 this.videoMaxBitrate = videoMaxBitrate;
178 this.videoCodec = videoCodec; 179 this.videoCodec = videoCodec;
179 this.videoCodecHwAcceleration = videoCodecHwAcceleration; 180 this.videoCodecHwAcceleration = videoCodecHwAcceleration;
180 this.captureToTexture = captureToTexture;
181 this.audioStartBitrate = audioStartBitrate; 181 this.audioStartBitrate = audioStartBitrate;
182 this.audioCodec = audioCodec; 182 this.audioCodec = audioCodec;
183 this.noAudioProcessing = noAudioProcessing; 183 this.noAudioProcessing = noAudioProcessing;
184 this.aecDump = aecDump; 184 this.aecDump = aecDump;
185 this.useOpenSLES = useOpenSLES; 185 this.useOpenSLES = useOpenSLES;
186 this.disableBuiltInAEC = disableBuiltInAEC; 186 this.disableBuiltInAEC = disableBuiltInAEC;
187 this.disableBuiltInAGC = disableBuiltInAGC; 187 this.disableBuiltInAGC = disableBuiltInAGC;
188 this.disableBuiltInNS = disableBuiltInNS; 188 this.disableBuiltInNS = disableBuiltInNS;
189 this.enableLevelControl = enableLevelControl; 189 this.enableLevelControl = enableLevelControl;
190 } 190 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 executor.execute(new Runnable() { 279 executor.execute(new Runnable() {
280 @Override 280 @Override
281 public void run() { 281 public void run() {
282 createPeerConnectionFactoryInternal(context); 282 createPeerConnectionFactoryInternal(context);
283 } 283 }
284 }); 284 });
285 } 285 }
286 286
287 public void createPeerConnection(final EglBase.Context renderEGLContext, 287 public void createPeerConnection(final EglBase.Context renderEGLContext,
288 final VideoRenderer.Callbacks localRender, final VideoRenderer.Callbacks r emoteRender, 288 final VideoRenderer.Callbacks localRender, final VideoRenderer.Callbacks r emoteRender,
289 final SignalingParameters signalingParameters) { 289 final VideoCapturer videoCapturer, final SignalingParameters signalingPara meters) {
290 createPeerConnection(renderEGLContext, localRender, Collections.singletonLis t(remoteRender),
291 videoCapturer, signalingParameters);
292 }
293 public void createPeerConnection(final EglBase.Context renderEGLContext,
294 final VideoRenderer.Callbacks localRender, final List<VideoRenderer.Callba cks> remoteRenders,
295 final VideoCapturer videoCapturer, final SignalingParameters signalingPara meters) {
290 if (peerConnectionParameters == null) { 296 if (peerConnectionParameters == null) {
291 Log.e(TAG, "Creating peer connection without initializing factory."); 297 Log.e(TAG, "Creating peer connection without initializing factory.");
292 return; 298 return;
293 } 299 }
294 this.localRender = localRender; 300 this.localRender = localRender;
295 this.remoteRender = remoteRender; 301 this.remoteRenders = remoteRenders;
302 this.videoCapturer = videoCapturer;
296 this.signalingParameters = signalingParameters; 303 this.signalingParameters = signalingParameters;
297 executor.execute(new Runnable() { 304 executor.execute(new Runnable() {
298 @Override 305 @Override
299 public void run() { 306 public void run() {
300 try { 307 try {
301 createMediaConstraintsInternal(); 308 createMediaConstraintsInternal();
302 createPeerConnectionInternal(renderEGLContext); 309 createPeerConnectionInternal(renderEGLContext);
303 } catch (Exception e) { 310 } catch (Exception e) {
304 reportError("Failed to create peer connection: " + e.getMessage()); 311 reportError("Failed to create peer connection: " + e.getMessage());
305 throw e; 312 throw e;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true")); 468 new MediaConstraints.KeyValuePair("OfferToReceiveAudio", "true"));
462 if (videoCallEnabled || peerConnectionParameters.loopback) { 469 if (videoCallEnabled || peerConnectionParameters.loopback) {
463 sdpMediaConstraints.mandatory.add( 470 sdpMediaConstraints.mandatory.add(
464 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true")); 471 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"));
465 } else { 472 } else {
466 sdpMediaConstraints.mandatory.add( 473 sdpMediaConstraints.mandatory.add(
467 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false")); 474 new MediaConstraints.KeyValuePair("OfferToReceiveVideo", "false"));
468 } 475 }
469 } 476 }
470 477
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) { 478 private void createPeerConnectionInternal(EglBase.Context renderEGLContext) {
502 if (factory == null || isError) { 479 if (factory == null || isError) {
503 Log.e(TAG, "Peerconnection factory is not created"); 480 Log.e(TAG, "Peerconnection factory is not created");
504 return; 481 return;
505 } 482 }
506 Log.d(TAG, "Create peer connection."); 483 Log.d(TAG, "Create peer connection.");
507 484
508 Log.d(TAG, "PCConstraints: " + pcConstraints.toString()); 485 Log.d(TAG, "PCConstraints: " + pcConstraints.toString());
509 queuedRemoteCandidates = new LinkedList<IceCandidate>(); 486 queuedRemoteCandidates = new LinkedList<IceCandidate>();
510 487
(...skipping 16 matching lines...) Expand all
527 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb server); 504 peerConnection = factory.createPeerConnection(rtcConfig, pcConstraints, pcOb server);
528 isInitiator = false; 505 isInitiator = false;
529 506
530 // Set default WebRTC tracing and INFO libjingle logging. 507 // Set default WebRTC tracing and INFO libjingle logging.
531 // NOTE: this _must_ happen while |factory| is alive! 508 // NOTE: this _must_ happen while |factory| is alive!
532 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT )); 509 Logging.enableTracing("logcat:", EnumSet.of(Logging.TraceLevel.TRACE_DEFAULT ));
533 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO); 510 Logging.enableLogToDebugOutput(Logging.Severity.LS_INFO);
534 511
535 mediaStream = factory.createLocalMediaStream("ARDAMS"); 512 mediaStream = factory.createLocalMediaStream("ARDAMS");
536 if (videoCallEnabled) { 513 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)); 514 mediaStream.addTrack(createVideoTrack(videoCapturer));
555 } 515 }
556 516
557 mediaStream.addTrack(createAudioTrack()); 517 mediaStream.addTrack(createAudioTrack());
558 peerConnection.addStream(mediaStream); 518 peerConnection.addStream(mediaStream);
559 if (videoCallEnabled) { 519 if (videoCallEnabled) {
560 findVideoSender(); 520 findVideoSender();
561 } 521 }
562 522
563 if (peerConnectionParameters.aecDump) { 523 if (peerConnectionParameters.aecDump) {
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 if (queuedRemoteCandidates != null) { 956 if (queuedRemoteCandidates != null) {
997 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates"); 957 Log.d(TAG, "Add " + queuedRemoteCandidates.size() + " remote candidates");
998 for (IceCandidate candidate : queuedRemoteCandidates) { 958 for (IceCandidate candidate : queuedRemoteCandidates) {
999 peerConnection.addIceCandidate(candidate); 959 peerConnection.addIceCandidate(candidate);
1000 } 960 }
1001 queuedRemoteCandidates = null; 961 queuedRemoteCandidates = null;
1002 } 962 }
1003 } 963 }
1004 964
1005 private void switchCameraInternal() { 965 private void switchCameraInternal() {
1006 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer == null) { 966 if (videoCapturer instanceof CameraVideoCapturer) {
1007 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Erro r : " + isError 967 if (!videoCallEnabled || numberOfCameras < 2 || isError || videoCapturer = = null) {
1008 + ". Number of cameras: " + numberOfCameras); 968 Log.e(TAG, "Failed to switch camera. Video: " + videoCallEnabled + ". Er ror : " + isError
1009 return; // No video is sent or only one camera is available or error happe ned. 969 + ". Number of cameras: " + numberOfCameras);
970 return; // No video is sent or only one camera is available or error hap pened.
971 }
972 Log.d(TAG, "Switch camera");
973 CameraVideoCapturer cameraVideoCapturer = (CameraVideoCapturer) videoCaptu rer;
974 cameraVideoCapturer.switchCamera(null);
975 } else {
976 Log.d(TAG, "Will not switch camera, video caputurer is not a camera");
1010 } 977 }
1011 Log.d(TAG, "Switch camera");
1012 videoCapturer.switchCamera(null);
1013 } 978 }
1014 979
1015 public void switchCamera() { 980 public void switchCamera() {
1016 executor.execute(new Runnable() { 981 executor.execute(new Runnable() {
1017 @Override 982 @Override
1018 public void run() { 983 public void run() {
1019 switchCameraInternal(); 984 switchCameraInternal();
1020 } 985 }
1021 }); 986 });
1022 } 987 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 if (peerConnection == null || isError) { 1067 if (peerConnection == null || isError) {
1103 return; 1068 return;
1104 } 1069 }
1105 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) { 1070 if (stream.audioTracks.size() > 1 || stream.videoTracks.size() > 1) {
1106 reportError("Weird-looking stream: " + stream); 1071 reportError("Weird-looking stream: " + stream);
1107 return; 1072 return;
1108 } 1073 }
1109 if (stream.videoTracks.size() == 1) { 1074 if (stream.videoTracks.size() == 1) {
1110 remoteVideoTrack = stream.videoTracks.get(0); 1075 remoteVideoTrack = stream.videoTracks.get(0);
1111 remoteVideoTrack.setEnabled(renderVideo); 1076 remoteVideoTrack.setEnabled(renderVideo);
1112 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender)); 1077 for (VideoRenderer.Callbacks remoteRender : remoteRenders) {
1078 remoteVideoTrack.addRenderer(new VideoRenderer(remoteRender));
1079 }
1113 } 1080 }
1114 } 1081 }
1115 }); 1082 });
1116 } 1083 }
1117 1084
1118 @Override 1085 @Override
1119 public void onRemoveStream(final MediaStream stream) { 1086 public void onRemoveStream(final MediaStream stream) {
1120 executor.execute(new Runnable() { 1087 executor.execute(new Runnable() {
1121 @Override 1088 @Override
1122 public void run() { 1089 public void run() {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 public void onCreateFailure(final String error) { 1177 public void onCreateFailure(final String error) {
1211 reportError("createSDP error: " + error); 1178 reportError("createSDP error: " + error);
1212 } 1179 }
1213 1180
1214 @Override 1181 @Override
1215 public void onSetFailure(final String error) { 1182 public void onSetFailure(final String error) {
1216 reportError("setSDP error: " + error); 1183 reportError("setSDP error: " + error);
1217 } 1184 }
1218 } 1185 }
1219 } 1186 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698