OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2015 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" | 11 #include "webrtc/sdk/android/src/jni/native_handle_impl.h" |
12 | 12 |
13 #include <memory> | 13 #include <memory> |
14 | 14 |
15 #include "webrtc/common_video/include/video_frame_buffer.h" | 15 #include "webrtc/common_video/include/video_frame_buffer.h" |
16 #include "webrtc/rtc_base/bind.h" | 16 #include "webrtc/rtc_base/bind.h" |
17 #include "webrtc/rtc_base/checks.h" | 17 #include "webrtc/rtc_base/checks.h" |
18 #include "webrtc/rtc_base/keep_ref_until_done.h" | 18 #include "webrtc/rtc_base/keep_ref_until_done.h" |
19 #include "webrtc/rtc_base/logging.h" | 19 #include "webrtc/rtc_base/logging.h" |
20 #include "webrtc/rtc_base/scoped_ref_ptr.h" | 20 #include "webrtc/rtc_base/scoped_ref_ptr.h" |
21 #include "webrtc/rtc_base/timeutils.h" | 21 #include "webrtc/rtc_base/timeutils.h" |
22 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" | 22 #include "webrtc/sdk/android/src/jni/classreferenceholder.h" |
23 #include "webrtc/sdk/android/src/jni/jni_helpers.h" | 23 #include "webrtc/sdk/android/src/jni/jni_helpers.h" |
24 #include "webrtc/system_wrappers/include/aligned_malloc.h" | 24 #include "webrtc/system_wrappers/include/aligned_malloc.h" |
25 | 25 |
26 namespace webrtc_jni { | 26 namespace webrtc_jni { |
27 | 27 |
28 namespace { | |
29 | |
30 class AndroidVideoI420Buffer : public webrtc::I420BufferInterface { | |
31 public: | |
32 AndroidVideoI420Buffer(JNIEnv* jni, | |
33 jmethodID j_release_id, | |
34 int width, | |
35 int height, | |
36 jobject j_video_frame_buffer); | |
37 ~AndroidVideoI420Buffer(); | |
38 | |
39 private: | |
40 const uint8_t* DataY() const override { return data_y_; } | |
41 const uint8_t* DataU() const override { return data_u_; } | |
42 const uint8_t* DataV() const override { return data_v_; } | |
43 | |
44 int StrideY() const override { return stride_y_; } | |
45 int StrideU() const override { return stride_u_; } | |
46 int StrideV() const override { return stride_v_; } | |
47 | |
48 int width() const override { return width_; } | |
49 int height() const override { return height_; } | |
50 | |
51 const jmethodID j_release_id_; | |
52 const int width_; | |
53 const int height_; | |
54 // Holds a VideoFrame.I420Buffer. | |
55 const ScopedGlobalRef<jobject> j_video_frame_buffer_; | |
56 | |
57 const uint8_t* data_y_; | |
58 const uint8_t* data_u_; | |
59 const uint8_t* data_v_; | |
60 int stride_y_; | |
61 int stride_u_; | |
62 int stride_v_; | |
63 }; | |
64 | |
65 AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni, | |
66 jmethodID j_release_id, | |
67 int width, | |
68 int height, | |
69 jobject j_video_frame_buffer) | |
70 : j_release_id_(j_release_id), | |
71 width_(width), | |
72 height_(height), | |
73 j_video_frame_buffer_(jni, j_video_frame_buffer) { | |
74 jclass j_video_frame_i420_buffer_class = | |
75 FindClass(jni, "org/webrtc/VideoFrame$I420Buffer"); | |
76 jmethodID j_get_data_y_id = jni->GetMethodID( | |
77 j_video_frame_i420_buffer_class, "getDataY", "()Ljava/nio/ByteBuffer;"); | |
78 jmethodID j_get_data_u_id = jni->GetMethodID( | |
79 j_video_frame_i420_buffer_class, "getDataU", "()Ljava/nio/ByteBuffer;"); | |
80 jmethodID j_get_data_v_id = jni->GetMethodID( | |
81 j_video_frame_i420_buffer_class, "getDataV", "()Ljava/nio/ByteBuffer;"); | |
82 jmethodID j_get_stride_y_id = | |
83 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideY", "()I"); | |
84 jmethodID j_get_stride_u_id = | |
85 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideU", "()I"); | |
86 jmethodID j_get_stride_v_id = | |
87 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideV", "()I"); | |
88 | |
89 jobject j_data_y = | |
90 jni->CallObjectMethod(j_video_frame_buffer, j_get_data_y_id); | |
91 jobject j_data_u = | |
92 jni->CallObjectMethod(j_video_frame_buffer, j_get_data_u_id); | |
93 jobject j_data_v = | |
94 jni->CallObjectMethod(j_video_frame_buffer, j_get_data_v_id); | |
95 | |
96 data_y_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y)); | |
97 data_u_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u)); | |
98 data_v_ = static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v)); | |
99 | |
100 stride_y_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_y_id); | |
101 stride_u_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_u_id); | |
102 stride_v_ = jni->CallIntMethod(j_video_frame_buffer, j_get_stride_v_id); | |
103 } | |
104 | |
105 AndroidVideoI420Buffer::~AndroidVideoI420Buffer() { | |
106 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | |
107 jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_); | |
108 } | |
109 | |
110 } // namespace | |
111 | |
28 Matrix::Matrix(JNIEnv* jni, jfloatArray a) { | 112 Matrix::Matrix(JNIEnv* jni, jfloatArray a) { |
29 RTC_CHECK_EQ(16, jni->GetArrayLength(a)); | 113 RTC_CHECK_EQ(16, jni->GetArrayLength(a)); |
30 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); | 114 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); |
31 for (int i = 0; i < 16; ++i) { | 115 for (int i = 0; i < 16; ++i) { |
32 elem_[i] = ptr[i]; | 116 elem_[i] = ptr[i]; |
33 } | 117 } |
34 jni->ReleaseFloatArrayElements(a, ptr, 0); | 118 jni->ReleaseFloatArrayElements(a, ptr, 0); |
35 } | 119 } |
36 | 120 |
37 jfloatArray Matrix::ToJava(JNIEnv* jni) const { | 121 jfloatArray Matrix::ToJava(JNIEnv* jni) const { |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
224 | 308 |
225 int AndroidVideoBuffer::width() const { | 309 int AndroidVideoBuffer::width() const { |
226 return width_; | 310 return width_; |
227 } | 311 } |
228 | 312 |
229 int AndroidVideoBuffer::height() const { | 313 int AndroidVideoBuffer::height() const { |
230 return height_; | 314 return height_; |
231 } | 315 } |
232 | 316 |
233 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() { | 317 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() { |
234 // TODO(magjed): Implement using Java ToI420. | 318 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
235 return nullptr; | 319 ScopedLocalRefFrame local_ref_frame(jni); |
320 | |
321 jclass j_video_frame_buffer_class = | |
322 FindClass(jni, "org/webrtc/VideoFrame$Buffer"); | |
323 jmethodID j_to_i420_id = | |
324 jni->GetMethodID(j_video_frame_buffer_class, "toI420", | |
325 "()Lorg/webrtc/VideoFrame$I420Buffer;"); | |
326 | |
327 jobject j_i420_buffer = | |
328 jni->CallObjectMethod(*j_video_frame_buffer_, j_to_i420_id); | |
magjed_webrtc
2017/08/01 12:31:42
I'm still worried about the asymmetry between wher
sakal
2017/08/09 11:07:29
I don't like having this in the constructor becaus
| |
329 | |
330 return new rtc::RefCountedObject<AndroidVideoI420Buffer>( | |
331 jni, j_release_id_, width_, height_, j_i420_buffer); | |
236 } | 332 } |
237 | 333 |
238 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, | 334 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, |
239 int rotation) { | 335 int rotation) { |
240 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer"); | 336 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer"); |
241 jclass j_i420_frame_class = | 337 jclass j_i420_frame_class = |
242 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame"); | 338 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame"); |
243 jmethodID j_i420_frame_ctor_id = GetMethodID( | 339 jmethodID j_i420_frame_ctor_id = GetMethodID( |
244 jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V"); | 340 jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V"); |
245 // Java code just uses the native frame to hold a reference to the buffer so | 341 // Java code just uses the native frame to hold a reference to the buffer so |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer( | 388 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer( |
293 jobject j_video_frame_buffer) const { | 389 jobject j_video_frame_buffer) const { |
294 JNIEnv* jni = AttachCurrentThreadIfNeeded(); | 390 JNIEnv* jni = AttachCurrentThreadIfNeeded(); |
295 int width = jni->CallIntMethod(j_video_frame_buffer, j_get_width_id_); | 391 int width = jni->CallIntMethod(j_video_frame_buffer, j_get_width_id_); |
296 int height = jni->CallIntMethod(j_video_frame_buffer, j_get_height_id_); | 392 int height = jni->CallIntMethod(j_video_frame_buffer, j_get_height_id_); |
297 return new rtc::RefCountedObject<AndroidVideoBuffer>( | 393 return new rtc::RefCountedObject<AndroidVideoBuffer>( |
298 jni, j_retain_id_, j_release_id_, width, height, j_video_frame_buffer); | 394 jni, j_retain_id_, j_release_id_, width, height, j_video_frame_buffer); |
299 } | 395 } |
300 | 396 |
301 } // namespace webrtc_jni | 397 } // namespace webrtc_jni |
OLD | NEW |