Index: webrtc/sdk/android/src/jni/native_handle_impl.cc |
diff --git a/webrtc/sdk/android/src/jni/native_handle_impl.cc b/webrtc/sdk/android/src/jni/native_handle_impl.cc |
index 6ac65a1066ab3eb2f15ca79f8e2d2f4111fbeea8..edc93e827bc7848f4248e3f26f577e33d5ed0434 100644 |
--- a/webrtc/sdk/android/src/jni/native_handle_impl.cc |
+++ b/webrtc/sdk/android/src/jni/native_handle_impl.cc |
@@ -25,6 +25,108 @@ |
namespace webrtc_jni { |
+namespace { |
+ |
+class AndroidVideoI420Buffer : public AndroidVideoBuffer, |
magjed_webrtc
2017/07/27 14:45:01
Don't inherit from AndroidVideoBuffer, because you
sakal
2017/07/28 09:01:10
Done.
|
+ public webrtc::I420BufferInterface { |
+ public: |
+ AndroidVideoI420Buffer(JNIEnv* jni, |
+ jmethodID j_release_id, |
+ jmethodID j_get_width_id, |
+ jmethodID j_get_height_id, |
+ jmethodID j_get_data_y_id, |
+ jmethodID j_get_data_u_id, |
+ jmethodID j_get_data_v_id, |
+ jmethodID j_get_stride_y_id, |
+ jmethodID j_get_stride_u_id, |
+ jmethodID j_get_stride_v_id, |
+ jobject j_video_frame_buffer); |
+ |
+ private: |
+ const uint8_t* DataY() const override; |
+ const uint8_t* DataU() const override; |
+ const uint8_t* DataV() const override; |
+ |
+ int StrideY() const override; |
+ int StrideU() const override; |
+ int StrideV() const override; |
+ |
+ using webrtc::I420BufferInterface::type; |
+ int width() const override { return AndroidVideoBuffer::width(); } |
+ int height() const override { return AndroidVideoBuffer::height(); } |
+ |
+ const jmethodID j_get_data_y_id_; |
+ const jmethodID j_get_data_u_id_; |
+ const jmethodID j_get_data_v_id_; |
+ const jmethodID j_get_stride_y_id_; |
+ const jmethodID j_get_stride_u_id_; |
+ const jmethodID j_get_stride_v_id_; |
+}; |
+ |
+AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni, |
+ jmethodID j_release_id, |
+ jmethodID j_get_width_id, |
+ jmethodID j_get_height_id, |
+ jmethodID j_get_data_y_id, |
+ jmethodID j_get_data_u_id, |
+ jmethodID j_get_data_v_id, |
+ jmethodID j_get_stride_y_id, |
+ jmethodID j_get_stride_u_id, |
+ jmethodID j_get_stride_v_id, |
+ jobject j_video_frame_buffer) |
+ : AndroidVideoBuffer(jni, |
+ j_release_id, |
+ j_get_width_id, |
+ j_get_height_id, |
+ j_video_frame_buffer), |
+ j_get_data_y_id_(j_get_data_y_id), |
+ j_get_data_u_id_(j_get_data_u_id), |
+ j_get_data_v_id_(j_get_data_v_id), |
+ j_get_stride_y_id_(j_get_stride_y_id), |
+ j_get_stride_u_id_(j_get_stride_u_id), |
+ j_get_stride_v_id_(j_get_stride_v_id) {} |
+ |
+const uint8_t* AndroidVideoI420Buffer::DataY() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ ScopedLocalRefFrame local_ref_frame(jni); |
+ jobject j_data_y = |
+ jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_y_id_); |
+ return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y)); |
+} |
+ |
+const uint8_t* AndroidVideoI420Buffer::DataU() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ ScopedLocalRefFrame local_ref_frame(jni); |
+ jobject j_data_u = |
+ jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_u_id_); |
+ return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u)); |
+} |
+ |
+const uint8_t* AndroidVideoI420Buffer::DataV() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ ScopedLocalRefFrame local_ref_frame(jni); |
+ jobject j_data_v = |
+ jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_v_id_); |
+ return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v)); |
+} |
+ |
+int AndroidVideoI420Buffer::StrideY() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_y_id_); |
+} |
+ |
+int AndroidVideoI420Buffer::StrideU() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_u_id_); |
+} |
+ |
+int AndroidVideoI420Buffer::StrideV() const { |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_v_id_); |
+} |
+ |
+} // namespace |
+ |
Matrix::Matrix(JNIEnv* jni, jfloatArray a) { |
RTC_CHECK_EQ(16, jni->GetArrayLength(a)); |
jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); |
@@ -197,17 +299,14 @@ rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidTextureBuffer::ToI420() { |
} |
AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni, |
- jmethodID j_retain_id, |
jmethodID j_release_id, |
jmethodID j_get_width_id, |
jmethodID j_get_height_id, |
jobject j_video_frame_buffer) |
- : j_release_id_(j_release_id), |
+ : j_video_frame_buffer_(jni, j_video_frame_buffer), |
+ j_release_id_(j_release_id), |
j_get_width_id_(j_get_width_id), |
- j_get_height_id_(j_get_height_id), |
- j_video_frame_buffer_(jni, j_video_frame_buffer) { |
- jni->CallVoidMethod(j_video_frame_buffer, j_retain_id); |
-} |
+ j_get_height_id_(j_get_height_id) {} |
AndroidVideoBuffer::~AndroidVideoBuffer() { |
JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
@@ -233,8 +332,37 @@ int AndroidVideoBuffer::height() const { |
} |
rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() { |
- // TODO(magjed): Implement using Java ToI420. |
- return nullptr; |
+ JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ 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;"); |
+ |
+ 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_i420_buffer = |
+ jni->CallObjectMethod(*j_video_frame_buffer_, j_to_i420_id); |
+ |
+ return new rtc::RefCountedObject<AndroidVideoI420Buffer>( |
+ jni, j_release_id_, j_get_width_id_, j_get_height_id_, j_get_data_y_id, |
+ j_get_data_u_id, j_get_data_v_id, j_get_stride_y_id, j_get_stride_u_id, |
+ j_get_stride_v_id, j_i420_buffer); |
} |
jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, |
@@ -294,8 +422,9 @@ webrtc::VideoFrame AndroidVideoBufferFactory::CreateFrame( |
rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer( |
jobject j_video_frame_buffer) const { |
JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
+ jni->CallVoidMethod(j_video_frame_buffer, j_retain_id_); |
return new rtc::RefCountedObject<AndroidVideoBuffer>( |
- jni, j_retain_id_, j_release_id_, j_get_width_id_, j_get_height_id_, |
+ jni, j_release_id_, j_get_width_id_, j_get_height_id_, |
j_video_frame_buffer); |
} |