| 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 309a5be0da757a997ee2839df03e7080bf081218..0197bcb3227dbc0fa0f290ab334199a4efa243ca 100644
|
| --- a/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
|
| +++ b/webrtc/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
|
| @@ -134,34 +134,37 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
|
|
| // Peer connection statistics callback period in ms.
|
| private static final int STAT_CALLBACK_PERIOD = 1000;
|
| - // Local preview screen position before call is connected.
|
| - private static final int LOCAL_X_CONNECTING = 0;
|
| - private static final int LOCAL_Y_CONNECTING = 0;
|
| - private static final int LOCAL_WIDTH_CONNECTING = 100;
|
| - private static final int LOCAL_HEIGHT_CONNECTING = 100;
|
| - // Local preview screen position after call is connected.
|
| - private static final int LOCAL_X_CONNECTED = 72;
|
| - private static final int LOCAL_Y_CONNECTED = 72;
|
| - private static final int LOCAL_WIDTH_CONNECTED = 25;
|
| - private static final int LOCAL_HEIGHT_CONNECTED = 25;
|
| - // Remote video screen position
|
| - private static final int REMOTE_X = 0;
|
| - private static final int REMOTE_Y = 0;
|
| - private static final int REMOTE_WIDTH = 100;
|
| - private static final int REMOTE_HEIGHT = 100;
|
| +
|
| + private class ProxyRenderer implements VideoRenderer.Callbacks {
|
| + private VideoRenderer.Callbacks target;
|
| +
|
| + synchronized public void renderFrame(VideoRenderer.I420Frame frame) {
|
| + if (target == null) {
|
| + Logging.d(TAG, "Dropping frame in proxy because target is null.");
|
| + VideoRenderer.renderFrameDone(frame);
|
| + return;
|
| + }
|
| +
|
| + target.renderFrame(frame);
|
| + }
|
| +
|
| + synchronized public void setTarget(VideoRenderer.Callbacks target) {
|
| + this.target = target;
|
| + }
|
| + }
|
| +
|
| + private final ProxyRenderer remoteProxyRenderer = new ProxyRenderer();
|
| + private final ProxyRenderer localProxyRenderer = new ProxyRenderer();
|
| private PeerConnectionClient peerConnectionClient = null;
|
| private AppRTCClient appRtcClient;
|
| private SignalingParameters signalingParameters;
|
| private AppRTCAudioManager audioManager = null;
|
| private EglBase rootEglBase;
|
| - private SurfaceViewRenderer localRender;
|
| - private SurfaceViewRenderer remoteRenderScreen;
|
| + private SurfaceViewRenderer pipRenderer;
|
| + private SurfaceViewRenderer fullscreenRenderer;
|
| private VideoFileRenderer videoFileRenderer;
|
| private final List<VideoRenderer.Callbacks> remoteRenderers =
|
| new ArrayList<VideoRenderer.Callbacks>();
|
| - private PercentFrameLayout localRenderLayout;
|
| - private PercentFrameLayout remoteRenderLayout;
|
| - private ScalingType scalingType;
|
| private Toast logToast;
|
| private boolean commandLineRun;
|
| private int runTimeMs;
|
| @@ -176,6 +179,8 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| private boolean screencaptureEnabled = false;
|
| private static Intent mediaProjectionPermissionResultData;
|
| private static int mediaProjectionPermissionResultCode;
|
| + // True if local view is in the fullscreen renderer.
|
| + private boolean isSwappedFeeds;
|
|
|
| // Controls
|
| private CallFragment callFragment;
|
| @@ -198,13 +203,10 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
|
|
| iceConnected = false;
|
| signalingParameters = null;
|
| - scalingType = ScalingType.SCALE_ASPECT_FILL;
|
|
|
| // Create UI controls.
|
| - localRender = (SurfaceViewRenderer) findViewById(R.id.local_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);
|
| + pipRenderer = (SurfaceViewRenderer) findViewById(R.id.pip_video_view);
|
| + fullscreenRenderer = (SurfaceViewRenderer) findViewById(R.id.fullscreen_video_view);
|
| callFragment = new CallFragment();
|
| hudFragment = new HudFragment();
|
|
|
| @@ -216,15 +218,23 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| }
|
| };
|
|
|
| - localRender.setOnClickListener(listener);
|
| - remoteRenderScreen.setOnClickListener(listener);
|
| - remoteRenderers.add(remoteRenderScreen);
|
| + // Swap feeds on pip view click.
|
| + pipRenderer.setOnClickListener(new View.OnClickListener() {
|
| + @Override
|
| + public void onClick(View view) {
|
| + setSwappedFeeds(!isSwappedFeeds);
|
| + }
|
| + });
|
| +
|
| + fullscreenRenderer.setOnClickListener(listener);
|
| + remoteRenderers.add(remoteProxyRenderer);
|
|
|
| final Intent intent = getIntent();
|
|
|
| // Create video renderers.
|
| rootEglBase = EglBase.create();
|
| - localRender.init(rootEglBase.getEglBaseContext(), null);
|
| + pipRenderer.init(rootEglBase.getEglBaseContext(), null);
|
| + pipRenderer.setScalingType(ScalingType.SCALE_ASPECT_FIT);
|
| String saveRemoteVideoToFile = intent.getStringExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE);
|
|
|
| // When saveRemoteVideoToFile is set we save the video from the remote to a file.
|
| @@ -240,12 +250,14 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| "Failed to open video file for output: " + saveRemoteVideoToFile, e);
|
| }
|
| }
|
| - remoteRenderScreen.init(rootEglBase.getEglBaseContext(), null);
|
| + fullscreenRenderer.init(rootEglBase.getEglBaseContext(), null);
|
| + fullscreenRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL);
|
|
|
| - localRender.setZOrderMediaOverlay(true);
|
| - localRender.setEnableHardwareScaler(true /* enabled */);
|
| - remoteRenderScreen.setEnableHardwareScaler(true /* enabled */);
|
| - updateVideoView();
|
| + pipRenderer.setZOrderMediaOverlay(true);
|
| + pipRenderer.setEnableHardwareScaler(true /* enabled */);
|
| + fullscreenRenderer.setEnableHardwareScaler(true /* enabled */);
|
| + // Start with local feed in fullscreen and swap it to the pip when the call is connected.
|
| + setSwappedFeeds(true /* isSwappedFeeds */);
|
|
|
| // Check for mandatory permissions.
|
| for (String permission : MANDATORY_PERMISSIONS) {
|
| @@ -508,8 +520,7 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
|
|
| @Override
|
| public void onVideoScalingSwitch(ScalingType scalingType) {
|
| - this.scalingType = scalingType;
|
| - updateVideoView();
|
| + fullscreenRenderer.setScalingType(scalingType);
|
| }
|
|
|
| @Override
|
| @@ -547,26 +558,6 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| ft.commit();
|
| }
|
|
|
| - private void updateVideoView() {
|
| - remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT);
|
| - remoteRenderScreen.setScalingType(scalingType);
|
| - remoteRenderScreen.setMirror(false);
|
| -
|
| - if (iceConnected) {
|
| - localRenderLayout.setPosition(
|
| - LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED);
|
| - localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT);
|
| - } else {
|
| - localRenderLayout.setPosition(
|
| - LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING);
|
| - localRender.setScalingType(scalingType);
|
| - }
|
| - localRender.setMirror(true);
|
| -
|
| - localRender.requestLayout();
|
| - remoteRenderScreen.requestLayout();
|
| - }
|
| -
|
| private void startCall() {
|
| if (appRtcClient == null) {
|
| Log.e(TAG, "AppRTC client is not allocated for a call.");
|
| @@ -603,10 +594,9 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| Log.w(TAG, "Call is connected in closed or error state");
|
| return;
|
| }
|
| - // Update video view.
|
| - updateVideoView();
|
| // Enable statistics callback.
|
| peerConnectionClient.enableStatsEvents(true, STAT_CALLBACK_PERIOD);
|
| + setSwappedFeeds(false /* isSwappedFeeds */);
|
| }
|
|
|
| // This method is called when the audio manager reports audio device change,
|
| @@ -621,6 +611,8 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| // Disconnect from remote resources, dispose of local resources, and exit.
|
| private void disconnect() {
|
| activityRunning = false;
|
| + remoteProxyRenderer.setTarget(null);
|
| + localProxyRenderer.setTarget(null);
|
| if (appRtcClient != null) {
|
| appRtcClient.disconnectFromRoom();
|
| appRtcClient = null;
|
| @@ -629,17 +621,17 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| peerConnectionClient.close();
|
| peerConnectionClient = null;
|
| }
|
| - if (localRender != null) {
|
| - localRender.release();
|
| - localRender = null;
|
| + if (pipRenderer != null) {
|
| + pipRenderer.release();
|
| + pipRenderer = null;
|
| }
|
| if (videoFileRenderer != null) {
|
| videoFileRenderer.release();
|
| videoFileRenderer = null;
|
| }
|
| - if (remoteRenderScreen != null) {
|
| - remoteRenderScreen.release();
|
| - remoteRenderScreen = null;
|
| + if (fullscreenRenderer != null) {
|
| + fullscreenRenderer.release();
|
| + fullscreenRenderer = null;
|
| }
|
| if (audioManager != null) {
|
| audioManager.stop();
|
| @@ -728,6 +720,15 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| return videoCapturer;
|
| }
|
|
|
| + private void setSwappedFeeds(boolean isSwappedFeeds) {
|
| + Logging.d(TAG, "setSwappedFeeds: " + isSwappedFeeds);
|
| + this.isSwappedFeeds = isSwappedFeeds;
|
| + localProxyRenderer.setTarget(isSwappedFeeds ? fullscreenRenderer : pipRenderer);
|
| + remoteProxyRenderer.setTarget(isSwappedFeeds ? pipRenderer : fullscreenRenderer);
|
| + fullscreenRenderer.setMirror(isSwappedFeeds);
|
| + pipRenderer.setMirror(!isSwappedFeeds);
|
| + }
|
| +
|
| // -----Implementation of AppRTCClient.AppRTCSignalingEvents ---------------
|
| // All callbacks are invoked from websocket signaling looper thread and
|
| // are routed to UI thread.
|
| @@ -740,7 +741,7 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
|
| if (peerConnectionParameters.videoCallEnabled) {
|
| videoCapturer = createVideoCapturer();
|
| }
|
| - peerConnectionClient.createPeerConnection(rootEglBase.getEglBaseContext(), localRender,
|
| + peerConnectionClient.createPeerConnection(rootEglBase.getEglBaseContext(), localProxyRenderer,
|
| remoteRenderers, videoCapturer, signalingParameters);
|
|
|
| if (signalingParameters.initiator) {
|
|
|