Revert of AppRTCDemo: Render each video in a separate SurfaceView (patchset #4 id:120001 of https://codereview.webrtc.org/1257043004/ )
Reason for revert: AppRTCDemo often crashes in loopback mode and incorrect layout when connection is established BUG=webrtc:4909,webrtc:4910 Original issue's description: > AppRTCDemo: Render each video in a separate SurfaceView > > This CL introduces a new org.webrtc.VideoRenderer.Callbacks implementation called SurfaceViewRenderer that renders each video stream in its own SurfaceView. AppRTCDemo is updated to use this new rendering. > > This CL also does the following changes: > * Make the VideoRenderer.Callbacks interface asynchronous and require that renderFrameDone() is called for every renderFrame(). In JNI, this is implemented with cricket::VideoFrame::Copy()/delete. > * Make public static helper functions: convertScalingTypeToVisibleFraction(), getDisplaySize(), and getTextureMatrix(). > * Introduces new helper functions surfaceWidth()/surfaceHeight() in EGlBase that allows to query the surface size. > * Introduce PercentFrameLayout that implements the percentage layout that is used by AppRTCDemo. > > BUG=webrtc:4742 > > Committed: https://crrev.com/05bfbe47ef6bcc9ca731c0fa0d5cd15a4f21e93f > Cr-Commit-Position: refs/heads/master@{#9699} TBR=glaznev@webrtc.org,wzh@webrtc.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=webrtc:4742 Review URL: https://codereview.webrtc.org/1286133002 Cr-Commit-Position: refs/heads/master@{#9703}
This commit is contained in:
@ -24,19 +24,18 @@ import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.webrtc.EglBase;
|
||||
import org.webrtc.IceCandidate;
|
||||
import org.webrtc.SessionDescription;
|
||||
import org.webrtc.StatsReport;
|
||||
import org.webrtc.SurfaceViewRenderer;
|
||||
import org.webrtc.RendererCommon.ScalingType;
|
||||
import org.webrtc.VideoRenderer;
|
||||
import org.webrtc.VideoRendererGui;
|
||||
import org.webrtc.VideoRendererGui.ScalingType;
|
||||
|
||||
/**
|
||||
* Activity for peer connection call setup, call waiting
|
||||
@ -110,11 +109,8 @@ public class CallActivity extends Activity
|
||||
private AppRTCClient appRtcClient;
|
||||
private SignalingParameters signalingParameters;
|
||||
private AppRTCAudioManager audioManager = null;
|
||||
private EglBase rootEglBase;
|
||||
private SurfaceViewRenderer localRender;
|
||||
private SurfaceViewRenderer remoteRender;
|
||||
private PercentFrameLayout localRenderLayout;
|
||||
private PercentFrameLayout remoteRenderLayout;
|
||||
private VideoRenderer.Callbacks localRender;
|
||||
private VideoRenderer.Callbacks remoteRender;
|
||||
private ScalingType scalingType;
|
||||
private Toast logToast;
|
||||
private boolean commandLineRun;
|
||||
@ -128,6 +124,7 @@ public class CallActivity extends Activity
|
||||
private long callStartedTimeMs = 0;
|
||||
|
||||
// Controls
|
||||
private GLSurfaceView videoView;
|
||||
CallFragment callFragment;
|
||||
HudFragment hudFragment;
|
||||
|
||||
@ -157,29 +154,31 @@ public class CallActivity extends Activity
|
||||
scalingType = ScalingType.SCALE_ASPECT_FILL;
|
||||
|
||||
// Create UI controls.
|
||||
localRender = (SurfaceViewRenderer) findViewById(R.id.local_video_view);
|
||||
remoteRender = (SurfaceViewRenderer) findViewById(R.id.remote_video_view);
|
||||
localRenderLayout = (PercentFrameLayout) findViewById(R.id.local_video_layout);
|
||||
remoteRenderLayout = (PercentFrameLayout) findViewById(R.id.remote_video_layout);
|
||||
videoView = (GLSurfaceView) findViewById(R.id.glview_call);
|
||||
callFragment = new CallFragment();
|
||||
hudFragment = new HudFragment();
|
||||
|
||||
// Create video renderers.
|
||||
VideoRendererGui.setView(videoView, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createPeerConnectionFactory();
|
||||
}
|
||||
});
|
||||
remoteRender = VideoRendererGui.create(
|
||||
REMOTE_X, REMOTE_Y,
|
||||
REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
|
||||
localRender = VideoRendererGui.create(
|
||||
LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
|
||||
LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
|
||||
|
||||
// Show/hide call control fragment on view click.
|
||||
View.OnClickListener listener = new View.OnClickListener() {
|
||||
videoView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
toggleCallControlFragmentVisibility();
|
||||
}
|
||||
};
|
||||
localRender.setOnClickListener(listener);
|
||||
remoteRender.setOnClickListener(listener);
|
||||
|
||||
// Create video renderers.
|
||||
rootEglBase = new EglBase();
|
||||
localRender.init(rootEglBase.getContext());
|
||||
remoteRender.init(rootEglBase.getContext());
|
||||
localRender.setZOrderMediaOverlay(true);
|
||||
updateVideoView();
|
||||
});
|
||||
|
||||
// Check for mandatory permissions.
|
||||
for (String permission : MANDATORY_PERMISSIONS) {
|
||||
@ -243,19 +242,19 @@ public class CallActivity extends Activity
|
||||
|
||||
// For command line execution run connection for <runTimeMs> and exit.
|
||||
if (commandLineRun && runTimeMs > 0) {
|
||||
(new Handler()).postDelayed(new Runnable() {
|
||||
videoView.postDelayed(new Runnable() {
|
||||
public void run() {
|
||||
disconnect();
|
||||
}
|
||||
}, runTimeMs);
|
||||
}
|
||||
createPeerConnectionFactory();
|
||||
}
|
||||
|
||||
// Activity interfaces
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
videoView.onPause();
|
||||
activityRunning = false;
|
||||
if (peerConnectionClient != null) {
|
||||
peerConnectionClient.stopVideoSource();
|
||||
@ -265,6 +264,7 @@ public class CallActivity extends Activity
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
videoView.onResume();
|
||||
activityRunning = true;
|
||||
if (peerConnectionClient != null) {
|
||||
peerConnectionClient.startVideoSource();
|
||||
@ -279,12 +279,6 @@ public class CallActivity extends Activity
|
||||
logToast.cancel();
|
||||
}
|
||||
activityRunning = false;
|
||||
localRender.release();
|
||||
localRender = null;
|
||||
remoteRender.release();
|
||||
remoteRender = null;
|
||||
rootEglBase.release();
|
||||
rootEglBase = null;
|
||||
}
|
||||
|
||||
// CallFragment.OnCallEvents interface implementation.
|
||||
@ -326,23 +320,19 @@ public class CallActivity extends Activity
|
||||
}
|
||||
|
||||
private void updateVideoView() {
|
||||
remoteRenderLayout.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT);
|
||||
remoteRender.setScalingType(scalingType);
|
||||
remoteRender.setMirror(false);
|
||||
|
||||
VideoRendererGui.update(remoteRender,
|
||||
REMOTE_X, REMOTE_Y,
|
||||
REMOTE_WIDTH, REMOTE_HEIGHT, scalingType, false);
|
||||
if (iceConnected) {
|
||||
localRenderLayout.setPosition(
|
||||
LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED, LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED);
|
||||
localRender.setScalingType(ScalingType.SCALE_ASPECT_FIT);
|
||||
VideoRendererGui.update(localRender,
|
||||
LOCAL_X_CONNECTED, LOCAL_Y_CONNECTED,
|
||||
LOCAL_WIDTH_CONNECTED, LOCAL_HEIGHT_CONNECTED,
|
||||
ScalingType.SCALE_ASPECT_FIT, true);
|
||||
} else {
|
||||
localRenderLayout.setPosition(
|
||||
LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING, LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING);
|
||||
localRender.setScalingType(scalingType);
|
||||
VideoRendererGui.update(localRender,
|
||||
LOCAL_X_CONNECTING, LOCAL_Y_CONNECTING,
|
||||
LOCAL_WIDTH_CONNECTING, LOCAL_HEIGHT_CONNECTING, scalingType, true);
|
||||
}
|
||||
localRender.setMirror(true);
|
||||
|
||||
localRender.requestLayout();
|
||||
remoteRender.requestLayout();
|
||||
}
|
||||
|
||||
private void startCall() {
|
||||
@ -400,7 +390,7 @@ public class CallActivity extends Activity
|
||||
Log.d(TAG, "Creating peer connection factory, delay=" + delta + "ms");
|
||||
peerConnectionClient = PeerConnectionClient.getInstance();
|
||||
peerConnectionClient.createPeerConnectionFactory(CallActivity.this,
|
||||
rootEglBase.getContext(), peerConnectionParameters,
|
||||
VideoRendererGui.getEGLContext(), peerConnectionParameters,
|
||||
CallActivity.this);
|
||||
}
|
||||
if (signalingParameters != null) {
|
||||
|
||||
@ -19,7 +19,7 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.webrtc.RendererCommon.ScalingType;
|
||||
import org.webrtc.VideoRendererGui.ScalingType;
|
||||
|
||||
/**
|
||||
* Fragment for call control.
|
||||
|
||||
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
package org.appspot.apprtc;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Simple container that confines the children to a subrectangle specified as percentage values of
|
||||
* the container size. The children are centered horizontally and vertically inside the confined
|
||||
* space.
|
||||
*/
|
||||
public class PercentFrameLayout extends ViewGroup {
|
||||
private int xPercent = 0;
|
||||
private int yPercent = 0;
|
||||
private int widthPercent = 100;
|
||||
private int heightPercent = 100;
|
||||
|
||||
public PercentFrameLayout(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public PercentFrameLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public PercentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public void setPosition(int xPercent, int yPercent, int widthPercent, int heightPercent) {
|
||||
this.xPercent = xPercent;
|
||||
this.yPercent = yPercent;
|
||||
this.widthPercent = widthPercent;
|
||||
this.heightPercent = heightPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDelayChildPressedState() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
final int width = getDefaultSize(Integer.MAX_VALUE, widthMeasureSpec);
|
||||
final int height = getDefaultSize(Integer.MAX_VALUE, heightMeasureSpec);
|
||||
setMeasuredDimension(
|
||||
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
|
||||
|
||||
final int childWidthMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(width * widthPercent / 100, MeasureSpec.AT_MOST);
|
||||
final int childHeightMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(height * heightPercent / 100, MeasureSpec.AT_MOST);
|
||||
for (int i = 0; i < getChildCount(); ++i) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
final int width = right - left;
|
||||
final int height = bottom - top;
|
||||
// Sub-rectangle specified by percentage values.
|
||||
final int subWidth = width * widthPercent / 100;
|
||||
final int subHeight = height * heightPercent / 100;
|
||||
final int subLeft = left + width * xPercent / 100;
|
||||
final int subTop = top + height * yPercent / 100;
|
||||
|
||||
for (int i = 0; i < getChildCount(); ++i) {
|
||||
final View child = getChildAt(i);
|
||||
if (child.getVisibility() != GONE) {
|
||||
final int childWidth = child.getMeasuredWidth();
|
||||
final int childHeight = child.getMeasuredHeight();
|
||||
// Center child both vertically and horizontally.
|
||||
final int childLeft = subLeft + (subWidth - childWidth) / 2;
|
||||
final int childTop = subTop + (subHeight - childHeight) / 2;
|
||||
child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user