Android AppRTCMobile: Transition local render to new VideoSink interface
BUG=None
Review-Url: https://codereview.webrtc.org/3016443002
Cr-Original-Commit-Position: refs/heads/master@{#19820}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 4e15e67da8072e8ce7b70c32df3c4be286363ab4
diff --git a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
index 9c3347b..45bc26b 100644
--- a/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
+++ b/examples/androidapp/src/org/appspot/apprtc/CallActivity.java
@@ -56,7 +56,9 @@
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFileRenderer;
+import org.webrtc.VideoFrame;
import org.webrtc.VideoRenderer;
+import org.webrtc.VideoSink;
/**
* Activity for peer connection call setup, call waiting
@@ -137,9 +139,11 @@
// Peer connection statistics callback period in ms.
private static final int STAT_CALLBACK_PERIOD = 1000;
- private class ProxyRenderer implements VideoRenderer.Callbacks {
- private VideoRenderer.Callbacks target;
+ private class ProxyRenderer<T extends VideoRenderer.Callbacks & VideoSink>
+ implements VideoRenderer.Callbacks, VideoSink {
+ private T target;
+ @Override
synchronized public void renderFrame(VideoRenderer.I420Frame frame) {
if (target == null) {
Logging.d(TAG, "Dropping frame in proxy because target is null.");
@@ -150,7 +154,17 @@
target.renderFrame(frame);
}
- synchronized public void setTarget(VideoRenderer.Callbacks target) {
+ @Override
+ synchronized public void onFrame(VideoFrame frame) {
+ if (target == null) {
+ Logging.d(TAG, "Dropping frame in proxy because target is null.");
+ return;
+ }
+
+ target.onFrame(frame);
+ }
+
+ synchronized public void setTarget(T target) {
this.target = target;
}
}
diff --git a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
index c9c9a51..e40a17c 100644
--- a/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
+++ b/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
@@ -52,6 +52,7 @@
import org.webrtc.StatsReport;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoRenderer;
+import org.webrtc.VideoSink;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
import org.webrtc.voiceengine.WebRtcAudioManager;
@@ -123,7 +124,7 @@
private boolean videoCapturerStopped;
private boolean isError;
private Timer statsTimer;
- private VideoRenderer.Callbacks localRender;
+ private VideoSink localRender;
private List<VideoRenderer.Callbacks> remoteRenders;
private SignalingParameters signalingParameters;
private MediaConstraints pcConstraints;
@@ -332,13 +333,13 @@
});
}
- public void createPeerConnection(final VideoRenderer.Callbacks localRender,
+ public void createPeerConnection(final VideoSink localRender,
final VideoRenderer.Callbacks remoteRender, final VideoCapturer videoCapturer,
final SignalingParameters signalingParameters) {
createPeerConnection(
localRender, Collections.singletonList(remoteRender), videoCapturer, signalingParameters);
}
- public void createPeerConnection(final VideoRenderer.Callbacks localRender,
+ public void createPeerConnection(final VideoSink localRender,
final List<VideoRenderer.Callbacks> remoteRenders, final VideoCapturer videoCapturer,
final SignalingParameters signalingParameters) {
if (peerConnectionParameters == null) {
@@ -946,7 +947,7 @@
localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource);
localVideoTrack.setEnabled(renderVideo);
- localVideoTrack.addRenderer(new VideoRenderer(localRender));
+ localVideoTrack.addSink(localRender);
return localVideoTrack;
}
diff --git a/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
index 08c0242..dda16ad 100644
--- a/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
+++ b/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
@@ -42,7 +42,9 @@
import org.webrtc.SessionDescription;
import org.webrtc.StatsReport;
import org.webrtc.VideoCapturer;
+import org.webrtc.VideoFrame;
import org.webrtc.VideoRenderer;
+import org.webrtc.VideoSink;
@RunWith(BaseJUnit4ClassRunner.class)
public class PeerConnectionClientTest implements PeerConnectionEvents {
@@ -126,6 +128,49 @@
}
}
+ // Mock VideoSink implementation.
+ private static class MockSink implements VideoSink {
+ // These are protected by 'this' since we gets called from worker threads.
+ private String rendererName;
+ private boolean renderFrameCalled = false;
+
+ // Thread-safe in itself.
+ private CountDownLatch doneRendering;
+
+ public MockSink(int expectedFrames, String rendererName) {
+ this.rendererName = rendererName;
+ reset(expectedFrames);
+ }
+
+ // Resets render to wait for new amount of video frames.
+ public synchronized void reset(int expectedFrames) {
+ renderFrameCalled = false;
+ doneRendering = new CountDownLatch(expectedFrames);
+ }
+
+ @Override
+ public synchronized void onFrame(VideoFrame frame) {
+ if (!renderFrameCalled) {
+ if (rendererName != null) {
+ Log.d(TAG,
+ rendererName + " render frame: " + frame.getRotatedWidth() + " x "
+ + frame.getRotatedHeight());
+ } else {
+ Log.d(TAG, "Render frame: " + frame.getRotatedWidth() + " x " + frame.getRotatedHeight());
+ }
+ }
+ renderFrameCalled = true;
+ doneRendering.countDown();
+ }
+
+ // This method shouldn't hold any locks or touch member variables since it
+ // blocks.
+ public boolean waitForFramesRendered(int timeoutMs) throws InterruptedException {
+ doneRendering.await(timeoutMs, TimeUnit.MILLISECONDS);
+ return (doneRendering.getCount() <= 0);
+ }
+ }
+
// Peer connection events implementation.
@Override
public void onLocalDescription(SessionDescription sdp) {
@@ -236,7 +281,7 @@
}
}
- PeerConnectionClient createPeerConnectionClient(MockRenderer localRenderer,
+ PeerConnectionClient createPeerConnectionClient(MockSink localRenderer,
MockRenderer remoteRenderer, PeerConnectionParameters peerConnectionParameters,
VideoCapturer videoCapturer) {
List<PeerConnection.IceServer> iceServers = new LinkedList<PeerConnection.IceServer>();
@@ -333,7 +378,7 @@
@SmallTest
public void testSetLocalOfferMakesVideoFlowLocally() throws InterruptedException {
Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally");
- MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
+ MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
pcClient = createPeerConnectionClient(localRenderer, new MockRenderer(0, null),
createParametersForVideoCall(VIDEO_CODEC_VP8),
createCameraCapturer(false /* captureToTexture */));
@@ -355,11 +400,11 @@
private void doLoopbackTest(PeerConnectionParameters parameters, VideoCapturer videoCapturer,
boolean decodeToTexture) throws InterruptedException {
loopback = true;
- MockRenderer localRenderer = null;
+ MockSink localRenderer = null;
MockRenderer remoteRenderer = null;
if (parameters.videoCallEnabled) {
Log.d(TAG, "testLoopback for video " + parameters.videoCodec);
- localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
+ localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
} else {
Log.d(TAG, "testLoopback for audio.");
@@ -494,7 +539,7 @@
Log.d(TAG, "testCameraSwitch");
loopback = true;
- MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
+ MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,
@@ -542,7 +587,7 @@
Log.d(TAG, "testVideoSourceRestart");
loopback = true;
- MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
+ MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,
@@ -591,7 +636,7 @@
Log.d(TAG, "testCaptureFormatChange");
loopback = true;
- MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
+ MockSink localRenderer = new MockSink(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
pcClient = createPeerConnectionClient(localRenderer, remoteRenderer,