Add unit test to decode to a surface texture.
Also parameterise on PeerConnectionParameters to prepare for more test variations. (capture and encode to textures)

Review URL: https://codereview.webrtc.org/1404093002

Cr-Commit-Position: refs/heads/master@{#10279}
diff --git a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
index 2b400bd..4024140 100644
--- a/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
+++ b/webrtc/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java
@@ -20,6 +20,7 @@
 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionEvents;
 import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
 import org.appspot.apprtc.util.LooperExecutor;
+import org.webrtc.EglBase;
 import org.webrtc.IceCandidate;
 import org.webrtc.MediaConstraints;
 import org.webrtc.PeerConnection;
@@ -28,6 +29,7 @@
 import org.webrtc.StatsReport;
 import org.webrtc.VideoRenderer;
 
+import android.os.Build;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
@@ -52,6 +54,9 @@
   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 LooperExecutor signalingExecutor;
   private boolean isClosed;
@@ -220,18 +225,13 @@
 
   PeerConnectionClient createPeerConnectionClient(
       MockRenderer localRenderer, MockRenderer remoteRenderer,
-      boolean enableVideo, String videoCodec) {
+      PeerConnectionParameters peerConnectionParameters, boolean decodeToTexture) {
     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.
-    PeerConnectionParameters peerConnectionParameters =
-        new PeerConnectionParameters(
-            enableVideo, true, // videoCallEnabled, loopback.
-            0, 0, 0, 0, videoCodec, true, // video codec parameters.
-            0, "OPUS", false, true); // audio codec parameters.
 
     PeerConnectionClient client = PeerConnectionClient.getInstance();
     PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
@@ -239,21 +239,37 @@
     client.setPeerConnectionFactoryOptions(options);
     client.createPeerConnectionFactory(
         getInstrumentation().getContext(), peerConnectionParameters, this);
-    client.createPeerConnection(
-        null, localRenderer, remoteRenderer, signalingParameters);
+    client.createPeerConnection(decodeToTexture ? eglBase.getContext() : null,
+        localRenderer, remoteRenderer, signalingParameters);
     client.createOffer();
     return client;
   }
 
+  private PeerConnectionParameters createParameters(boolean enableVideo,
+      String videoCodec) {
+    PeerConnectionParameters peerConnectionParameters =
+        new PeerConnectionParameters(
+            enableVideo, true, // videoCallEnabled, loopback.
+            0, 0, 0, 0, videoCodec, true, // video codec parameters.
+            0, "OPUS", false, true); // audio codec parameters.
+    return peerConnectionParameters;
+  }
+
   @Override
   public void setUp() {
     signalingExecutor = new LooperExecutor();
     signalingExecutor.requestStart();
+    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+      eglBase = new EglBase();
+    }
   }
 
   @Override
   public void tearDown() {
     signalingExecutor.requestStop();
+    if (eglBase != null) {
+      eglBase.release();
+    }
   }
 
   public void testSetLocalOfferMakesVideoFlowLocally()
@@ -261,7 +277,7 @@
     Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally");
     MockRenderer localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
     pcClient = createPeerConnectionClient(
-        localRenderer, new MockRenderer(0, null), true, VIDEO_CODEC_VP8);
+        localRenderer, new MockRenderer(0, null), createParameters(true, VIDEO_CODEC_VP8), false);
 
     // Wait for local SDP and ice candidates set events.
     assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -278,20 +294,20 @@
     Log.d(TAG, "testSetLocalOfferMakesVideoFlowLocally Done.");
   }
 
-  private void doLoopbackTest(boolean enableVideo, String videoCodec)
+  private void doLoopbackTest(PeerConnectionParameters parameters, boolean decodeToTexure)
       throws InterruptedException {
     loopback = true;
     MockRenderer localRenderer = null;
     MockRenderer remoteRenderer = null;
-    if (enableVideo) {
-      Log.d(TAG, "testLoopback for video " + videoCodec);
+    if (parameters.videoCallEnabled) {
+      Log.d(TAG, "testLoopback for video " + parameters.videoCodec);
       localRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, LOCAL_RENDERER_NAME);
       remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
     } else {
       Log.d(TAG, "testLoopback for audio.");
     }
     pcClient = createPeerConnectionClient(
-        localRenderer, remoteRenderer, enableVideo, videoCodec);
+        localRenderer, remoteRenderer, parameters, decodeToTexure);
 
     // Wait for local SDP, rename it to answer and set as remote SDP.
     assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -303,7 +319,7 @@
     // Wait for ICE connection.
     assertTrue("ICE connection failure.", waitForIceConnected(ICE_CONNECTION_WAIT_TIMEOUT));
 
-    if (enableVideo) {
+    if (parameters.videoCallEnabled) {
       // Check that local and remote video frames were rendered.
       assertTrue("Local video frames were not rendered.",
           localRenderer.waitForFramesRendered(WAIT_TIMEOUT));
@@ -321,19 +337,44 @@
   }
 
   public void testLoopbackAudio() throws InterruptedException {
-    doLoopbackTest(false, VIDEO_CODEC_VP8);
+    doLoopbackTest(createParameters(false, VIDEO_CODEC_VP8), false);
   }
 
   public void testLoopbackVp8() throws InterruptedException {
-    doLoopbackTest(true, VIDEO_CODEC_VP8);
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_VP8), false);
   }
 
   public void DISABLED_testLoopbackVp9() throws InterruptedException {
-    doLoopbackTest(true, VIDEO_CODEC_VP9);
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_VP9), false);
   }
 
   public void testLoopbackH264() throws InterruptedException {
-    doLoopbackTest(true, VIDEO_CODEC_H264);
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_H264), false);
+  }
+
+  public void testLoopbackVp8DecodeToTexture() throws InterruptedException {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+      Log.i(TAG, "Decode to textures is not supported, requires EGL14.");
+      return;
+    }
+
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_VP8), true);
+  }
+
+  public void DISABLED_testLoopbackVp9DecodeToTexture() throws InterruptedException {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+      Log.i(TAG, "Decode to textures is not supported, requires EGL14.");
+      return;
+    }
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_VP9), true);
+  }
+
+  public void testLoopbackH264DecodeToTexture() throws InterruptedException {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+      Log.i(TAG, "Decode to textures is not supported, requires EGL14.");
+      return;
+    }
+    doLoopbackTest(createParameters(true, VIDEO_CODEC_H264), true);
   }
 
   // Checks if default front camera can be switched to back camera and then
@@ -346,7 +387,7 @@
     MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
 
     pcClient = createPeerConnectionClient(
-        localRenderer, remoteRenderer, true, VIDEO_CODEC_VP8);
+        localRenderer, remoteRenderer, createParameters(true, VIDEO_CODEC_VP8), false);
 
     // Wait for local SDP, rename it to answer and set as remote SDP.
     assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));
@@ -392,7 +433,7 @@
     MockRenderer remoteRenderer = new MockRenderer(EXPECTED_VIDEO_FRAMES, REMOTE_RENDERER_NAME);
 
     pcClient = createPeerConnectionClient(
-        localRenderer, remoteRenderer, true, VIDEO_CODEC_VP8);
+        localRenderer, remoteRenderer, createParameters(true, VIDEO_CODEC_VP8), false);
 
     // Wait for local SDP, rename it to answer and set as remote SDP.
     assertTrue("Local SDP was not set.", waitForLocalSDP(WAIT_TIMEOUT));