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

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

Issue 2991633002: Implement AndroidVideoBuffer::ToI420. (Closed)
Patch Set: Cache values. 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
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 webrtc::I420BufferInterface {
31 public:
32 AndroidVideoI420Buffer(JNIEnv* jni,
33 jmethodID j_release_id,
34 const uint8_t* data_y,
35 const uint8_t* data_u,
36 const uint8_t* data_v,
37 int stride_y,
38 int stride_u,
39 int stride_v,
40 int width,
41 int height,
42 jobject j_video_frame_buffer);
43
44 private:
45 const uint8_t* DataY() const override { return data_y_; }
46 const uint8_t* DataU() const override { return data_u_; }
47 const uint8_t* DataV() const override { return data_v_; }
48
49 int StrideY() const override { return stride_y_; }
50 int StrideU() const override { return stride_u_; }
51 int StrideV() const override { return stride_v_; }
52
53 int width() const override { return android_video_buffer->width(); }
54 int height() const override { return android_video_buffer->height(); }
55
56 rtc::scoped_refptr<AndroidVideoBuffer> android_video_buffer;
57 const uint8_t* data_y_;
58 const uint8_t* data_u_;
59 const uint8_t* data_v_;
60 const int stride_y_;
61 const int stride_u_;
62 const int stride_v_;
63 };
64
65 AndroidVideoI420Buffer::AndroidVideoI420Buffer(JNIEnv* jni,
66 jmethodID j_release_id,
67 const uint8_t* data_y,
68 const uint8_t* data_u,
69 const uint8_t* data_v,
70 int stride_y,
71 int stride_u,
72 int stride_v,
73 int width,
74 int height,
75 jobject j_video_frame_buffer)
76 : android_video_buffer(
77 new rtc::RefCountedObject<AndroidVideoBuffer>(jni,
magjed_webrtc 2017/07/28 09:45:04 I think it's clearer to duplicate the code you nee
78 j_release_id,
79 width,
80 height,
81 j_video_frame_buffer)),
82 data_y_(data_y),
83 data_u_(data_u),
84 data_v_(data_v),
85 stride_y_(stride_y),
86 stride_u_(stride_u),
87 stride_v_(stride_v) {}
88
89 } // namespace
90
28 Matrix::Matrix(JNIEnv* jni, jfloatArray a) { 91 Matrix::Matrix(JNIEnv* jni, jfloatArray a) {
29 RTC_CHECK_EQ(16, jni->GetArrayLength(a)); 92 RTC_CHECK_EQ(16, jni->GetArrayLength(a));
30 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr); 93 jfloat* ptr = jni->GetFloatArrayElements(a, nullptr);
31 for (int i = 0; i < 16; ++i) { 94 for (int i = 0; i < 16; ++i) {
32 elem_[i] = ptr[i]; 95 elem_[i] = ptr[i];
33 } 96 }
34 jni->ReleaseFloatArrayElements(a, ptr, 0); 97 jni->ReleaseFloatArrayElements(a, ptr, 0);
35 } 98 }
36 99
37 jfloatArray Matrix::ToJava(JNIEnv* jni) const { 100 jfloatArray Matrix::ToJava(JNIEnv* jni) const {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 jni->CallVoidMethod(surface_texture_helper_, 253 jni->CallVoidMethod(surface_texture_helper_,
191 transform_mid, 254 transform_mid,
192 byte_buffer, width(), height(), stride, 255 byte_buffer, width(), height(), stride,
193 native_handle_.oes_texture_id, sampling_matrix); 256 native_handle_.oes_texture_id, sampling_matrix);
194 CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception"; 257 CHECK_EXCEPTION(jni) << "textureToYUV throwed an exception";
195 258
196 return copy; 259 return copy;
197 } 260 }
198 261
199 AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni, 262 AndroidVideoBuffer::AndroidVideoBuffer(JNIEnv* jni,
200 jmethodID j_retain_id,
magjed_webrtc 2017/07/28 09:45:05 Revert this change in this CL.
sakal 2017/07/28 11:08:49 Done.
201 jmethodID j_release_id, 263 jmethodID j_release_id,
202 int width, 264 int width,
203 int height, 265 int height,
204 jobject j_video_frame_buffer) 266 jobject j_video_frame_buffer)
205 : j_release_id_(j_release_id), 267 : j_release_id_(j_release_id),
206 width_(width), 268 width_(width),
207 height_(height), 269 height_(height),
208 j_video_frame_buffer_(jni, j_video_frame_buffer) { 270 j_video_frame_buffer_(jni, j_video_frame_buffer) {}
209 jni->CallVoidMethod(j_video_frame_buffer, j_retain_id);
210 }
211 271
212 AndroidVideoBuffer::~AndroidVideoBuffer() { 272 AndroidVideoBuffer::~AndroidVideoBuffer() {
213 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 273 JNIEnv* jni = AttachCurrentThreadIfNeeded();
214 jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_); 274 jni->CallVoidMethod(*j_video_frame_buffer_, j_release_id_);
215 } 275 }
216 276
217 jobject AndroidVideoBuffer::video_frame_buffer() const { 277 jobject AndroidVideoBuffer::video_frame_buffer() const {
218 return *j_video_frame_buffer_; 278 return *j_video_frame_buffer_;
219 } 279 }
220 280
221 webrtc::VideoFrameBuffer::Type AndroidVideoBuffer::type() const { 281 webrtc::VideoFrameBuffer::Type AndroidVideoBuffer::type() const {
222 return Type::kNative; 282 return Type::kNative;
223 } 283 }
224 284
225 int AndroidVideoBuffer::width() const { 285 int AndroidVideoBuffer::width() const {
226 return width_; 286 return width_;
227 } 287 }
228 288
229 int AndroidVideoBuffer::height() const { 289 int AndroidVideoBuffer::height() const {
230 return height_; 290 return height_;
231 } 291 }
232 292
233 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() { 293 rtc::scoped_refptr<webrtc::I420BufferInterface> AndroidVideoBuffer::ToI420() {
234 // TODO(magjed): Implement using Java ToI420. 294 JNIEnv* jni = AttachCurrentThreadIfNeeded();
235 return nullptr; 295 ScopedLocalRefFrame local_ref_frame(jni);
296
297 jclass j_video_frame_buffer_class =
298 FindClass(jni, "org/webrtc/VideoFrame$Buffer");
299 jmethodID j_to_i420_id =
300 jni->GetMethodID(j_video_frame_buffer_class, "toI420",
301 "()Lorg/webrtc/VideoFrame$I420Buffer;");
302
303 jclass j_video_frame_i420_buffer_class =
304 FindClass(jni, "org/webrtc/VideoFrame$I420Buffer");
305 jmethodID j_get_data_y_id = jni->GetMethodID(
306 j_video_frame_i420_buffer_class, "getDataY", "()Ljava/nio/ByteBuffer;");
307 jmethodID j_get_data_u_id = jni->GetMethodID(
308 j_video_frame_i420_buffer_class, "getDataU", "()Ljava/nio/ByteBuffer;");
309 jmethodID j_get_data_v_id = jni->GetMethodID(
310 j_video_frame_i420_buffer_class, "getDataV", "()Ljava/nio/ByteBuffer;");
311 jmethodID j_get_stride_y_id =
312 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideY", "()I");
313 jmethodID j_get_stride_u_id =
314 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideU", "()I");
315 jmethodID j_get_stride_v_id =
316 jni->GetMethodID(j_video_frame_i420_buffer_class, "getStrideV", "()I");
317
318 jobject j_i420_buffer =
319 jni->CallObjectMethod(*j_video_frame_buffer_, j_to_i420_id);
magjed_webrtc 2017/07/28 09:45:05 How about extracting j_i420_buffer here and passin
sakal 2017/07/28 11:08:49 Done.
320
321 jobject j_data_y = jni->CallObjectMethod(j_i420_buffer, j_get_data_y_id);
322 jobject j_data_u = jni->CallObjectMethod(j_i420_buffer, j_get_data_u_id);
323 jobject j_data_v = jni->CallObjectMethod(j_i420_buffer, j_get_data_v_id);
324
325 const uint8_t* data_y =
326 static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_y));
327 const uint8_t* data_u =
328 static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_u));
329 const uint8_t* data_v =
330 static_cast<const uint8_t*>(jni->GetDirectBufferAddress(j_data_v));
331
332 int stride_y = jni->CallIntMethod(j_i420_buffer, j_get_stride_y_id);
333 int stride_u = jni->CallIntMethod(j_i420_buffer, j_get_stride_u_id);
334 int stride_v = jni->CallIntMethod(j_i420_buffer, j_get_stride_v_id);
335
336 return new rtc::RefCountedObject<AndroidVideoI420Buffer>(
337 jni, j_release_id_, data_y, data_u, data_v, stride_y, stride_u, stride_v,
338 width_, height_, j_i420_buffer);
236 } 339 }
237 340
238 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni, 341 jobject AndroidVideoBuffer::ToJavaI420Frame(JNIEnv* jni,
239 int rotation) { 342 int rotation) {
240 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer"); 343 jclass j_byte_buffer_class = jni->FindClass("java/nio/ByteBuffer");
241 jclass j_i420_frame_class = 344 jclass j_i420_frame_class =
242 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame"); 345 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame");
243 jmethodID j_i420_frame_ctor_id = GetMethodID( 346 jmethodID j_i420_frame_ctor_id = GetMethodID(
244 jni, j_i420_frame_class, "<init>", "(ILorg/webrtc/VideoFrame$Buffer;J)V"); 347 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 348 // 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
285 rtc::scoped_refptr<AndroidVideoBuffer> buffer = 388 rtc::scoped_refptr<AndroidVideoBuffer> buffer =
286 CreateBuffer(j_video_frame_buffer); 389 CreateBuffer(j_video_frame_buffer);
287 return webrtc::VideoFrame(buffer, timestamp_rtp, 390 return webrtc::VideoFrame(buffer, timestamp_rtp,
288 timestamp_ns / rtc::kNumNanosecsPerMillisec, 391 timestamp_ns / rtc::kNumNanosecsPerMillisec,
289 static_cast<webrtc::VideoRotation>(rotation)); 392 static_cast<webrtc::VideoRotation>(rotation));
290 } 393 }
291 394
292 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer( 395 rtc::scoped_refptr<AndroidVideoBuffer> AndroidVideoBufferFactory::CreateBuffer(
293 jobject j_video_frame_buffer) const { 396 jobject j_video_frame_buffer) const {
294 JNIEnv* jni = AttachCurrentThreadIfNeeded(); 397 JNIEnv* jni = AttachCurrentThreadIfNeeded();
398 jni->CallVoidMethod(j_video_frame_buffer, j_retain_id_);
295 int width = jni->CallIntMethod(j_video_frame_buffer, j_get_width_id_); 399 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_); 400 int height = jni->CallIntMethod(j_video_frame_buffer, j_get_height_id_);
297 return new rtc::RefCountedObject<AndroidVideoBuffer>( 401 return new rtc::RefCountedObject<AndroidVideoBuffer>(
298 jni, j_retain_id_, j_release_id_, width, height, j_video_frame_buffer); 402 jni, j_release_id_, width, height, j_video_frame_buffer);
299 } 403 }
300 404
301 } // namespace webrtc_jni 405 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698