Android: Add functionality for wrapping C++ I420 buffers to Java

This functionality is needed when sending C++ I420 buffers to Java
VideoSinks or Java encoders.

Bug: webrtc:7749
Change-Id: Ied783470b90b9d2e0cb5930795f35de4a296d499
Reviewed-on: https://chromium-review.googlesource.com/532961
Commit-Queue: Magnus Jedvert <magjed@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#18597}
This commit is contained in:
Magnus Jedvert
2017-06-14 19:03:31 +02:00
committed by Commit Bot
parent cca0f6cc68
commit 62faaabce9
5 changed files with 191 additions and 0 deletions

View File

@ -46,6 +46,8 @@ rtc_static_library("libjingle_peerconnection_jni") {
"src/jni/rtcstatscollectorcallbackwrapper.h", "src/jni/rtcstatscollectorcallbackwrapper.h",
"src/jni/surfacetexturehelper_jni.cc", "src/jni/surfacetexturehelper_jni.cc",
"src/jni/surfacetexturehelper_jni.h", "src/jni/surfacetexturehelper_jni.h",
"src/jni/wrapped_native_i420_buffer.cc",
"src/jni/wrapped_native_i420_buffer.h",
] ]
configs += [ ":libjingle_peerconnection_jni_warnings_config" ] configs += [ ":libjingle_peerconnection_jni_warnings_config" ]
@ -214,6 +216,7 @@ android_library("libjingle_peerconnection_java") {
"src/java/org/webrtc/FramerateBitrateAdjuster.java", "src/java/org/webrtc/FramerateBitrateAdjuster.java",
"src/java/org/webrtc/HardwareVideoEncoder.java", "src/java/org/webrtc/HardwareVideoEncoder.java",
"src/java/org/webrtc/Histogram.java", "src/java/org/webrtc/Histogram.java",
"src/java/org/webrtc/WrappedNativeI420Buffer.java",
"src/java/org/webrtc/YuvConverter.java", "src/java/org/webrtc/YuvConverter.java",
] ]

View File

@ -0,0 +1,99 @@
/*
* Copyright 2017 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.
*/
package org.webrtc;
import java.nio.ByteBuffer;
/**
* This class wraps a webrtc::I420BufferInterface into a VideoFrame.I420Buffer.
*/
class WrappedNativeI420Buffer implements VideoFrame.I420Buffer {
private final int width;
private final int height;
private final ByteBuffer dataY;
private final int strideY;
private final ByteBuffer dataU;
private final int strideU;
private final ByteBuffer dataV;
private final int strideV;
private final long nativeBuffer;
WrappedNativeI420Buffer(int width, int height, ByteBuffer dataY, int strideY, ByteBuffer dataU,
int strideU, ByteBuffer dataV, int strideV, long nativeBuffer) {
this.width = width;
this.height = height;
this.dataY = dataY;
this.strideY = strideY;
this.dataU = dataU;
this.strideU = strideU;
this.dataV = dataV;
this.strideV = strideV;
this.nativeBuffer = nativeBuffer;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public ByteBuffer getDataY() {
return dataY;
}
@Override
public ByteBuffer getDataU() {
return dataU;
}
@Override
public ByteBuffer getDataV() {
return dataV;
}
@Override
public int getStrideY() {
return strideY;
}
@Override
public int getStrideU() {
return strideU;
}
@Override
public int getStrideV() {
return strideV;
}
@Override
public VideoFrame.I420Buffer toI420() {
return this;
}
@Override
public void retain() {
nativeAddRef(nativeBuffer);
}
@Override
public void release() {
nativeRelease(nativeBuffer);
}
private static native long nativeAddRef(long nativeBuffer);
private static native long nativeRelease(long nativeBuffer);
}

View File

@ -105,6 +105,7 @@ ClassReferenceHolder::ClassReferenceHolder(JNIEnv* jni) {
LoadClass(jni, "org/webrtc/VideoCapturer"); LoadClass(jni, "org/webrtc/VideoCapturer");
LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame"); LoadClass(jni, "org/webrtc/VideoRenderer$I420Frame");
LoadClass(jni, "org/webrtc/VideoTrack"); LoadClass(jni, "org/webrtc/VideoTrack");
LoadClass(jni, "org/webrtc/WrappedNativeI420Buffer");
} }
ClassReferenceHolder::~ClassReferenceHolder() { ClassReferenceHolder::~ClassReferenceHolder() {

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2017 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 "webrtc/sdk/android/src/jni/wrapped_native_i420_buffer.h"
#include "webrtc/sdk/android/src/jni/classreferenceholder.h"
#include "webrtc/sdk/android/src/jni/jni_helpers.h"
namespace webrtc_jni {
// TODO(magjed): Write a test for this function.
jobject WrapI420Buffer(
const rtc::scoped_refptr<webrtc::I420BufferInterface>& i420_buffer) {
JNIEnv* jni = AttachCurrentThreadIfNeeded();
ScopedLocalRefFrame local_ref_frame(jni);
jclass j_wrapped_native_i420_buffer_class =
FindClass(jni, "org/webrtc/WrappedNativeI420Buffer");
jmethodID j_wrapped_native_i420_buffer_ctor_id =
GetMethodID(jni, j_wrapped_native_i420_buffer_class, "<init>",
"(IILjava/nio/ByteBuffer;ILjava/nio/ByteBuffer;ILjava/nio/"
"ByteBuffer;IJ)V");
jobject y_buffer =
jni->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataY()),
i420_buffer->StrideY() * i420_buffer->height());
jobject u_buffer = jni->NewDirectByteBuffer(
const_cast<uint8_t*>(i420_buffer->DataU()),
i420_buffer->StrideU() * i420_buffer->ChromaHeight());
jobject v_buffer = jni->NewDirectByteBuffer(
const_cast<uint8_t*>(i420_buffer->DataV()),
i420_buffer->StrideV() * i420_buffer->ChromaHeight());
jobject j_wrapped_native_i420_buffer = jni->NewObject(
j_wrapped_native_i420_buffer_class, j_wrapped_native_i420_buffer_ctor_id,
i420_buffer->width(), i420_buffer->height(), y_buffer,
i420_buffer->StrideY(), u_buffer, i420_buffer->StrideU(), v_buffer,
i420_buffer->StrideV(), jlongFromPointer(i420_buffer.get()));
CHECK_EXCEPTION(jni);
return j_wrapped_native_i420_buffer;
}
JOW(void, WrappedNativeI420Buffer_nativeAddRef)
(JNIEnv* jni, jclass, jlong j_buffer_pointer) {
reinterpret_cast<webrtc::VideoFrameBuffer*>(j_buffer_pointer)->AddRef();
}
JOW(void, WrappedNativeI420Buffer_nativeRelease)
(JNIEnv* jni, jclass, jlong j_buffer_pointer) {
reinterpret_cast<webrtc::VideoFrameBuffer*>(j_buffer_pointer)->Release();
}
} // namespace webrtc_jni

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2017 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.
*/
#ifndef WEBRTC_SDK_ANDROID_SRC_JNI_WRAPPED_NATIVE_I420_BUFFER_H_
#define WEBRTC_SDK_ANDROID_SRC_JNI_WRAPPED_NATIVE_I420_BUFFER_H_
#include <jni.h>
#include "webrtc/api/video/video_frame_buffer.h"
namespace webrtc_jni {
// This function wraps the C++ I420 buffer and returns a Java
// VideoFrame.I420Buffer as a jobject.
jobject WrapI420Buffer(
const rtc::scoped_refptr<webrtc::I420BufferInterface>& i420_buffer);
} // namespace webrtc_jni
#endif // WEBRTC_SDK_ANDROID_SRC_JNI_WRAPPED_NATIVE_I420_BUFFER_H_