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:
committed by
Commit Bot
parent
cca0f6cc68
commit
62faaabce9
@ -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",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
@ -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() {
|
||||||
|
|||||||
61
webrtc/sdk/android/src/jni/wrapped_native_i420_buffer.cc
Normal file
61
webrtc/sdk/android/src/jni/wrapped_native_i420_buffer.cc
Normal 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
|
||||||
27
webrtc/sdk/android/src/jni/wrapped_native_i420_buffer.h
Normal file
27
webrtc/sdk/android/src/jni/wrapped_native_i420_buffer.h
Normal 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_
|
||||||
Reference in New Issue
Block a user