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

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

Issue 2854123003: Build WebRTC with data channel only. (Closed)
Patch Set: Rebase. 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 = (video_frame.video_frame_buffer()->type() ==
52 webrtc::VideoFrameBuffer::Type::kNative)
53 ? ToJavaTextureFrame(&video_frame)
54 : ToJavaI420Frame(&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 ToJavaI420Frame(const webrtc::VideoFrame* frame) {
71 jintArray strides = jni()->NewIntArray(3);
72 jint* strides_array = jni()->GetIntArrayElements(strides, NULL);
73 rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer =
74 frame->video_frame_buffer()->ToI420();
75 strides_array[0] = i420_buffer->StrideY();
76 strides_array[1] = i420_buffer->StrideU();
77 strides_array[2] = i420_buffer->StrideV();
78 jni()->ReleaseIntArrayElements(strides, strides_array, 0);
79 jobjectArray planes = jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL);
80 jobject y_buffer = jni()->NewDirectByteBuffer(
81 const_cast<uint8_t*>(i420_buffer->DataY()),
82 i420_buffer->StrideY() * i420_buffer->height());
83 size_t chroma_height = i420_buffer->ChromaHeight();
84 jobject u_buffer =
85 jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataU()),
86 i420_buffer->StrideU() * chroma_height);
87 jobject v_buffer =
88 jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataV()),
89 i420_buffer->StrideV() * chroma_height);
90
91 jni()->SetObjectArrayElement(planes, 0, y_buffer);
92 jni()->SetObjectArrayElement(planes, 1, u_buffer);
93 jni()->SetObjectArrayElement(planes, 2, v_buffer);
94 return jni()->NewObject(*j_frame_class_, j_i420_frame_ctor_id_,
95 frame->width(), frame->height(),
96 static_cast<int>(frame->rotation()), strides,
97 planes, javaShallowCopy(frame));
98 }
99
100 // Return a VideoRenderer.I420Frame referring texture object in |frame|.
101 jobject ToJavaTextureFrame(const webrtc::VideoFrame* frame) {
102 NativeHandleImpl handle =
103 static_cast<AndroidTextureBuffer*>(frame->video_frame_buffer().get())
104 ->native_handle_impl();
105 jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni());
106
107 return jni()->NewObject(
108 *j_frame_class_, j_texture_frame_ctor_id_, frame->width(),
109 frame->height(), static_cast<int>(frame->rotation()),
110 handle.oes_texture_id, sampling_matrix, javaShallowCopy(frame));
111 }
112
113 JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
114
115 ScopedGlobalRef<jobject> j_callbacks_;
116 jmethodID j_render_frame_id_;
117 ScopedGlobalRef<jclass> j_frame_class_;
118 jmethodID j_i420_frame_ctor_id_;
119 jmethodID j_texture_frame_ctor_id_;
120 ScopedGlobalRef<jclass> j_byte_buffer_class_;
121 };
122
123 JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
124 delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
125 }
126
127 JOW(void, VideoRenderer_releaseNativeFrame)
128 (JNIEnv* jni, jclass, jlong j_frame_ptr) {
129 delete reinterpret_cast<const webrtc::VideoFrame*>(j_frame_ptr);
130 }
131
132 JOW(jlong, VideoRenderer_nativeWrapVideoRenderer)
133 (JNIEnv* jni, jclass, jobject j_callbacks) {
134 std::unique_ptr<JavaVideoRendererWrapper> renderer(
135 new JavaVideoRendererWrapper(jni, j_callbacks));
136 return (jlong)renderer.release();
137 }
138
139 JOW(void, VideoRenderer_nativeCopyPlane)
140 (JNIEnv* jni,
141 jclass,
142 jobject j_src_buffer,
143 jint width,
144 jint height,
145 jint src_stride,
146 jobject j_dst_buffer,
147 jint dst_stride) {
148 size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer);
149 size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer);
150 RTC_CHECK(src_stride >= width) << "Wrong source stride " << src_stride;
151 RTC_CHECK(dst_stride >= width) << "Wrong destination stride " << dst_stride;
152 RTC_CHECK(src_size >= src_stride * height)
153 << "Insufficient source buffer capacity " << src_size;
154 RTC_CHECK(dst_size >= dst_stride * height)
155 << "Insufficient destination buffer capacity " << dst_size;
156 uint8_t* src =
157 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer));
158 uint8_t* dst =
159 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_buffer));
160 if (src_stride == dst_stride) {
161 memcpy(dst, src, src_stride * height);
162 } else {
163 for (int i = 0; i < height; i++) {
164 memcpy(dst, src, width);
165 src += src_stride;
166 dst += dst_stride;
167 }
168 }
169 }
170
171 } // namespace webrtc_jni
OLDNEW
« webrtc/pc/peerconnectionfactory.cc ('K') | « webrtc/sdk/android/src/jni/video_jni.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698