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

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

Issue 2854123003: Build WebRTC with data channel only. (Closed)
Patch Set: Fix the issue on the trybots. Created 3 years, 6 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
(Empty)
1 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include <jni.h>
12 #undef JNIEXPORT
13 #define JNIEXPORT __attribute__((visibility("default")))
14
15 #include "webrtc/api/video/video_frame.h"
16 #include "webrtc/media/base/videosinkinterface.h"
17 #include "webrtc/sdk/android/src/jni/classreferenceholder.h"
18 #include "webrtc/sdk/android/src/jni/jni_helpers.h"
19 #include "webrtc/sdk/android/src/jni/native_handle_impl.h"
20
21 namespace webrtc_jni {
22
23 // Wrapper dispatching rtc::VideoSinkInterface to a Java VideoRenderer
24 // instance.
25 class JavaVideoRendererWrapper
26 : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
27 public:
28 JavaVideoRendererWrapper(JNIEnv* jni, jobject j_callbacks)
29 : j_callbacks_(jni, j_callbacks),
30 j_render_frame_id_(
31 GetMethodID(jni,
32 GetObjectClass(jni, j_callbacks),
33 "renderFrame",
34 "(Lorg/webrtc/VideoRenderer$I420Frame;)V")),
35 j_frame_class_(jni,
36 FindClass(jni, "org/webrtc/VideoRenderer$I420Frame")),
37 j_i420_frame_ctor_id_(GetMethodID(jni,
38 *j_frame_class_,
39 "<init>",
40 "(III[I[Ljava/nio/ByteBuffer;J)V")),
41 j_texture_frame_ctor_id_(
42 GetMethodID(jni, *j_frame_class_, "<init>", "(IIII[FJ)V")),
43 j_byte_buffer_class_(jni, FindClass(jni, "java/nio/ByteBuffer")) {
44 CHECK_EXCEPTION(jni);
45 }
46
47 virtual ~JavaVideoRendererWrapper() {}
48
49 void OnFrame(const webrtc::VideoFrame& video_frame) override {
50 ScopedLocalRefFrame local_ref_frame(jni());
51 jobject j_frame =
52 (video_frame.video_frame_buffer()->native_handle() != nullptr)
53 ? CricketToJavaTextureFrame(&video_frame)
54 : CricketToJavaI420Frame(&video_frame);
55 // |j_callbacks_| is responsible for releasing |j_frame| with
56 // VideoRenderer.renderFrameDone().
57 jni()->CallVoidMethod(*j_callbacks_, j_render_frame_id_, j_frame);
58 CHECK_EXCEPTION(jni());
59 }
60
61 private:
62 // Make a shallow copy of |frame| to be used with Java. The callee has
63 // ownership of the frame, and the frame should be released with
64 // VideoRenderer.releaseNativeFrame().
65 static jlong javaShallowCopy(const webrtc::VideoFrame* frame) {
66 return jlongFromPointer(new webrtc::VideoFrame(*frame));
67 }
68
69 // Return a VideoRenderer.I420Frame referring to the data in |frame|.
70 jobject CricketToJavaI420Frame(const webrtc::VideoFrame* frame) {
71 jintArray strides = jni()->NewIntArray(3);
72 jint* strides_array = jni()->GetIntArrayElements(strides, NULL);
73 strides_array[0] = frame->video_frame_buffer()->StrideY();
74 strides_array[1] = frame->video_frame_buffer()->StrideU();
75 strides_array[2] = frame->video_frame_buffer()->StrideV();
76 jni()->ReleaseIntArrayElements(strides, strides_array, 0);
77 jobjectArray planes = jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL);
78 jobject y_buffer = jni()->NewDirectByteBuffer(
79 const_cast<uint8_t*>(frame->video_frame_buffer()->DataY()),
80 frame->video_frame_buffer()->StrideY() *
81 frame->video_frame_buffer()->height());
82 size_t chroma_height = (frame->height() + 1) / 2;
83 jobject u_buffer = jni()->NewDirectByteBuffer(
84 const_cast<uint8_t*>(frame->video_frame_buffer()->DataU()),
85 frame->video_frame_buffer()->StrideU() * chroma_height);
86 jobject v_buffer = jni()->NewDirectByteBuffer(
87 const_cast<uint8_t*>(frame->video_frame_buffer()->DataV()),
88 frame->video_frame_buffer()->StrideV() * chroma_height);
89
90 jni()->SetObjectArrayElement(planes, 0, y_buffer);
91 jni()->SetObjectArrayElement(planes, 1, u_buffer);
92 jni()->SetObjectArrayElement(planes, 2, v_buffer);
93 return jni()->NewObject(*j_frame_class_, j_i420_frame_ctor_id_,
94 frame->width(), frame->height(),
95 static_cast<int>(frame->rotation()), strides,
96 planes, javaShallowCopy(frame));
97 }
98
99 // Return a VideoRenderer.I420Frame referring texture object in |frame|.
100 jobject CricketToJavaTextureFrame(const webrtc::VideoFrame* frame) {
101 NativeHandleImpl* handle = reinterpret_cast<NativeHandleImpl*>(
102 frame->video_frame_buffer()->native_handle());
103 jfloatArray sampling_matrix = handle->sampling_matrix.ToJava(jni());
104
105 return jni()->NewObject(
106 *j_frame_class_, j_texture_frame_ctor_id_, frame->width(),
107 frame->height(), static_cast<int>(frame->rotation()),
108 handle->oes_texture_id, sampling_matrix, javaShallowCopy(frame));
109 }
110
111 JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
112
113 ScopedGlobalRef<jobject> j_callbacks_;
114 jmethodID j_render_frame_id_;
115 ScopedGlobalRef<jclass> j_frame_class_;
116 jmethodID j_i420_frame_ctor_id_;
117 jmethodID j_texture_frame_ctor_id_;
118 ScopedGlobalRef<jclass> j_byte_buffer_class_;
119 };
120
121 JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
122 delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
123 }
124
125 JOW(void, VideoRenderer_releaseNativeFrame)
126 (JNIEnv* jni, jclass, jlong j_frame_ptr) {
127 delete reinterpret_cast<const webrtc::VideoFrame*>(j_frame_ptr);
128 }
129
130 JOW(jlong, VideoRenderer_nativeWrapVideoRenderer)
131 (JNIEnv* jni, jclass, jobject j_callbacks) {
132 std::unique_ptr<JavaVideoRendererWrapper> renderer(
133 new JavaVideoRendererWrapper(jni, j_callbacks));
134 return (jlong)renderer.release();
135 }
136
137 JOW(void, VideoRenderer_nativeCopyPlane)
138 (JNIEnv* jni,
139 jclass,
140 jobject j_src_buffer,
141 jint width,
142 jint height,
143 jint src_stride,
144 jobject j_dst_buffer,
145 jint dst_stride) {
146 size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer);
147 size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer);
148 RTC_CHECK(src_stride >= width) << "Wrong source stride " << src_stride;
149 RTC_CHECK(dst_stride >= width) << "Wrong destination stride " << dst_stride;
150 RTC_CHECK(src_size >= src_stride * height)
151 << "Insufficient source buffer capacity " << src_size;
152 RTC_CHECK(dst_size >= dst_stride * height)
153 << "Insufficient destination buffer capacity " << dst_size;
154 uint8_t* src =
155 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer));
156 uint8_t* dst =
157 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_buffer));
158 if (src_stride == dst_stride) {
159 memcpy(dst, src, src_stride * height);
160 } else {
161 for (int i = 0; i < height; i++) {
162 memcpy(dst, src, width);
163 src += src_stride;
164 dst += dst_stride;
165 }
166 }
167 }
168
169 } // namespace webrtc_jni
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698