Move cropAndScaleI420 to JavaI420Buffer.

This allows removing JavaI420Buffer from video_api. This is technically
a public method but I don't think anyone is using it so it should be
safe to move.

Bug: webrtc:9048
Change-Id: Id563a3af030497e1a92e09da79ca1ed925e064a3
Reviewed-on: https://webrtc-review.googlesource.com/90250
Reviewed-by: Paulina Hensman <phensman@webrtc.org>
Commit-Queue: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#24090}
diff --git a/sdk/android/BUILD.gn b/sdk/android/BUILD.gn
index 0969637..c6839fa 100644
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -229,9 +229,6 @@
       "api/org/webrtc/VideoSink.java",
     ]
 
-    # TODO(sakal): These should be moved to video_java but cannot because of dependencies.
-    java_files += [ "api/org/webrtc/JavaI420Buffer.java" ]
-
     deps = [
       ":base_java",
       "//rtc_base:base_java",
@@ -246,6 +243,7 @@
       "api/org/webrtc/GlShader.java",
       "api/org/webrtc/GlTextureFrameBuffer.java",
       "api/org/webrtc/GlUtil.java",
+      "api/org/webrtc/JavaI420Buffer.java",
       "api/org/webrtc/RendererCommon.java",
       "api/org/webrtc/SurfaceTextureHelper.java",
       "api/org/webrtc/TextureBufferImpl.java",
@@ -529,6 +527,7 @@
       "src/jni/encodedimage.cc",
       "src/jni/encodedimage.h",
       "src/jni/h264utils.cc",
+      "src/jni/javai420buffer.cc",
       "src/jni/jni_generator_helper.h",
       "src/jni/nativecapturerobserver.cc",
       "src/jni/nativecapturerobserver.h",
@@ -923,8 +922,6 @@
       "../../rtc_base:checks",
       "../../rtc_base:rtc_base",
       "../../rtc_base:rtc_base_approved",
-      "../../rtc_base/memory:aligned_malloc",
-      "//third_party/libyuv",
     ]
   }
 
@@ -1110,6 +1107,7 @@
   generate_jni("generated_video_jni") {
     sources = [
       "api/org/webrtc/EncodedImage.java",
+      "api/org/webrtc/JavaI420Buffer.java",
       "api/org/webrtc/MediaCodecVideoDecoder.java",
       "api/org/webrtc/MediaCodecVideoEncoder.java",
       "api/org/webrtc/VideoCodecInfo.java",
diff --git a/sdk/android/api/org/webrtc/JavaI420Buffer.java b/sdk/android/api/org/webrtc/JavaI420Buffer.java
index 7231fda..9bbd9b2 100644
--- a/sdk/android/api/org/webrtc/JavaI420Buffer.java
+++ b/sdk/android/api/org/webrtc/JavaI420Buffer.java
@@ -163,7 +163,37 @@
   @Override
   public VideoFrame.Buffer cropAndScale(
       int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
-    return VideoFrame.cropAndScaleI420(
-        this, cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight);
+    return cropAndScaleI420(this, cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight);
   }
+
+  public static VideoFrame.Buffer cropAndScaleI420(final I420Buffer buffer, int cropX, int cropY,
+      int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
+    if (cropWidth == scaleWidth && cropHeight == scaleHeight) {
+      // No scaling.
+      ByteBuffer dataY = buffer.getDataY();
+      ByteBuffer dataU = buffer.getDataU();
+      ByteBuffer dataV = buffer.getDataV();
+
+      dataY.position(cropX + cropY * buffer.getStrideY());
+      dataU.position(cropX / 2 + cropY / 2 * buffer.getStrideU());
+      dataV.position(cropX / 2 + cropY / 2 * buffer.getStrideV());
+
+      buffer.retain();
+      return JavaI420Buffer.wrap(scaleWidth, scaleHeight, dataY.slice(), buffer.getStrideY(),
+          dataU.slice(), buffer.getStrideU(), dataV.slice(), buffer.getStrideV(), buffer::release);
+    }
+
+    JavaI420Buffer newBuffer = JavaI420Buffer.allocate(scaleWidth, scaleHeight);
+    nativeCropAndScaleI420(buffer.getDataY(), buffer.getStrideY(), buffer.getDataU(),
+        buffer.getStrideU(), buffer.getDataV(), buffer.getStrideV(), cropX, cropY, cropWidth,
+        cropHeight, newBuffer.getDataY(), newBuffer.getStrideY(), newBuffer.getDataU(),
+        newBuffer.getStrideU(), newBuffer.getDataV(), newBuffer.getStrideV(), scaleWidth,
+        scaleHeight);
+    return newBuffer;
+  }
+
+  private static native void nativeCropAndScaleI420(ByteBuffer srcY, int srcStrideY,
+      ByteBuffer srcU, int srcStrideU, ByteBuffer srcV, int srcStrideV, int cropX, int cropY,
+      int cropWidth, int cropHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU,
+      int dstStrideU, ByteBuffer dstV, int dstStrideV, int scaleWidth, int scaleHeight);
 }
diff --git a/sdk/android/api/org/webrtc/VideoFrame.java b/sdk/android/api/org/webrtc/VideoFrame.java
index 4afe782..fb733af 100644
--- a/sdk/android/api/org/webrtc/VideoFrame.java
+++ b/sdk/android/api/org/webrtc/VideoFrame.java
@@ -188,37 +188,4 @@
   public void release() {
     buffer.release();
   }
-
-  // TODO(sakal): This file should be strictly an interface. This method should be moved somewhere
-  // else.
-  public static VideoFrame.Buffer cropAndScaleI420(final I420Buffer buffer, int cropX, int cropY,
-      int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
-    if (cropWidth == scaleWidth && cropHeight == scaleHeight) {
-      // No scaling.
-      ByteBuffer dataY = buffer.getDataY();
-      ByteBuffer dataU = buffer.getDataU();
-      ByteBuffer dataV = buffer.getDataV();
-
-      dataY.position(cropX + cropY * buffer.getStrideY());
-      dataU.position(cropX / 2 + cropY / 2 * buffer.getStrideU());
-      dataV.position(cropX / 2 + cropY / 2 * buffer.getStrideV());
-
-      buffer.retain();
-      return JavaI420Buffer.wrap(scaleWidth, scaleHeight, dataY.slice(), buffer.getStrideY(),
-          dataU.slice(), buffer.getStrideU(), dataV.slice(), buffer.getStrideV(), buffer::release);
-    }
-
-    JavaI420Buffer newBuffer = JavaI420Buffer.allocate(scaleWidth, scaleHeight);
-    nativeCropAndScaleI420(buffer.getDataY(), buffer.getStrideY(), buffer.getDataU(),
-        buffer.getStrideU(), buffer.getDataV(), buffer.getStrideV(), cropX, cropY, cropWidth,
-        cropHeight, newBuffer.getDataY(), newBuffer.getStrideY(), newBuffer.getDataU(),
-        newBuffer.getStrideU(), newBuffer.getDataV(), newBuffer.getStrideV(), scaleWidth,
-        scaleHeight);
-    return newBuffer;
-  }
-
-  private static native void nativeCropAndScaleI420(ByteBuffer srcY, int srcStrideY,
-      ByteBuffer srcU, int srcStrideU, ByteBuffer srcV, int srcStrideV, int cropX, int cropY,
-      int cropWidth, int cropHeight, ByteBuffer dstY, int dstStrideY, ByteBuffer dstU,
-      int dstStrideU, ByteBuffer dstV, int dstStrideV, int scaleWidth, int scaleHeight);
 }
diff --git a/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java b/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
index 8b698ca..0461660 100644
--- a/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
+++ b/sdk/android/src/java/org/webrtc/WrappedNativeI420Buffer.java
@@ -104,7 +104,7 @@
   @Override
   public VideoFrame.Buffer cropAndScale(
       int cropX, int cropY, int cropWidth, int cropHeight, int scaleWidth, int scaleHeight) {
-    return VideoFrame.cropAndScaleI420(
+    return JavaI420Buffer.cropAndScaleI420(
         this, cropX, cropY, cropWidth, cropHeight, scaleWidth, scaleHeight);
   }
 }
diff --git a/sdk/android/src/jni/javai420buffer.cc b/sdk/android/src/jni/javai420buffer.cc
new file mode 100644
index 0000000..a98462f
--- /dev/null
+++ b/sdk/android/src/jni/javai420buffer.cc
@@ -0,0 +1,64 @@
+/*
+ *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "sdk/android/generated_video_jni/jni/JavaI420Buffer_jni.h"
+#include "third_party/libyuv/include/libyuv/scale.h"
+
+namespace webrtc {
+namespace jni {
+
+static void JNI_JavaI420Buffer_CropAndScaleI420(
+    JNIEnv* jni,
+    const JavaParamRef<jclass>&,
+    const JavaParamRef<jobject>& j_src_y,
+    jint src_stride_y,
+    const JavaParamRef<jobject>& j_src_u,
+    jint src_stride_u,
+    const JavaParamRef<jobject>& j_src_v,
+    jint src_stride_v,
+    jint crop_x,
+    jint crop_y,
+    jint crop_width,
+    jint crop_height,
+    const JavaParamRef<jobject>& j_dst_y,
+    jint dst_stride_y,
+    const JavaParamRef<jobject>& j_dst_u,
+    jint dst_stride_u,
+    const JavaParamRef<jobject>& j_dst_v,
+    jint dst_stride_v,
+    jint scale_width,
+    jint scale_height) {
+  uint8_t const* src_y =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_y.obj()));
+  uint8_t const* src_u =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_u.obj()));
+  uint8_t const* src_v =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_v.obj()));
+  uint8_t* dst_y =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y.obj()));
+  uint8_t* dst_u =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u.obj()));
+  uint8_t* dst_v =
+      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v.obj()));
+
+  // Perform cropping using pointer arithmetic.
+  src_y += crop_x + crop_y * src_stride_y;
+  src_u += crop_x / 2 + crop_y / 2 * src_stride_u;
+  src_v += crop_x / 2 + crop_y / 2 * src_stride_v;
+
+  bool ret = libyuv::I420Scale(
+      src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, crop_width,
+      crop_height, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,
+      dst_stride_v, scale_width, scale_height, libyuv::kFilterBox);
+  RTC_DCHECK_EQ(ret, 0) << "I420Scale failed";
+}
+
+}  // namespace jni
+}  // namespace webrtc
diff --git a/sdk/android/src/jni/videoframe.cc b/sdk/android/src/jni/videoframe.cc
index aeb43bc..dd13cb3 100644
--- a/sdk/android/src/jni/videoframe.cc
+++ b/sdk/android/src/jni/videoframe.cc
@@ -17,13 +17,11 @@
 #include "rtc_base/checks.h"
 #include "rtc_base/keep_ref_until_done.h"
 #include "rtc_base/logging.h"
-#include "rtc_base/memory/aligned_malloc.h"
 #include "rtc_base/scoped_ref_ptr.h"
 #include "rtc_base/timeutils.h"
 #include "sdk/android/generated_video_jni/jni/VideoFrame_jni.h"
 #include "sdk/android/src/jni/jni_helpers.h"
 #include "sdk/android/src/jni/wrapped_native_i420_buffer.h"
-#include "third_party/libyuv/include/libyuv/scale.h"
 
 namespace webrtc {
 namespace jni {
@@ -230,51 +228,5 @@
   Java_VideoFrame_release(jni, j_video_frame);
 }
 
-static void JNI_VideoFrame_CropAndScaleI420(
-    JNIEnv* jni,
-    const JavaParamRef<jclass>&,
-    const JavaParamRef<jobject>& j_src_y,
-    jint src_stride_y,
-    const JavaParamRef<jobject>& j_src_u,
-    jint src_stride_u,
-    const JavaParamRef<jobject>& j_src_v,
-    jint src_stride_v,
-    jint crop_x,
-    jint crop_y,
-    jint crop_width,
-    jint crop_height,
-    const JavaParamRef<jobject>& j_dst_y,
-    jint dst_stride_y,
-    const JavaParamRef<jobject>& j_dst_u,
-    jint dst_stride_u,
-    const JavaParamRef<jobject>& j_dst_v,
-    jint dst_stride_v,
-    jint scale_width,
-    jint scale_height) {
-  uint8_t const* src_y =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_y.obj()));
-  uint8_t const* src_u =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_u.obj()));
-  uint8_t const* src_v =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_v.obj()));
-  uint8_t* dst_y =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_y.obj()));
-  uint8_t* dst_u =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_u.obj()));
-  uint8_t* dst_v =
-      static_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_v.obj()));
-
-  // Perform cropping using pointer arithmetic.
-  src_y += crop_x + crop_y * src_stride_y;
-  src_u += crop_x / 2 + crop_y / 2 * src_stride_u;
-  src_v += crop_x / 2 + crop_y / 2 * src_stride_v;
-
-  bool ret = libyuv::I420Scale(
-      src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v, crop_width,
-      crop_height, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,
-      dst_stride_v, scale_width, scale_height, libyuv::kFilterBox);
-  RTC_DCHECK_EQ(ret, 0) << "I420Scale failed";
-}
-
 }  // namespace jni
 }  // namespace webrtc