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) { |