Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: webrtc/sdk/android/src/jni/native_handle_impl.cc

Issue 2991633002: Implement AndroidVideoBuffer::ToI420. (Closed)
Patch Set: Rebase on top of remove-matrix. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/sdk/android/src/jni/native_handle_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 AndroidVideoBuffer,
magjed_webrtc 2017/07/27 14:45:01 Don't inherit from AndroidVideoBuffer, because you
sakal 2017/07/28 09:01:10 Done.
31 public webrtc::I420BufferInterface {
32 public:
33 AndroidVideoI420Buffer(JNIEnv* jni,
34 jmethodID j_release_id,
35 jmethodID j_get_width_id,
36 jmethodID j_get_height_id,
37 jmethodID j_get_data_y_id,
38 jmethodID j_get_data_u_id,
39 jmethodID j_get_data_v_id,
40 jmethodID j_get_stride_y_id,
41 jmethodID j_get_stride_u_id,
42 jmethodID j_get_stride_v_id,
43 jobject j_video_frame_buffer);
44
45 private:
46 const uint8_t* DataY() const override;
47 const uint8_t* DataU() const override;
48 const uint8_t* DataV() const override;
49
50 int StrideY() const override;
51 int StrideU() const override;
52 int StrideV() const override;
53
54 using webrtc::I420BufferInterface::type;
55 int width() const override { return AndroidVideoBuffer::width(); }
56 int height() const override { return AndroidVideoBuffer::height(); }
57
58 const jmethodID j_get_data_y_id_;
59 const jmethodID j_get_data_u_id_;
60 const jmethodID j_get_data_v_id_;
61 const jmethodID j_get_stride_y_id_;
62 const jmethodID j_get_stride_u_id_;
63 const jmethodID j_get_stride_v_id_;
64 };
65
66 AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni,
67 jmethodID j_release_id,
68 jmethodID j_get_width_id,
69 jmethodID j_get_height_id,
70 jmethodID j_get_data_y_id,
71 jmethodID j_get_data_u_id,
72 jmethodID j_get_data_v_id,
73 jmethodID j_get_stride_y_id,
74 jmethodID j_get_stride_u_id,
75 jmethodID j_get_stride_v_id,
76 jobject j_video_frame_buffer)
77 : AndroidVideoBuffer(jni,
78 j_release_id,
79 j_get_width_id,
80 j_get_height_id,
81 j_video_frame_buffer),
82 j_get_data_y_id_(j_get_data_y_id),
83 j_get_data_u_id_(j_get_data_u_id),
84 j_get_data_v_id_(j_get_data_v_id),
85 j_get_stride_y_id_(j_get_stride_y_id),
86 j_get_stride_u_id_(j_get_stride_u_id),
87 j_get_stride_v_id_(j_get_stride_v_id) {}
88
89 const uint8_t* AndroidVideoI420Buffer::DataY() const {
90 JNIEnv* jni = AttachCurrentThreadIfNeeded();
91 ScopedLocalRefFrame local_ref_frame(jni);
92 jobject j_data_y =
93 jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_y_id_);
94 return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y));
95 }
96
97 const uint8_t* AndroidVideoI420Buffer::DataU() const {
98 JNIEnv* jni = AttachCurrentThreadIfNeeded();
99 ScopedLocalRefFrame local_ref_frame(jni);
100 jobject j_data_u =
101 jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_u_id_);
102 return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u));
103 }
104
105 const uint8_t* AndroidVideoI420Buffer::DataV() const {
106 JNIEnv* jni = AttachCurrentThreadIfNeeded();
107 ScopedLocalRefFrame local_ref_frame(jni);
108 jobject j_data_v =
109 jni->CallObjectMethod(*j_video_frame_buffer_, j_get_data_v_id_);
110 return static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v));
111 }
112
113 int AndroidVideoI420Buffer::StrideY() const {
114 JNIEnv* jni = AttachCurrentThreadIfNeeded();
115 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_y_id_);
116 }
117
118 int AndroidVideoI420Buffer::StrideU() const {
119 JNIEnv* jni = AttachCurrentThreadIfNeeded();
120 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_u_id_);
121 }
122
123 int AndroidVideoI420Buffer::StrideV() const {
124 JNIEnv* jni = AttachCurrentThreadIfNeeded();
125 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_stride_v_id_);
126 }
127
128 } // namespace
129
28 Matrix::Matrix(JNIEnv* jni, jfloatArray a) { 130 Matrix::Matrix(JNIEnv* jni, jfloatArray a) {
29 RTC_CHECK_EQ(16, jni->GetArrayLength(a)); 131 RTC_CHECK_EQ(16, jni->GetArrayLength(a));
30 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); 132 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr);
31 for (int i = 0; i < 16; ++i) { 133 for (int i = 0; i < 16; ++i) {
32 elem_[i] = ptr[i]; 134 elem_[i] = ptr[i];
33 } 135 }
34 jni->ReleaseFloatArrayElements(a, ptr, 0); 136 jni->ReleaseFloatArrayElements(a, ptr, 0);
35 } 137 }
36 138
37 jfloatArray Matrix::ToJava(JNIEnv* jni) const { 139 jfloatArray Matrix::ToJava(JNIEnv* jni) const {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 jni->CallVoidMethod(surface_texture_helper_, 292 jni->CallVoidMethod(surface_texture_helper_,
191 transform_mid, 293 transform_mid,
192 byte_buffer, width(), height(), stride, 294 byte_buffer, width(), height(), stride,
193 native_handle_.oes_texture_id, sampling_matrix); 295 native_handle_.oes_texture_id, sampling_matrix);
194 CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception"; 296 CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception";
195 297
196 return copy; 298 return copy;
197 } 299 }
198 300
199 AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni, 301 AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni,
200 jmethodID j_retain_id,
201 jmethodID j_release_id, 302 jmethodID j_release_id,
202 jmethodID j_get_width_id, 303 jmethodID j_get_width_id,
203 jmethodID j_get_height_id, 304 jmethodID j_get_height_id,
204 jobject j_video_frame_buffer) 305 jobject j_video_frame_buffer)
205 : j_release_id_(j_release_id), 306 : j_video_frame_buffer_(jni, j_video_frame_buffer),
307 j_release_id_(j_release_id),
206 j_get_width_id_(j_get_width_id), 308 j_get_width_id_(j_get_width_id),
207 j_get_height_id_(j_get_height_id), 309 j_get_height_id_(j_get_height_id) {}
208 j_video_frame_buffer_(jni, j_video_frame_buffer) {
209 jni->CallVoidMethod(j_video_frame_buffer, j_retain_id);
210 }
211 310
212 AndroidVideoBuffer::~AndroidVideoBuffer() { 311 AndroidVideoBuffer::~AndroidVideoBuffer() {
213 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 312 JNIEnv* jni = AttachCurrentThreadIfNeeded();
214 jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_); 313 jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_);
215 } 314 }
216 315
217 jobject AndroidVideoBuffer::video_frame_buffer() const { 316 jobject AndroidVideoBuffer::video_frame_buffer() const {
218 return *j_video_frame_buffer_; 317 return *j_video_frame_buffer_;
219 } 318 }
220 319
221 webrtc::VideoFrameBuffer::Type AndroidVideoBuffer::type() const { 320 webrtc::VideoFrameBuffer::Type AndroidVideoBuffer::type() const {
222 return Type::kNative; 321 return Type::kNative;
223 } 322 }
224 323
225 int AndroidVideoBuffer::width() const { 324 int AndroidVideoBuffer::width() const {
226 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 325 JNIEnv* jni = AttachCurrentThreadIfNeeded();
227 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_width_id_); 326 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_width_id_);
228 } 327 }
229 328
230 int AndroidVideoBuffer::height() const { 329 int AndroidVideoBuffer::height() const {
231 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 330 JNIEnv* jni = AttachCurrentThreadIfNeeded();
232 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_height_id_); 331 return jni->CallIntMethod(*j_video_frame_buffer_, j_get_height_id_);
233 } 332 }
234 333
235 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() { 334 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() {
236 // TODO(magjed): Implement using Java ToI420. 335 JNIEnv* jni = AttachCurrentThreadIfNeeded();
237 return nullptr; 336 ScopedLocalRefFrame local_ref_frame(jni);
337
338 jclass j_video_frame_buffer_class =
339 FindClass(jni, "org/webrtc/VideoFrame$Buffer");
340 jmethodID j_to_i420_id =
341 jni->GetMethodID(j_video_frame_buffer_class, "toI420",
342 "()Lorg/webrtc/VideoFrame$I420Buffer;");
343
344 jclass j_video_frame_i420_buffer_class =
345 FindClass(jni, "org/webrtc/VideoFrame$I420Buffer");
346 jmethodID j_get_data_y_id = jni->GetMethodID(
347 j_video_frame_i420_buffer_class, "getDataY", "()Ljava/nio/ByteBuffer;");
348 jmethodID j_get_data_u_id = jni->GetMethodID(
349 j_video_frame_i420_buffer_class, "getDataU", "()Ljava/nio/ByteBuffer;");
350 jmethodID j_get_data_v_id = jni->GetMethodID(
351 j_video_frame_i420_buffer_class, "getDataV", "()Ljava/nio/ByteBuffer;");
352 jmethodID j_get_stride_y_id =
353 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideY", "()I");
354 jmethodID j_get_stride_u_id =
355 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideU", "()I");
356 jmethodID j_get_stride_v_id =
357 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideV", "()I");
358
359 jobject j_i420_buffer =
360 jni->CallObjectMethod(*j_video_frame_buffer_, j_to_i420_id);
361
362 return new rtc::RefCountedObject<AndroidVideoI420Buffer>(
363 jni, j_release_id_, j_get_width_id_, j_get_height_id_, j_get_data_y_id,
364 j_get_data_u_id, j_get_data_v_id, j_get_stride_y_id, j_get_stride_u_id,
365 j_get_stride_v_id, j_i420_buffer);
238 } 366 }
239 367
240 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, 368 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni,
241 int rotation) { 369 int rotation) {
242 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer"); 370 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer");
243 jclass j_i420_frame_class = 371 jclass j_i420_frame_class =
244 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame"); 372 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame");
245 jmethodID j_i420_frame_ctor_id = GetMethodID( 373 jmethodID j_i420_frame_ctor_id = GetMethodID(
246 jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V"); 374 jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V");
247 // Java code just uses the native frame to hold a reference to the buffer so 375 // Java code just uses the native frame to hold a reference to the buffer so
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 rtc::scoped_refptr<AndroidVideoBuffer> buffer = 415 rtc::scoped_refptr<AndroidVideoBuffer> buffer =
288 CreateBuffer(j_video_frame_buffer); 416 CreateBuffer(j_video_frame_buffer);
289 return webrtc::VideoFrame(buffer, timestamp_rtp, 417 return webrtc::VideoFrame(buffer, timestamp_rtp,
290 timestamp_ns / rtc::kNumNanosecsPerMillisec, 418 timestamp_ns / rtc::kNumNanosecsPerMillisec,
291 static_cast<webrtc::VideoRotation>(rotation)); 419 static_cast<webrtc::VideoRotation>(rotation));
292 } 420 }
293 421
294 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer( 422 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer(
295 jobject j_video_frame_buffer) const { 423 jobject j_video_frame_buffer) const {
296 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 424 JNIEnv* jni = AttachCurrentThreadIfNeeded();
425 jni->CallVoidMethod(j_video_frame_buffer, j_retain_id_);
297 return new rtc::RefCountedObject<AndroidVideoBuffer>( 426 return new rtc::RefCountedObject<AndroidVideoBuffer>(
298 jni, j_retain_id_, j_release_id_, j_get_width_id_, j_get_height_id_, 427 jni, j_release_id_, j_get_width_id_, j_get_height_id_,
299 j_video_frame_buffer); 428 j_video_frame_buffer);
300 } 429 }
301 430
302 } // namespace webrtc_jni 431 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « webrtc/sdk/android/src/jni/native_handle_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698