Add option to inject YuvConverter to SurfaceTextureHelper.

Add option to inject VideoFrameDrawer to YuvConverter and EglRenderer.

Bug: none
Change-Id: I0aab0026c30b41d72f70fb00b251aed5e4a4a774
Reviewed-on: https://webrtc-review.googlesource.com/c/123443
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26848}
diff --git a/sdk/android/api/org/webrtc/YuvConverter.java b/sdk/android/api/org/webrtc/YuvConverter.java
index 7d55f07..0e2d505 100644
--- a/sdk/android/api/org/webrtc/YuvConverter.java
+++ b/sdk/android/api/org/webrtc/YuvConverter.java
@@ -107,17 +107,27 @@
       new GlTextureFrameBuffer(GLES20.GL_RGBA);
   private final ShaderCallbacks shaderCallbacks = new ShaderCallbacks();
   private final GlGenericDrawer drawer = new GlGenericDrawer(FRAGMENT_SHADER, shaderCallbacks);
+  private final VideoFrameDrawer videoFrameDrawer;
 
   /**
    * This class should be constructed on a thread that has an active EGL context.
    */
   public YuvConverter() {
+    this(new VideoFrameDrawer());
+  }
+
+  public YuvConverter(VideoFrameDrawer videoFrameDrawer) {
+    this.videoFrameDrawer = videoFrameDrawer;
     threadChecker.detachThread();
   }
 
   /** Converts the texture buffer to I420. */
   public I420Buffer convert(TextureBuffer inputTextureBuffer) {
     threadChecker.checkIsOnValidThread();
+
+    TextureBuffer preparedBuffer = (TextureBuffer) videoFrameDrawer.prepareBufferForViewportSize(
+        inputTextureBuffer, inputTextureBuffer.getWidth(), inputTextureBuffer.getHeight());
+
     // We draw into a buffer laid out like
     //
     //    +---------+
@@ -146,8 +156,8 @@
     // Since the V data needs to start on a boundary of such a
     // larger pixel, it is not sufficient that |stride| is even, it
     // has to be a multiple of 8 pixels.
-    final int frameWidth = inputTextureBuffer.getWidth();
-    final int frameHeight = inputTextureBuffer.getHeight();
+    final int frameWidth = preparedBuffer.getWidth();
+    final int frameHeight = preparedBuffer.getHeight();
     final int stride = ((frameWidth + 7) / 8) * 8;
     final int uvHeight = (frameHeight + 1) / 2;
     // Total height of the combined memory layout.
@@ -171,19 +181,19 @@
 
     // Draw Y.
     shaderCallbacks.setPlaneY();
-    VideoFrameDrawer.drawTexture(drawer, inputTextureBuffer, renderMatrix, frameWidth, frameHeight,
+    VideoFrameDrawer.drawTexture(drawer, preparedBuffer, renderMatrix, frameWidth, frameHeight,
         /* viewportX= */ 0, /* viewportY= */ 0, viewportWidth,
         /* viewportHeight= */ frameHeight);
 
     // Draw U.
     shaderCallbacks.setPlaneU();
-    VideoFrameDrawer.drawTexture(drawer, inputTextureBuffer, renderMatrix, frameWidth, frameHeight,
+    VideoFrameDrawer.drawTexture(drawer, preparedBuffer, renderMatrix, frameWidth, frameHeight,
         /* viewportX= */ 0, /* viewportY= */ frameHeight, viewportWidth / 2,
         /* viewportHeight= */ uvHeight);
 
     // Draw V.
     shaderCallbacks.setPlaneV();
-    VideoFrameDrawer.drawTexture(drawer, inputTextureBuffer, renderMatrix, frameWidth, frameHeight,
+    VideoFrameDrawer.drawTexture(drawer, preparedBuffer, renderMatrix, frameWidth, frameHeight,
         /* viewportX= */ viewportWidth / 2, /* viewportY= */ frameHeight, viewportWidth / 2,
         /* viewportHeight= */ uvHeight);
 
@@ -215,6 +225,8 @@
     i420ByteBuffer.limit(vPos + uvSize);
     final ByteBuffer dataV = i420ByteBuffer.slice();
 
+    preparedBuffer.release();
+
     return JavaI420Buffer.wrap(frameWidth, frameHeight, dataY, stride, dataU, stride, dataV, stride,
         () -> { JniCommon.nativeFreeByteBuffer(i420ByteBuffer); });
   }
@@ -223,6 +235,7 @@
     threadChecker.checkIsOnValidThread();
     drawer.release();
     i420TextureFrameBuffer.release();
+    videoFrameDrawer.release();
     // Allow this class to be reused.
     threadChecker.detachThread();
   }