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

Unified Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.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 side-by-side diff with in-line comments
Download patch
Index: webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
diff --git a/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java b/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
index a1ea8a457d2ed2e1589e56e1828ea23e6c5a4bfe..6a64e53b6900cc8175bb8e69426e58283bc7e536 100644
--- a/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
+++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
@@ -29,14 +29,26 @@ import android.view.Window;
import android.view.WindowManager.LayoutParams;
import android.widget.Toast;
+import java.io.IOException;
+import java.lang.RuntimeException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
+import org.webrtc.CameraEnumerator;
import org.webrtc.EglBase;
+import org.webrtc.FileVideoCapturer;
+import org.webrtc.VideoFileRenderer;
import org.webrtc.IceCandidate;
+import org.webrtc.Logging;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RendererCommon.ScalingType;
import org.webrtc.SessionDescription;
import org.webrtc.StatsReport;
import org.webrtc.SurfaceViewRenderer;
+import org.webrtc.VideoCapturer;
+import org.webrtc.VideoRenderer;
/**
* Activity for peer connection call setup, call waiting
@@ -96,6 +108,16 @@ public class CallActivity extends Activity
"org.appspot.apprtc.CMDLINE";
public static final String EXTRA_RUNTIME =
"org.appspot.apprtc.RUNTIME";
+ public static final String EXTRA_VIDEO_FILE_AS_CAMERA =
+ "org.appspot.apprtc.VIDEO_FILE_AS_CAMERA";
sakal 2016/10/05 13:28:41 Please correct the indentation on this and followi
mandermo 2016/10/07 11:33:41 Done.
+ public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE =
+ "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE";
+ public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH =
+ "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_WIDTH";
+ public static final String EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT =
+ "org.appspot.apprtc.SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT";
+ public static final String EXTRA_USE_VALUES_FROM_INTENT =
+ "org.appspot.apprtc.USE_VALUES_FROM_INTENT";
private static final String TAG = "CallRTCClient";
// List of mandatory application permissions.
@@ -128,7 +150,9 @@ public class CallActivity extends Activity
private AppRTCAudioManager audioManager = null;
private EglBase rootEglBase;
private SurfaceViewRenderer localRender;
- private SurfaceViewRenderer remoteRender;
+ private SurfaceViewRenderer remoteRenderScreen;
+ private VideoFileRenderer videoFileRenderer;
+ private List<VideoRenderer.Callbacks> remoteRenders = new ArrayList<VideoRenderer.Callbacks>();
sakal 2016/10/05 13:28:41 final
mandermo 2016/10/07 11:33:40 Made remoteRenders final and changed name to remot
private PercentFrameLayout localRenderLayout;
private PercentFrameLayout remoteRenderLayout;
private ScalingType scalingType;
@@ -176,7 +200,7 @@ public class CallActivity extends Activity
// Create UI controls.
localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view);
- remoteRender = (SurfaceViewRenderer) findViewById(R.id.remote_video_view);
+ remoteRenderScreen = (SurfaceViewRenderer) findViewById(R.id.remote_video_view);
localRenderLayout = (PercentFrameLayout) findViewById(R.id.local_video_layout);
remoteRenderLayout = (PercentFrameLayout) findViewById(R.id.remote_video_layout);
callFragment = new CallFragment();
@@ -191,12 +215,31 @@ public class CallActivity extends Activity
};
localRender.setOnClickListener(listener);
- remoteRender.setOnClickListener(listener);
+ remoteRenderScreen.setOnClickListener(listener);
+ remoteRenders.add(remoteRenderScreen);
+
+ final Intent intent = getIntent();
// Create video renderers.
rootEglBase = EglBase.create();
localRender.init(rootEglBase.getEglBaseContext(), null);
- remoteRender.init(rootEglBase.getEglBaseContext(), null);
+ String saveRemoteVideoToFile = intent.getStringExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE);
+
+ // When saveRemoveToFile is set we save the video from the remote to a file.
sakal 2016/10/05 13:28:41 saveRemoveToFile -> saveRemoteVideoToFile
mandermo 2016/10/07 11:33:41 Done.
+ if (saveRemoteVideoToFile != null) {
+ int videoOutWidth = intent.getIntExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH, 0);
+ int videoOutHeight = intent.getIntExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT, 0);
+ try {
+ videoFileRenderer = new VideoFileRenderer(
+ saveRemoteVideoToFile, videoOutWidth, videoOutHeight,
+ rootEglBase.getEglBaseContext());
+ remoteRenders.add(videoFileRenderer);
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to open video file for output: " + saveRemoteVideoToFile, e);
+ }
+ }
+ remoteRenderScreen.init(rootEglBase.getEglBaseContext(), null);
+
localRender.setZOrderMediaOverlay(true);
updateVideoView();
@@ -211,7 +254,6 @@ public class CallActivity extends Activity
}
// Get Intent parameters.
sakal 2016/10/05 13:28:41 nit: move comment
mandermo 2016/10/07 11:33:41 Moved to before String roomId = intent.getStringEx
- final Intent intent = getIntent();
Uri roomUri = intent.getData();
if (roomUri == null) {
logAndToast(getString(R.string.missing_url));
@@ -221,6 +263,7 @@ public class CallActivity extends Activity
return;
}
String roomId = intent.getStringExtra(EXTRA_ROOMID);
+ Log.d(TAG, "Room ID: " + roomId);
if (roomId == null || roomId.length() == 0) {
logAndToast(getString(R.string.missing_url));
Log.e(TAG, "Incorrect room ID in intent!");
@@ -232,21 +275,16 @@ public class CallActivity extends Activity
boolean loopback = intent.getBooleanExtra(EXTRA_LOOPBACK, false);
boolean tracing = intent.getBooleanExtra(EXTRA_TRACING, false);
- boolean useCamera2 = Camera2Enumerator.isSupported()
- && intent.getBooleanExtra(EXTRA_CAMERA2, true);
-
peerConnectionParameters = new PeerConnectionParameters(
intent.getBooleanExtra(EXTRA_VIDEO_CALL, true),
loopback,
tracing,
- useCamera2,
intent.getIntExtra(EXTRA_VIDEO_WIDTH, 0),
intent.getIntExtra(EXTRA_VIDEO_HEIGHT, 0),
intent.getIntExtra(EXTRA_VIDEO_FPS, 0),
intent.getIntExtra(EXTRA_VIDEO_BITRATE, 0),
intent.getStringExtra(EXTRA_VIDEOCODEC),
intent.getBooleanExtra(EXTRA_HWCODEC_ENABLED, true),
- intent.getBooleanExtra(EXTRA_CAPTURETOTEXTURE_ENABLED, false),
intent.getIntExtra(EXTRA_AUDIO_BITRATE, 0),
intent.getStringExtra(EXTRA_AUDIOCODEC),
intent.getBooleanExtra(EXTRA_NOAUDIOPROCESSING_ENABLED, false),
@@ -256,9 +294,10 @@ public class CallActivity extends Activity
intent.getBooleanExtra(EXTRA_DISABLE_BUILT_IN_AGC, false),
intent.getBooleanExtra(EXTRA_DISABLE_BUILT_IN_NS, false),
intent.getBooleanExtra(EXTRA_ENABLE_LEVEL_CONTROL, false));
- commandLineRun = intent.getBooleanExtra(EXTRA_CMDLINE, false);
runTimeMs = intent.getIntExtra(EXTRA_RUNTIME, 0);
+ Log.d(TAG, "VIDEO_FILE: '" + intent.getStringExtra(EXTRA_VIDEO_FILE_AS_CAMERA) + "'");
+
// Create connection client. Use DirectRTCClient if room name is an IP otherwise use the
// standard WebSocketRTCClient.
if (loopback || !DirectRTCClient.IP_PATTERN.matcher(roomId).matches()) {
@@ -305,6 +344,47 @@ public class CallActivity extends Activity
CallActivity.this, peerConnectionParameters, CallActivity.this);
}
+ private boolean useCamera2() {
+ return Camera2Enumerator.isSupported()
+ && getIntent().getBooleanExtra(EXTRA_CAMERA2, true);
+ }
+
+ private boolean captureToTexture() {
+ return getIntent().getBooleanExtra(EXTRA_CAPTURETOTEXTURE_ENABLED, false);
+ }
+
+ private VideoCapturer createCapturer(CameraEnumerator enumerator) {
sakal 2016/10/05 13:28:41 nit: rename to createCameraCapturer
mandermo 2016/10/07 11:33:41 Done. Change name of createVideoCapturer in PeerCo
+ final String[] deviceNames = enumerator.getDeviceNames();
+
+ // First, try to find front facing camera
+ Logging.d(TAG, "Looking for front facing cameras.");
+ for (String deviceName : deviceNames) {
+ if (enumerator.isFrontFacing(deviceName)) {
+ Logging.d(TAG, "Creating front facing camera capturer.");
+ VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
+
+ if (videoCapturer != null) {
+ return videoCapturer;
+ }
+ }
+ }
+
+ // Front facing camera not found, try something else
+ Logging.d(TAG, "Looking for other cameras.");
+ for (String deviceName : deviceNames) {
+ if (!enumerator.isFrontFacing(deviceName)) {
+ Logging.d(TAG, "Creating other camera capturer.");
+ VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
+
+ if (videoCapturer != null) {
+ return videoCapturer;
+ }
+ }
+ }
+
+ return null;
+ }
+
// Activity interfaces
@Override
public void onPause() {
@@ -393,8 +473,8 @@ public class CallActivity extends Activity
private void updateVideoView() {
remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT);
- remoteRender.setScalingType(scalingType);
- remoteRender.setMirror(false);
+ remoteRenderScreen.setScalingType(scalingType);
+ remoteRenderScreen.setMirror(false);
if (iceConnected) {
localRenderLayout.setPosition(
@@ -408,7 +488,7 @@ public class CallActivity extends Activity
localRender.setMirror(true);
localRender.requestLayout();
- remoteRender.requestLayout();
+ remoteRenderScreen.requestLayout();
}
private void startCall() {
@@ -474,9 +554,13 @@ public class CallActivity extends Activity
localRender.release();
localRender = null;
}
- if (remoteRender != null) {
- remoteRender.release();
- remoteRender = null;
+ if (videoFileRenderer != null) {
+ videoFileRenderer.release();
+ videoFileRenderer = null;
+ }
+ if (remoteRenderScreen != null) {
+ remoteRenderScreen.release();
+ remoteRenderScreen = null;
}
if (audioManager != null) {
audioManager.close();
@@ -531,6 +615,36 @@ public class CallActivity extends Activity
});
}
+ private VideoCapturer createVideoCapturer() {
+ VideoCapturer videoCapturer = null;
+ String videoFileAsCamera = getIntent().getStringExtra(EXTRA_VIDEO_FILE_AS_CAMERA);
+ if (videoFileAsCamera != null) {
+ videoCapturer = FileVideoCapturer.create(
+ videoFileAsCamera);
+
+ if (videoCapturer == null) {
+ reportError("Failed to open video file for emulated camera");
+ return null;
+ }
+ } else if (useCamera2()) {
+ if (!captureToTexture()) {
+ reportError(getString(R.string.camera2_texture_only_error));
+ return null;
+ }
+
+ Logging.d(TAG, "Creating capturer using camera2 API.");
+ videoCapturer = createCapturer(new Camera2Enumerator(this));
+ } else {
+ Logging.d(TAG, "Creating capturer using camera1 API.");
+ videoCapturer = createCapturer(new Camera1Enumerator(captureToTexture()));
+ }
+ if (videoCapturer == null) {
+ reportError("Failed to open camera");
+ return null;
+ }
+ return videoCapturer;
+ }
+
// -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
// All callbacks are invoked from websocket signaling looper thread and
// are routed to UI thread.
@@ -539,8 +653,12 @@ public class CallActivity extends Activity
signalingParameters = params;
logAndToast("Creating peer connection, delay=" + delta + "ms");
+ VideoCapturer videoCapturer = null;
+ if (peerConnectionParameters.videoCallEnabled) {
+ videoCapturer = createVideoCapturer();
+ }
peerConnectionClient.createPeerConnection(rootEglBase.getEglBaseContext(),
- localRender, remoteRender, signalingParameters);
+ localRender, remoteRenders, videoCapturer, signalingParameters);
if (signalingParameters.initiator) {
logAndToast("Creating OFFER...");

Powered by Google App Engine
This is Rietveld 408576698