| Index: webrtc/api/android/jni/peerconnection_jni.cc
 | 
| diff --git a/webrtc/api/android/jni/peerconnection_jni.cc b/webrtc/api/android/jni/peerconnection_jni.cc
 | 
| index 0762f80efbd243e43cdb9babd0f0193c5c896649..a552e4c18ae970ecccf59b5acd0e98179ead6e23 100644
 | 
| --- a/webrtc/api/android/jni/peerconnection_jni.cc
 | 
| +++ b/webrtc/api/android/jni/peerconnection_jni.cc
 | 
| @@ -43,6 +43,8 @@
 | 
|  #include <memory>
 | 
|  #include <utility>
 | 
|  
 | 
| +#include "third_party/libyuv/include/libyuv/convert_from.h"
 | 
| +#include "third_party/libyuv/include/libyuv/scale.h"
 | 
|  #include "webrtc/api/androidvideotracksource.h"
 | 
|  #include "webrtc/api/android/jni/androidmediadecoder_jni.h"
 | 
|  #include "webrtc/api/android/jni/androidmediaencoder_jni.h"
 | 
| @@ -2003,6 +2005,77 @@ JOW(void, VideoRenderer_nativeCopyPlane)(
 | 
|    }
 | 
|  }
 | 
|  
 | 
| +JOW(void, FileVideoCapturer_nativeI420ToNV21)(
 | 
| +    JNIEnv *jni, jclass, jbyteArray j_src_buffer, jint width, jint height,
 | 
| +    jbyteArray j_dst_buffer) {
 | 
| +  size_t src_size = jni->GetArrayLength(j_src_buffer);
 | 
| +  size_t dst_size = jni->GetArrayLength(j_dst_buffer);
 | 
| +  int src_stride = width;
 | 
| +  int dst_stride = width;
 | 
| +  RTC_CHECK_GE(src_size, src_stride * height * 3 / 2);
 | 
| +  RTC_CHECK_GE(dst_size, dst_stride * height * 3 / 2);
 | 
| +  uint8_t* src =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetByteArrayElements(j_src_buffer, 0));
 | 
| +  uint8_t* dst =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetByteArrayElements(j_dst_buffer, 0));
 | 
| +  uint8_t* src_y = src;
 | 
| +  size_t src_stride_y = src_stride;
 | 
| +  uint8_t* src_u = src + src_stride * height;
 | 
| +  size_t src_stride_u = src_stride / 2;
 | 
| +  uint8_t* src_v = src + src_stride * height * 5 / 4;
 | 
| +  size_t src_stride_v = src_stride / 2;
 | 
| +
 | 
| +  uint8_t* dst_y = dst;
 | 
| +  size_t dst_stride_y = dst_stride;
 | 
| +  size_t dst_stride_uv = dst_stride;
 | 
| +  uint8_t* dst_uv = dst + dst_stride * height;
 | 
| +
 | 
| +  libyuv::I420ToNV21(src_y, src_stride_y, src_u, src_stride_u, src_v,
 | 
| +                     src_stride_v, dst_y, dst_stride_y, dst_uv, dst_stride_uv,
 | 
| +                     width, height);
 | 
| +}
 | 
| +
 | 
| +JOW(void, VideoFileRenderer_nativeI420Scale)(
 | 
| +    JNIEnv *jni, jclass,
 | 
| +    jobject j_src_buffer_y, jint j_src_stride_y,
 | 
| +    jobject j_src_buffer_u, jint j_src_stride_u,
 | 
| +    jobject j_src_buffer_v, jint j_src_stride_v,
 | 
| +    jint width, jint height,
 | 
| +    jbyteArray j_dst_buffer, jint dstWidth, jint dstHeight) {
 | 
| +  size_t src_size_y = jni->GetDirectBufferCapacity(j_src_buffer_y);
 | 
| +  size_t src_size_u = jni->GetDirectBufferCapacity(j_src_buffer_u);
 | 
| +  size_t src_size_v = jni->GetDirectBufferCapacity(j_src_buffer_v);
 | 
| +  size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer);
 | 
| +  int dst_stride = dstWidth;
 | 
| +  RTC_CHECK_GE(src_size_y, j_src_stride_y * height);
 | 
| +  RTC_CHECK_GE(src_size_u, j_src_stride_u * height / 4);
 | 
| +  RTC_CHECK_GE(src_size_v, j_src_stride_v * height / 4);
 | 
| +  RTC_CHECK_GE(dst_size, dst_stride * height * 3 / 2);
 | 
| +  uint8_t* src_y =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer_y));
 | 
| +  uint8_t* src_u =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer_u));
 | 
| +  uint8_t* src_v =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer_v));
 | 
| +  uint8_t* dst =
 | 
| +      reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_buffer));
 | 
| +
 | 
| +  uint8_t* dst_y = dst;
 | 
| +  size_t dst_stride_y = dst_stride;
 | 
| +  uint8_t* dst_u = dst + dst_stride * dstHeight;
 | 
| +  size_t dst_stride_u = dst_stride / 2;
 | 
| +  uint8_t* dst_v = dst + dst_stride * dstHeight * 5 / 4;
 | 
| +  size_t dst_stride_v = dst_stride / 2;
 | 
| +
 | 
| +  int ret = libyuv::I420Scale(
 | 
| +      src_y, j_src_stride_y, src_u, j_src_stride_u, src_v, j_src_stride_v,
 | 
| +      width, height, dst_y, dst_stride_y, dst_u, dst_stride_u, dst_v,
 | 
| +      dst_stride_v, dstWidth, dstHeight, libyuv::kFilterBilinear);
 | 
| +  if (ret) {
 | 
| +    LOG(LS_ERROR) << "Error scaling I420 frame: " << ret;
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  JOW(jstring, MediaStreamTrack_nativeId)(JNIEnv* jni, jclass, jlong j_p) {
 | 
|    return JavaStringFromStdString(
 | 
|        jni, reinterpret_cast<MediaStreamTrackInterface*>(j_p)->id());
 | 
| 
 |