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

Side by Side Diff: talk/examples/android/src/org/appspot/apprtc/CallActivity.java

Issue 1257043004: AppRTCDemo: Render each video in a separate SurfaceView (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 4 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 * libjingle 2 * libjingle
3 * Copyright 2015 Google Inc. 3 * Copyright 2015 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 29 matching lines...) Expand all
40 import android.content.pm.PackageManager; 40 import android.content.pm.PackageManager;
41 import android.net.Uri; 41 import android.net.Uri;
42 import android.opengl.GLSurfaceView; 42 import android.opengl.GLSurfaceView;
43 import android.os.Bundle; 43 import android.os.Bundle;
44 import android.util.Log; 44 import android.util.Log;
45 import android.view.View; 45 import android.view.View;
46 import android.view.Window; 46 import android.view.Window;
47 import android.view.WindowManager.LayoutParams; 47 import android.view.WindowManager.LayoutParams;
48 import android.widget.Toast; 48 import android.widget.Toast;
49 49
50 import org.webrtc.EglBase;
50 import org.webrtc.IceCandidate; 51 import org.webrtc.IceCandidate;
51 import org.webrtc.SessionDescription; 52 import org.webrtc.SessionDescription;
52 import org.webrtc.StatsReport; 53 import org.webrtc.StatsReport;
53 import org.webrtc.VideoRenderer; 54 import org.webrtc.SurfaceViewRenderer;
54 import org.webrtc.VideoRendererGui;
55 import org.webrtc.VideoRendererGui.ScalingType; 55 import org.webrtc.VideoRendererGui.ScalingType;
56 56
57 /** 57 /**
58 * Activity for peer connection call setup, call waiting 58 * Activity for peer connection call setup, call waiting
59 * and call view. 59 * and call view.
60 */ 60 */
61 public class CallActivity extends Activity 61 public class CallActivity extends Activity
62 implements AppRTCClient.SignalingEvents, 62 implements AppRTCClient.SignalingEvents,
63 PeerConnectionClient.PeerConnectionEvents, 63 PeerConnectionClient.PeerConnectionEvents,
64 CallFragment.OnCallEvents { 64 CallFragment.OnCallEvents {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 // Remote video screen position 119 // Remote video screen position
120 private static final int REMOTE_X = 0; 120 private static final int REMOTE_X = 0;
121 private static final int REMOTE_Y = 0; 121 private static final int REMOTE_Y = 0;
122 private static final int REMOTE_WIDTH = 100; 122 private static final int REMOTE_WIDTH = 100;
123 private static final int REMOTE_HEIGHT = 100; 123 private static final int REMOTE_HEIGHT = 100;
124 124
125 private PeerConnectionClient peerConnectionClient = null; 125 private PeerConnectionClient peerConnectionClient = null;
126 private AppRTCClient appRtcClient; 126 private AppRTCClient appRtcClient;
127 private SignalingParameters signalingParameters; 127 private SignalingParameters signalingParameters;
128 private AppRTCAudioManager audioManager = null; 128 private AppRTCAudioManager audioManager = null;
129 private VideoRenderer.Callbacks localRender; 129 private EglBase rootEglBase;
130 private VideoRenderer.Callbacks remoteRender; 130 private SurfaceViewRenderer localRender;
131 private SurfaceViewRenderer remoteRender;
132 private PercentFrameLayout localRenderLayout;
133 private PercentFrameLayout remoteRenderLayout;
131 private ScalingType scalingType; 134 private ScalingType scalingType;
132 private Toast logToast; 135 private Toast logToast;
133 private boolean commandLineRun; 136 private boolean commandLineRun;
134 private int runTimeMs; 137 private int runTimeMs;
135 private boolean activityRunning; 138 private boolean activityRunning;
136 private RoomConnectionParameters roomConnectionParameters; 139 private RoomConnectionParameters roomConnectionParameters;
137 private PeerConnectionParameters peerConnectionParameters; 140 private PeerConnectionParameters peerConnectionParameters;
138 private boolean iceConnected; 141 private boolean iceConnected;
139 private boolean isError; 142 private boolean isError;
140 private boolean callControlFragmentVisible = true; 143 private boolean callControlFragmentVisible = true;
141 private long callStartedTimeMs = 0; 144 private long callStartedTimeMs = 0;
142 145
143 // Controls 146 // Controls
144 private GLSurfaceView videoView;
145 CallFragment callFragment; 147 CallFragment callFragment;
146 HudFragment hudFragment; 148 HudFragment hudFragment;
147 149
148 @Override 150 @Override
149 public void onCreate(Bundle savedInstanceState) { 151 public void onCreate(Bundle savedInstanceState) {
150 super.onCreate(savedInstanceState); 152 super.onCreate(savedInstanceState);
151 Thread.setDefaultUncaughtExceptionHandler( 153 Thread.setDefaultUncaughtExceptionHandler(
152 new UnhandledExceptionHandler(this)); 154 new UnhandledExceptionHandler(this));
153 155
154 // Set window styles for fullscreen-window size. Needs to be done before 156 // Set window styles for fullscreen-window size. Needs to be done before
155 // adding content. 157 // adding content.
156 requestWindowFeature(Window.FEATURE_NO_TITLE); 158 requestWindowFeature(Window.FEATURE_NO_TITLE);
157 getWindow().addFlags( 159 getWindow().addFlags(
158 LayoutParams.FLAG_FULLSCREEN 160 LayoutParams.FLAG_FULLSCREEN
159 | LayoutParams.FLAG_KEEP_SCREEN_ON 161 | LayoutParams.FLAG_KEEP_SCREEN_ON
160 | LayoutParams.FLAG_DISMISS_KEYGUARD 162 | LayoutParams.FLAG_DISMISS_KEYGUARD
161 | LayoutParams.FLAG_SHOW_WHEN_LOCKED 163 | LayoutParams.FLAG_SHOW_WHEN_LOCKED
162 | LayoutParams.FLAG_TURN_SCREEN_ON); 164 | LayoutParams.FLAG_TURN_SCREEN_ON);
163 getWindow().getDecorView().setSystemUiVisibility( 165 getWindow().getDecorView().setSystemUiVisibility(
164 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 166 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
165 | View.SYSTEM_UI_FLAG_FULLSCREEN 167 | View.SYSTEM_UI_FLAG_FULLSCREEN
166 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); 168 | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
167 setContentView(R.layout.activity_call); 169 setContentView(R.layout.activity_call);
168 170
169 iceConnected = false; 171 iceConnected = false;
170 signalingParameters = null; 172 signalingParameters = null;
171 scalingType = ScalingType.SCALE_ASPECT_FILL; 173 scalingType = ScalingType.SCALE_ASPECT_FILL;
172 174
173 // Create UI controls. 175 // Create UI controls.
174 videoView = (GLSurfaceView) findViewById(R.id.glview_call); 176 localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view);
177 remoteRender = (SurfaceViewRenderer) findViewById(R.id.remote_video_view);
178 localRenderLayout = (PercentFrameLayout) findViewById(R.id.local_video_layou t);
179 remoteRenderLayout = (PercentFrameLayout) findViewById(R.id.remote_video_lay out);
175 callFragment = new CallFragment(); 180 callFragment = new CallFragment();
176 hudFragment = new HudFragment(); 181 hudFragment = new HudFragment();
177 182
178 // Create video renderers.
179 VideoRendererGui.setView(videoView, new Runnable() {
180 @Override
181 public void run() {
182 createPeerConnectionFactory();
183 }
184 });
185 remoteRender = VideoRendererGui.create(
186 REMOTE_X, REMOTE_Y,
187 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
188 localRender = VideoRendererGui.create(
189 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
190 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
191
192 // Show/hide call control fragment on view click. 183 // Show/hide call control fragment on view click.
193 videoView.setOnClickListener(new View.OnClickListener() { 184 View.OnClickListener listener = new View.OnClickListener() {
194 @Override 185 @Override
195 public void onClick(View view) { 186 public void onClick(View view) {
196 toggleCallControlFragmentVisibility(); 187 toggleCallControlFragmentVisibility();
197 } 188 }
198 }); 189 };
190 localRender.setOnClickListener(listener);
191 remoteRender.setOnClickListener(listener);
192
193 // Create video renderers.
194 rootEglBase = new EglBase();
195 localRender.init(rootEglBase.getContext());
196 remoteRender.init(rootEglBase.getContext());
197 localRender.setZOrderMediaOverlay(true);
198 updateVideoView();
199 199
200 // Check for mandatory permissions. 200 // Check for mandatory permissions.
201 for (String permission : MANDATORY_PERMISSIONS) { 201 for (String permission : MANDATORY_PERMISSIONS) {
202 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_ GRANTED) { 202 if (checkCallingOrSelfPermission(permission) != PackageManager.PERMISSION_ GRANTED) {
203 logAndToast("Permission " + permission + " is not granted"); 203 logAndToast("Permission " + permission + " is not granted");
204 setResult(RESULT_CANCELED); 204 setResult(RESULT_CANCELED);
205 finish(); 205 finish();
206 return; 206 return;
207 } 207 }
208 } 208 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 hudFragment.setArguments(intent.getExtras()); 252 hudFragment.setArguments(intent.getExtras());
253 // Activate call and HUD fragments and start the call. 253 // Activate call and HUD fragments and start the call.
254 FragmentTransaction ft = getFragmentManager().beginTransaction(); 254 FragmentTransaction ft = getFragmentManager().beginTransaction();
255 ft.add(R.id.call_fragment_container, callFragment); 255 ft.add(R.id.call_fragment_container, callFragment);
256 ft.add(R.id.hud_fragment_container, hudFragment); 256 ft.add(R.id.hud_fragment_container, hudFragment);
257 ft.commit(); 257 ft.commit();
258 startCall(); 258 startCall();
259 259
260 // For command line execution run connection for <runTimeMs> and exit. 260 // For command line execution run connection for <runTimeMs> and exit.
261 if (commandLineRun && runTimeMs > 0) { 261 if (commandLineRun && runTimeMs > 0) {
262 videoView.postDelayed(new Runnable() { 262 localRender.postDelayed(new Runnable() {
AlexG 2015/08/04 00:27:23 nit: this was probably not the best way from the b
magjed_webrtc 2015/08/04 17:05:05 Done.
263 public void run() { 263 public void run() {
264 disconnect(); 264 disconnect();
265 } 265 }
266 }, runTimeMs); 266 }, runTimeMs);
267 } 267 }
268 createPeerConnectionFactory();
268 } 269 }
269 270
270 // Activity interfaces 271 // Activity interfaces
271 @Override 272 @Override
272 public void onPause() { 273 public void onPause() {
273 super.onPause(); 274 super.onPause();
274 videoView.onPause();
275 activityRunning = false; 275 activityRunning = false;
276 if (peerConnectionClient != null) { 276 if (peerConnectionClient != null) {
277 peerConnectionClient.stopVideoSource(); 277 peerConnectionClient.stopVideoSource();
278 } 278 }
279 } 279 }
280 280
281 @Override 281 @Override
282 public void onResume() { 282 public void onResume() {
283 super.onResume(); 283 super.onResume();
284 videoView.onResume();
285 activityRunning = true; 284 activityRunning = true;
286 if (peerConnectionClient != null) { 285 if (peerConnectionClient != null) {
287 peerConnectionClient.startVideoSource(); 286 peerConnectionClient.startVideoSource();
288 } 287 }
289 } 288 }
290 289
291 @Override 290 @Override
292 protected void onDestroy() { 291 protected void onDestroy() {
293 disconnect(); 292 disconnect();
294 super.onDestroy(); 293 super.onDestroy();
295 if (logToast != null) { 294 if (logToast != null) {
296 logToast.cancel(); 295 logToast.cancel();
297 } 296 }
298 activityRunning = false; 297 activityRunning = false;
298 localRender.release();
299 localRender = null;
300 remoteRender.release();
301 remoteRender = null;
302 rootEglBase.release();
303 rootEglBase = null;
299 } 304 }
300 305
301 // CallFragment.OnCallEvents interface implementation. 306 // CallFragment.OnCallEvents interface implementation.
302 @Override 307 @Override
303 public void onCallHangUp() { 308 public void onCallHangUp() {
304 disconnect(); 309 disconnect();
305 } 310 }
306 311
307 @Override 312 @Override
308 public void onCameraSwitch() { 313 public void onCameraSwitch() {
(...skipping 21 matching lines...) Expand all
330 ft.show(hudFragment); 335 ft.show(hudFragment);
331 } else { 336 } else {
332 ft.hide(callFragment); 337 ft.hide(callFragment);
333 ft.hide(hudFragment); 338 ft.hide(hudFragment);
334 } 339 }
335 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 340 ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
336 ft.commit(); 341 ft.commit();
337 } 342 }
338 343
339 private void updateVideoView() { 344 private void updateVideoView() {
340 VideoRendererGui.update(remoteRender, 345 remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIG HT);
AlexG 2015/08/04 00:27:23 Could it cause race condition when say position is
magjed_webrtc 2015/08/04 17:05:05 There is no race between setPosition() and setScal
341 REMOTE_X, REMOTE_Y, 346 remoteRender.setScalingType(scalingType);
342 REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false); 347 remoteRender.setMirror(false);
348
343 if (iceConnected) { 349 if (iceConnected) {
344 VideoRendererGui.update(localRender, 350 localRenderLayout.setPosition(
345 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, 351 LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEI GHT_CONNECTED);
346 LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED, 352 localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT);
347 ScalingType.SCALE_ASPECT_FIT, true);
348 } else { 353 } else {
349 VideoRendererGui.update(localRender, 354 localRenderLayout.setPosition(
350 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, 355 LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_ HEIGHT_CONNECTING);
351 LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true); 356 localRender.setScalingType(scalingType);
352 } 357 }
358 localRender.setMirror(true);
359
360 localRender.requestLayout();
361 remoteRender.requestLayout();
353 } 362 }
354 363
355 private void startCall() { 364 private void startCall() {
356 if (appRtcClient == null) { 365 if (appRtcClient == null) {
357 Log.e(TAG, "AppRTC client is not allocated for a call."); 366 Log.e(TAG, "AppRTC client is not allocated for a call.");
358 return; 367 return;
359 } 368 }
360 callStartedTimeMs = System.currentTimeMillis(); 369 callStartedTimeMs = System.currentTimeMillis();
361 370
362 // Start room connection. 371 // Start room connection.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // Create peer connection factory when EGL context is ready. 409 // Create peer connection factory when EGL context is ready.
401 private void createPeerConnectionFactory() { 410 private void createPeerConnectionFactory() {
402 runOnUiThread(new Runnable() { 411 runOnUiThread(new Runnable() {
403 @Override 412 @Override
404 public void run() { 413 public void run() {
405 if (peerConnectionClient == null) { 414 if (peerConnectionClient == null) {
406 final long delta = System.currentTimeMillis() - callStartedTimeMs; 415 final long delta = System.currentTimeMillis() - callStartedTimeMs;
407 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms"); 416 Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms");
408 peerConnectionClient = PeerConnectionClient.getInstance(); 417 peerConnectionClient = PeerConnectionClient.getInstance();
409 peerConnectionClient.createPeerConnectionFactory(CallActivity.this, 418 peerConnectionClient.createPeerConnectionFactory(CallActivity.this,
410 VideoRendererGui.getEGLContext(), peerConnectionParameters, 419 rootEglBase.getContext(), peerConnectionParameters,
411 CallActivity.this); 420 CallActivity.this);
412 } 421 }
413 if (signalingParameters != null) { 422 if (signalingParameters != null) {
414 Log.w(TAG, "EGL context is ready after room connection."); 423 Log.w(TAG, "EGL context is ready after room connection.");
415 onConnectedToRoomInternal(signalingParameters); 424 onConnectedToRoomInternal(signalingParameters);
416 } 425 }
417 } 426 }
418 }); 427 });
419 } 428 }
420 429
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 } 664 }
656 } 665 }
657 }); 666 });
658 } 667 }
659 668
660 @Override 669 @Override
661 public void onPeerConnectionError(final String description) { 670 public void onPeerConnectionError(final String description) {
662 reportError(description); 671 reportError(description);
663 } 672 }
664 } 673 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698