Make PeerConnectionClient non-singleton.
Ownership of EglBase is moved to PeerConnectionClient.
BUG=webrtc:8135
Review-Url: https://codereview.webrtc.org/3007893002
Cr-Original-Commit-Position: refs/heads/master@{#19634}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 85d7650ab6a84477e807d458ea835154cf5138da
diff --git a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
index de9ecd0..9c3347b 100644
--- a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
+++ b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
@@ -45,7 +45,6 @@
import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
-import org.webrtc.EglBase;
import org.webrtc.FileVideoCapturer;
import org.webrtc.IceCandidate;
import org.webrtc.Logging;
@@ -162,7 +161,6 @@
private AppRTCClient appRtcClient;
private SignalingParameters signalingParameters;
private AppRTCAudioManager audioManager = null;
- private EglBase rootEglBase;
private SurfaceViewRenderer pipRenderer;
private SurfaceViewRenderer fullscreenRenderer;
private VideoFileRenderer videoFileRenderer;
@@ -234,9 +232,11 @@
final Intent intent = getIntent();
+ // Create peer connection client.
+ peerConnectionClient = new PeerConnectionClient();
+
// Create video renderers.
- rootEglBase = EglBase.create();
- pipRenderer.init(rootEglBase.getEglBaseContext(), null);
+ pipRenderer.init(peerConnectionClient.getRenderContext(), null);
pipRenderer.setScalingType(ScalingType.SCALE_ASPECT_FIT);
String saveRemoteVideoToFile = intent.getStringExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE);
@@ -245,15 +245,15 @@
int videoOutWidth = intent.getIntExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_WIDTH, 0);
int videoOutHeight = intent.getIntExtra(EXTRA_SAVE_REMOTE_VIDEO_TO_FILE_HEIGHT, 0);
try {
- videoFileRenderer = new VideoFileRenderer(
- saveRemoteVideoToFile, videoOutWidth, videoOutHeight, rootEglBase.getEglBaseContext());
+ videoFileRenderer = new VideoFileRenderer(saveRemoteVideoToFile, videoOutWidth,
+ videoOutHeight, peerConnectionClient.getRenderContext());
remoteRenderers.add(videoFileRenderer);
} catch (IOException e) {
throw new RuntimeException(
"Failed to open video file for output: " + saveRemoteVideoToFile, e);
}
}
- fullscreenRenderer.init(rootEglBase.getEglBaseContext(), null);
+ fullscreenRenderer.init(peerConnectionClient.getRenderContext(), null);
fullscreenRenderer.setScalingType(ScalingType.SCALE_ASPECT_FILL);
pipRenderer.setZOrderMediaOverlay(true);
@@ -368,7 +368,6 @@
}, runTimeMs);
}
- peerConnectionClient = PeerConnectionClient.getInstance();
if (loopback) {
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.networkIgnoreMask = 0;
@@ -507,7 +506,6 @@
logToast.cancel();
}
activityRunning = false;
- rootEglBase.release();
super.onDestroy();
}
@@ -623,10 +621,6 @@
appRtcClient.disconnectFromRoom();
appRtcClient = null;
}
- if (peerConnectionClient != null) {
- peerConnectionClient.close();
- peerConnectionClient = null;
- }
if (pipRenderer != null) {
pipRenderer.release();
pipRenderer = null;
@@ -639,6 +633,10 @@
fullscreenRenderer.release();
fullscreenRenderer = null;
}
+ if (peerConnectionClient != null) {
+ peerConnectionClient.close();
+ peerConnectionClient = null;
+ }
if (audioManager != null) {
audioManager.stop();
audioManager = null;
@@ -747,8 +745,8 @@
if (peerConnectionParameters.videoCallEnabled) {
videoCapturer = createVideoCapturer();
}
- peerConnectionClient.createPeerConnection(rootEglBase.getEglBaseContext(), localProxyRenderer,
- remoteRenderers, videoCapturer, signalingParameters);
+ peerConnectionClient.createPeerConnection(
+ localProxyRenderer, remoteRenderers, videoCapturer, signalingParameters);
if (signalingParameters.initiator) {
logAndToast("Creating OFFER...");
diff --git a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
index 28e7c7a..c9c9a51 100644
--- a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
@@ -103,11 +103,15 @@
private static final int HD_VIDEO_HEIGHT = 720;
private static final int BPS_IN_KBPS = 1000;
- private static final PeerConnectionClient instance = new PeerConnectionClient();
+ // Executor thread is started once in private ctor and is used for all
+ // peer connection API calls to ensure new peer connection factory is
+ // created on the same thread as previously destroyed factory.
+ private static final ExecutorService executor = Executors.newSingleThreadExecutor();
+
private final PCObserver pcObserver = new PCObserver();
private final SDPObserver sdpObserver = new SDPObserver();
- private final ExecutorService executor;
+ private final EglBase rootEglBase;
private PeerConnectionFactory factory;
private PeerConnection peerConnection;
PeerConnectionFactory.Options options = null;
@@ -288,15 +292,8 @@
void onPeerConnectionError(final String description);
}
- private PeerConnectionClient() {
- // Executor thread is started once in private ctor and is used for all
- // peer connection API calls to ensure new peer connection factory is
- // created on the same thread as previously destroyed factory.
- executor = Executors.newSingleThreadExecutor();
- }
-
- public static PeerConnectionClient getInstance() {
- return instance;
+ public PeerConnectionClient() {
+ rootEglBase = EglBase.create();
}
public void setPeerConnectionFactoryOptions(PeerConnectionFactory.Options options) {
@@ -335,15 +332,15 @@
});
}
- public void createPeerConnection(final EglBase.Context renderEGLContext,
- final VideoRenderer.Callbacks localRender, final VideoRenderer.Callbacks remoteRender,
- final VideoCapturer videoCapturer, final SignalingParameters signalingParameters) {
- createPeerConnection(renderEGLContext, localRender, Collections.singletonList(remoteRender),
- videoCapturer, signalingParameters);
+ public void createPeerConnection(final VideoRenderer.Callbacks localRender,
+ final VideoRenderer.Callbacks remoteRender, final VideoCapturer videoCapturer,
+ final SignalingParameters signalingParameters) {
+ createPeerConnection(
+ localRender, Collections.singletonList(remoteRender), videoCapturer, signalingParameters);
}
- public void createPeerConnection(final EglBase.Context renderEGLContext,
- final VideoRenderer.Callbacks localRender, final List<VideoRenderer.Callbacks> remoteRenders,
- final VideoCapturer videoCapturer, final SignalingParameters signalingParameters) {
+ public void createPeerConnection(final VideoRenderer.Callbacks localRender,
+ final List<VideoRenderer.Callbacks> remoteRenders, final VideoCapturer videoCapturer,
+ final SignalingParameters signalingParameters) {
if (peerConnectionParameters == null) {
Log.e(TAG, "Creating peer connection without initializing factory.");
return;
@@ -357,7 +354,7 @@
public void run() {
try {
createMediaConstraintsInternal();
- createPeerConnectionInternal(renderEGLContext);
+ createPeerConnectionInternal();
} catch (Exception e) {
reportError("Failed to create peer connection: " + e.getMessage());
throw e;
@@ -583,7 +580,7 @@
}
}
- private void createPeerConnectionInternal(EglBase.Context renderEGLContext) {
+ private void createPeerConnectionInternal() {
if (factory == null || isError) {
Log.e(TAG, "Peerconnection factory is not created");
return;
@@ -594,8 +591,8 @@
queuedRemoteCandidates = new LinkedList<IceCandidate>();
if (videoCallEnabled) {
- Log.d(TAG, "EGLContext: " + renderEGLContext);
- factory.setVideoHwAccelerationOptions(renderEGLContext, renderEGLContext);
+ factory.setVideoHwAccelerationOptions(
+ rootEglBase.getEglBaseContext(), rootEglBase.getEglBaseContext());
}
PeerConnection.RTCConfiguration rtcConfig =
@@ -698,6 +695,7 @@
factory = null;
}
options = null;
+ rootEglBase.release();
Log.d(TAG, "Closing peer connection done.");
events.onPeerConnectionClosed();
PeerConnectionFactory.stopInternalTracingCapture();
@@ -713,6 +711,10 @@
return videoWidth * videoHeight >= 1280 * 720;
}
+ public EglBase.Context getRenderContext() {
+ return rootEglBase.getEglBaseContext();
+ }
+
private void getStats() {
if (peerConnection == null || isError) {
return;
diff --git a/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
index e93ce74..08c0242 100644
--- a/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
+++ b/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
@@ -35,7 +35,6 @@
import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
-import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaCodecVideoEncoder;
import org.webrtc.PeerConnection;
@@ -73,9 +72,6 @@
private volatile PeerConnectionClient pcClient;
private volatile boolean loopback;
- // EGL context that can be used by hardware video decoders to decode to a texture.
- private EglBase eglBase;
-
// These are protected by their respective event objects.
private ExecutorService signalingExecutor;
private boolean isClosed;
@@ -242,22 +238,21 @@
PeerConnectionClient createPeerConnectionClient(MockRenderer localRenderer,
MockRenderer remoteRenderer, PeerConnectionParameters peerConnectionParameters,
- VideoCapturer videoCapturer, EglBase.Context eglContext) {
+ VideoCapturer videoCapturer) {
List<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.IceServer>();
SignalingParameters signalingParameters =
new SignalingParameters(iceServers, true, // iceServers, initiator.
null, null, null, // clientId, wssUrl, wssPostUrl.
null, null); // offerSdp, iceCandidates.
- PeerConnectionClient client = PeerConnectionClient.getInstance();
+ PeerConnectionClient client = new PeerConnectionClient();
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.networkIgnoreMask = 0;
options.disableNetworkMonitor = true;
client.setPeerConnectionFactoryOptions(options);
client.createPeerConnectionFactory(
InstrumentationRegistry.getTargetContext(), peerConnectionParameters, this);
- client.createPeerConnection(
- eglContext, localRenderer, remoteRenderer, videoCapturer, signalingParameters);
+ client.createPeerConnection(localRenderer, remoteRenderer, videoCapturer, signalingParameters);
client.createOffer();
return client;
}
@@ -327,17 +322,11 @@
@Before
public void setUp() {
signalingExecutor = Executors.newSingleThreadExecutor();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- eglBase = EglBase.create();
- }
}
@After
public void tearDown() {
signalingExecutor.shutdown();
- if (eglBase != null) {
- eglBase.release();
- }
}
@Test
@@ -347,7 +336,7 @@
MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
pcClient = createPeerConnectionClient(localRenderer, new MockRenderer(0, null),
createParametersForVideoCall(VIDEO_CODEC_VP8),
- createCameraCapturer(false /* captureToTexture */), null);
+ createCameraCapturer(false /* captureToTexture */));
// Wait for local SDP and ice candidates set events.
assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -375,8 +364,7 @@
} else {
Log.d(TAG, "testLoopback for audio.");
}
- pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, parameters, videoCapturer,
- decodeToTexture ? eglBase.getEglBaseContext() : null);
+ pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, parameters, videoCapturer);
// Wait for local SDP, rename it to answer and set as remote SDP.
assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -481,50 +469,6 @@
createCameraCapturer(true /* captureToTexture */), true /* decodeToTexture */);
}
- // Test that a call can be setup even if the EGL context used during initialization is
- // released before the Video codecs are created. The HW encoder and decoder is setup to use
- // textures.
- @Test
- @SmallTest
- public void testLoopbackEglContextReleasedAfterCreatingPc() throws InterruptedException {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
- Log.i(TAG, "Decode to textures is not supported. Requires SDK version 19");
- return;
- }
-
- loopback = true;
- PeerConnectionParameters parameters = createParametersForVideoCall(VIDEO_CODEC_VP8);
- MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
- MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
- pcClient = createPeerConnectionClient(localRenderer, remoteRenderer, parameters,
- createCameraCapturer(true /* captureToTexture */), eglBase.getEglBaseContext());
-
- // Wait for local SDP, rename it to answer and set as remote SDP.
- assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
-
- // Release the EGL context used for creating the PeerConnectionClient.
- // Since createPeerConnectionClient is asynchronous, we must wait for the local
- // SessionDescription.
- eglBase.release();
- eglBase = null;
-
- SessionDescription remoteSdp = new SessionDescription(
- SessionDescription.Type.fromCanonicalForm("answer"), localSdp.description);
- pcClient.setRemoteDescription(remoteSdp);
-
- // Wait for ICE connection.
- assertTrue("ICE connection failure.", waitForIceConnected(ICE_CONNECTION_WAIT_TIMEOUT));
- // Check that local and remote video frames were rendered.
- assertTrue(
- "Local video frames were not rendered.", localRenderer.waitForFramesRendered(WAIT_TIMEOUT));
- assertTrue("Remote video frames were not rendered.",
- remoteRenderer.waitForFramesRendered(WAIT_TIMEOUT));
-
- pcClient.close();
- assertTrue(waitForPeerConnectionClosed(WAIT_TIMEOUT));
- Log.d(TAG, "testLoopback done.");
- }
-
@Test
@SmallTest
public void testLoopbackH264CaptureToTexture() throws InterruptedException {
@@ -555,7 +499,7 @@
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,
createParametersForVideoCall(VIDEO_CODEC_VP8),
- createCameraCapturer(false /* captureToTexture */), null);
+ createCameraCapturer(false /* captureToTexture */));
// Wait for local SDP, rename it to answer and set as remote SDP.
assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -603,7 +547,7 @@
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,
createParametersForVideoCall(VIDEO_CODEC_VP8),
- createCameraCapturer(false /* captureToTexture */), null);
+ createCameraCapturer(false /* captureToTexture */));
// Wait for local SDP, rename it to answer and set as remote SDP.
assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -652,7 +596,7 @@
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,
createParametersForVideoCall(VIDEO_CODEC_VP8),
- createCameraCapturer(false /* captureToTexture */), null);
+ createCameraCapturer(false /* captureToTexture */));
// Wait for local SDP, rename it to answer and set as remote SDP.
assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));