Chromium Code Reviews| 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..0cb82d489e6bb99ded4f33d1507393fd5a5b6125 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,12 +179,14 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven |
| private boolean screencaptureEnabled = false; |
| private static Intent mediaProjectionPermissionResultData; |
| private static int mediaProjectionPermissionResultCode; |
| + private boolean isSwappedFeeds; |
|
magjed_webrtc
2017/02/10 13:23:38
Can you comment what it means when this is true vs
sakal
2017/02/10 14:05:36
Done.
|
| // Controls |
| private CallFragment callFragment; |
| private HudFragment hudFragment; |
| private CpuMonitor cpuMonitor; |
| + |
|
magjed_webrtc
2017/02/10 13:23:38
nit: remove unnecessary empty line
sakal
2017/02/10 14:05:36
Done.
|
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| @@ -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,13 @@ 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 */); |
| + setSwappedFeeds(true /* isSwappedFeeds */); |
|
magjed_webrtc
2017/02/10 13:23:38
Add a comment why we start with local in fullscree
sakal
2017/02/10 14:05:36
Done.
|
| // Check for mandatory permissions. |
| for (String permission : MANDATORY_PERMISSIONS) { |
| @@ -508,8 +519,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 +557,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 +593,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 +610,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 +620,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 +719,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 +740,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) { |