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:
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
Reference in New Issue
Block a user