Implement AndroidVideoBuffer::ToI420.
BUG=webrtc:7749, webrtc:7760 Review-Url: https://codereview.webrtc.org/2991633002 Cr-Commit-Position: refs/heads/master@{#19284}
This commit is contained in:
parent
e9a40732f5
commit
5ca60cc91c
@ -110,6 +110,7 @@ class I420BufferImpl implements VideoFrame.I420Buffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public I420Buffer toI420() {
|
public I420Buffer toI420() {
|
||||||
|
retain();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,7 @@ class WrappedNativeI420Buffer implements VideoFrame.I420Buffer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VideoFrame.I420Buffer toI420() {
|
public VideoFrame.I420Buffer toI420() {
|
||||||
|
retain();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,132 @@
|
|||||||
|
|
||||||
namespace webrtc_jni {
|
namespace webrtc_jni {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class AndroidVideoI420Buffer : public webrtc::I420BufferInterface {
|
||||||
|
public:
|
||||||
|
// Wraps an existing reference to a Java VideoBuffer. Retain will not be
|
||||||
|
// called but release will be called when the C++ object is destroyed.
|
||||||
|
static rtc::scoped_refptr<AndroidVideoI420Buffer> WrapReference(
|
||||||
|
JNIEnv* jni,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
AndroidVideoI420Buffer(JNIEnv* jni,
|
||||||
|
jmethodID j_retain_id,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer);
|
||||||
|
// Should not be called directly. Wraps a reference. Use
|
||||||
|
// AndroidVideoI420Buffer::WrapReference instead for clarity.
|
||||||
|
AndroidVideoI420Buffer(JNIEnv* jni,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer);
|
||||||
|
~AndroidVideoI420Buffer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
const uint8_t* DataY() const override { return data_y_; }
|
||||||
|
const uint8_t* DataU() const override { return data_u_; }
|
||||||
|
const uint8_t* DataV() const override { return data_v_; }
|
||||||
|
|
||||||
|
int StrideY() const override { return stride_y_; }
|
||||||
|
int StrideU() const override { return stride_u_; }
|
||||||
|
int StrideV() const override { return stride_v_; }
|
||||||
|
|
||||||
|
int width() const override { return width_; }
|
||||||
|
int height() const override { return height_; }
|
||||||
|
|
||||||
|
const jmethodID j_release_id_;
|
||||||
|
const int width_;
|
||||||
|
const int height_;
|
||||||
|
// Holds a VideoFrame.I420Buffer.
|
||||||
|
const ScopedGlobalRef<jobject> j_video_frame_buffer_;
|
||||||
|
|
||||||
|
const uint8_t* data_y_;
|
||||||
|
const uint8_t* data_u_;
|
||||||
|
const uint8_t* data_v_;
|
||||||
|
int stride_y_;
|
||||||
|
int stride_u_;
|
||||||
|
int stride_v_;
|
||||||
|
};
|
||||||
|
|
||||||
|
rtc::scoped_refptr<AndroidVideoI420Buffer>
|
||||||
|
AndroidVideoI420Buffer::WrapReference(JNIEnv* jni,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer) {
|
||||||
|
return new rtc::RefCountedObject<AndroidVideoI420Buffer>(
|
||||||
|
jni, j_release_id, width, height, j_video_frame_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni,
|
||||||
|
jmethodID j_retain_id,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer)
|
||||||
|
: AndroidVideoI420Buffer(jni,
|
||||||
|
j_release_id,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
j_video_frame_buffer) {
|
||||||
|
jni->CallVoidMethod(j_video_frame_buffer, j_retain_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni,
|
||||||
|
jmethodID j_release_id,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
jobject j_video_frame_buffer)
|
||||||
|
: j_release_id_(j_release_id),
|
||||||
|
width_(width),
|
||||||
|
height_(height),
|
||||||
|
j_video_frame_buffer_(jni, j_video_frame_buffer) {
|
||||||
|
jclass j_video_frame_i420_buffer_class =
|
||||||
|
FindClass(jni, "org/webrtc/VideoFrame$I420Buffer");
|
||||||
|
jmethodID j_get_data_y_id = jni->GetMethodID(
|
||||||
|
j_video_frame_i420_buffer_class, "getDataY", "()Ljava/nio/ByteBuffer;");
|
||||||
|
jmethodID j_get_data_u_id = jni->GetMethodID(
|
||||||
|
j_video_frame_i420_buffer_class, "getDataU", "()Ljava/nio/ByteBuffer;");
|
||||||
|
jmethodID j_get_data_v_id = jni->GetMethodID(
|
||||||
|
j_video_frame_i420_buffer_class, "getDataV", "()Ljava/nio/ByteBuffer;");
|
||||||
|
jmethodID j_get_stride_y_id =
|
||||||
|
jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideY", "()I");
|
||||||
|
jmethodID j_get_stride_u_id =
|
||||||
|
jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideU", "()I");
|
||||||
|
jmethodID j_get_stride_v_id =
|
||||||
|
jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideV", "()I");
|
||||||
|
|
||||||
|
jobject j_data_y =
|
||||||
|
jni->CallObjectMethod(j_video_frame_buffer, j_get_data_y_id);
|
||||||
|
jobject j_data_u =
|
||||||
|
jni->CallObjectMethod(j_video_frame_buffer, j_get_data_u_id);
|
||||||
|
jobject j_data_v =
|
||||||
|
jni->CallObjectMethod(j_video_frame_buffer, j_get_data_v_id);
|
||||||
|
|
||||||
|
data_y_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y));
|
||||||
|
data_u_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u));
|
||||||
|
data_v_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v));
|
||||||
|
|
||||||
|
stride_y_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_y_id);
|
||||||
|
stride_u_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_u_id);
|
||||||
|
stride_v_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_v_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidVideoI420Buffer::~AndroidVideoI420Buffer() {
|
||||||
|
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||||
|
jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
Matrix::Matrix(JNIEnv* jni, jfloatArray a) {
|
Matrix::Matrix(JNIEnv* jni, jfloatArray a) {
|
||||||
RTC_CHECK_EQ(16, jni->GetArrayLength(a));
|
RTC_CHECK_EQ(16, jni->GetArrayLength(a));
|
||||||
jfloat* ptr = jni->GetFloatArrayElements(a, nullptr);
|
jfloat* ptr = jni->GetFloatArrayElements(a, nullptr);
|
||||||
@ -231,8 +357,22 @@ int AndroidVideoBuffer::height() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() {
|
rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() {
|
||||||
// TODO(magjed): Implement using Java ToI420.
|
JNIEnv* jni = AttachCurrentThreadIfNeeded();
|
||||||
return nullptr;
|
ScopedLocalRefFrame local_ref_frame(jni);
|
||||||
|
|
||||||
|
jclass j_video_frame_buffer_class =
|
||||||
|
FindClass(jni, "org/webrtc/VideoFrame$Buffer");
|
||||||
|
jmethodID j_to_i420_id =
|
||||||
|
jni->GetMethodID(j_video_frame_buffer_class, "toI420",
|
||||||
|
"()Lorg/webrtc/VideoFrame$I420Buffer;");
|
||||||
|
|
||||||
|
jobject j_i420_buffer =
|
||||||
|
jni->CallObjectMethod(*j_video_frame_buffer_, j_to_i420_id);
|
||||||
|
|
||||||
|
// We don't need to retain the buffer because toI420 returns a new object that
|
||||||
|
// we are assumed to take the ownership of.
|
||||||
|
return AndroidVideoI420Buffer::WrapReference(jni, j_release_id_, width_,
|
||||||
|
height_, j_i420_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni,
|
jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni,
|
||||||
|
|||||||
@ -129,7 +129,7 @@ class AndroidVideoBuffer : public AndroidVideoFrameBuffer {
|
|||||||
const int width_;
|
const int width_;
|
||||||
const int height_;
|
const int height_;
|
||||||
// Holds a VideoFrame.Buffer.
|
// Holds a VideoFrame.Buffer.
|
||||||
ScopedGlobalRef<jobject> j_video_frame_buffer_;
|
const ScopedGlobalRef<jobject> j_video_frame_buffer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AndroidVideoBufferFactory {
|
class AndroidVideoBufferFactory {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user