Android AppRTCMobile: Transition local render to new VideoSink interface

BUG=None

Review-Url: https://codereview.webrtc.org/3016443002
Cr-Commit-Position: refs/heads/master@{#19820}
This commit is contained in:
magjed
2017-09-13 07:11:16 -07:00
committed by Commit Bot
parent c434e964e0
commit 4e15e67da8
3 changed files with 74 additions and 14 deletions

View File

@ -56,7 +56,9 @@ import org.webrtc.StatsReport;
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 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
// 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 @@ public class CallActivity extends Activity implements AppRTCClient.SignalingEven
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;
}
}

View File

@ -52,6 +52,7 @@ import org.webrtc.StatsObserver;
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 @@ public class PeerConnectionClient {
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 class PeerConnectionClient {
});
}
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 @@ public class PeerConnectionClient {
localVideoTrack = factory.createVideoTrack(VIDEO_TRACK_ID, videoSource);
localVideoTrack.setEnabled(renderVideo);
localVideoTrack.addRenderer(new VideoRenderer(localRender));
localVideoTrack.addSink(localRender);
return localVideoTrack;
}

View File

@ -42,7 +42,9 @@ import org.webrtc.PeerConnectionFactory;
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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
}
}
// 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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
}
}
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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
@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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
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 @@ public class PeerConnectionClientTest implements PeerConnectionEvents {
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,