Convert FileVideoCapturer to capture VideoFrames.

Bug: webrtc:7749
Change-Id: I0e102888bf3f9d413b9e9282354f7577c52bef59
Reviewed-on: https://webrtc-review.googlesource.com/6920
Reviewed-by: Magnus Jedvert <magjed@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20173}
diff --git a/sdk/android/api/org/webrtc/FileVideoCapturer.java b/sdk/android/api/org/webrtc/FileVideoCapturer.java
index a71e932..2cff9e0 100644
--- a/sdk/android/api/org/webrtc/FileVideoCapturer.java
+++ b/sdk/android/api/org/webrtc/FileVideoCapturer.java
@@ -12,12 +12,12 @@
 
 import android.content.Context;
 import android.os.SystemClock;
-
-import java.util.concurrent.TimeUnit;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
 import java.util.Timer;
 import java.util.TimerTask;
-import java.io.RandomAccessFile;
-import java.io.IOException;
+import java.util.concurrent.TimeUnit;
 
 public class FileVideoCapturer implements VideoCapturer {
   static {
@@ -25,9 +25,7 @@
   }
 
   private interface VideoReader {
-    int getFrameWidth();
-    int getFrameHeight();
-    byte[] getNextFrame();
+    VideoFrame getNextFrame();
     void close();
   }
 
@@ -35,26 +33,15 @@
    * Read video data from file for the .y4m container.
    */
   private static class VideoReaderY4M implements VideoReader {
-    private final static String TAG = "VideoReaderY4M";
-    private final int frameWidth;
-    private final int frameHeight;
-    private final int frameSize;
-
-    // First char after header
-    private final long videoStart;
-
+    private static final String TAG = "VideoReaderY4M";
     private static final String Y4M_FRAME_DELIMETER = "FRAME";
 
+    private final int frameWidth;
+    private final int frameHeight;
+    // First char after header
+    private final long videoStart;
     private final RandomAccessFile mediaFileStream;
 
-    public int getFrameWidth() {
-      return frameWidth;
-    }
-
-    public int getFrameHeight() {
-      return frameHeight;
-    }
-
     public VideoReaderY4M(String file) throws IOException {
       mediaFileStream = new RandomAccessFile(file, "r");
       StringBuilder builder = new StringBuilder();
@@ -100,12 +87,20 @@
       }
       frameWidth = w;
       frameHeight = h;
-      frameSize = w * h * 3 / 2;
-      Logging.d(TAG, "frame dim: (" + w + ", " + h + ") frameSize: " + frameSize);
+      Logging.d(TAG, "frame dim: (" + w + ", " + h + ")");
     }
 
-    public byte[] getNextFrame() {
-      byte[] frame = new byte[frameSize];
+    public VideoFrame getNextFrame() {
+      final long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime());
+      final JavaI420Buffer buffer = JavaI420Buffer.allocate(frameWidth, frameHeight);
+      final ByteBuffer dataY = buffer.getDataY();
+      final ByteBuffer dataU = buffer.getDataU();
+      final ByteBuffer dataV = buffer.getDataV();
+      final int chromaHeight = (frameHeight + 1) / 2;
+      final int sizeY = frameHeight * buffer.getStrideY();
+      final int sizeU = chromaHeight * buffer.getStrideU();
+      final int sizeV = chromaHeight * buffer.getStrideV();
+
       try {
         byte[] frameDelim = new byte[Y4M_FRAME_DELIMETER.length() + 1];
         if (mediaFileStream.read(frameDelim) < frameDelim.length) {
@@ -121,13 +116,15 @@
               "Frames should be delimited by FRAME plus newline, found delimter was: '"
               + frameDelimStr + "'");
         }
-        mediaFileStream.readFully(frame);
-        byte[] nv21Frame = new byte[frameSize];
-        nativeI420ToNV21(frame, frameWidth, frameHeight, nv21Frame);
-        return nv21Frame;
+
+        mediaFileStream.readFully(dataY.array(), dataY.arrayOffset(), sizeY);
+        mediaFileStream.readFully(dataU.array(), dataU.arrayOffset(), sizeU);
+        mediaFileStream.readFully(dataV.array(), dataV.arrayOffset(), sizeV);
       } catch (IOException e) {
         throw new RuntimeException(e);
       }
+
+      return new VideoFrame(buffer, 0 /* rotation */, captureTimeNs);
     }
 
     public void close() {
@@ -151,14 +148,6 @@
     }
   };
 
-  private int getFrameWidth() {
-    return videoReader.getFrameWidth();
-  }
-
-  private int getFrameHeight() {
-    return videoReader.getFrameHeight();
-  }
-
   public FileVideoCapturer(String inputFile) throws IOException {
     try {
       videoReader = new VideoReaderY4M(inputFile);
@@ -168,16 +157,8 @@
     }
   }
 
-  private byte[] getNextFrame() {
-    return videoReader.getNextFrame();
-  }
-
   public void tick() {
-    final long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime());
-
-    byte[] frameData = getNextFrame();
-    capturerObserver.onByteBufferFrameCaptured(
-        frameData, getFrameWidth(), getFrameHeight(), 0, captureTimeNs);
+    capturerObserver.onFrameCaptured(videoReader.getNextFrame());
   }
 
   @Override
@@ -210,6 +191,4 @@
   public boolean isScreencast() {
     return false;
   }
-
-  public static native void nativeI420ToNV21(byte[] src, int width, int height, byte[] dst);
 }