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

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

Issue 2939203002: Support building WebRTC without audio and video for Android (Closed)
Patch Set: Add [null_]media_jni targets. 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
« no previous file with comments | « webrtc/sdk/android/src/jni/video_jni.cc ('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
(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
52 jobject j_frame;
53 if (video_frame.video_frame_buffer()->type() ==
54 webrtc::VideoFrameBuffer::Type::kNative) {
55 AndroidVideoFrameBuffer* android_buffer =
56 static_cast<AndroidVideoFrameBuffer*>(
57 video_frame.video_frame_buffer().get());
58 switch (android_buffer->android_type()) {
59 case AndroidVideoFrameBuffer::AndroidType::kTextureBuffer:
60 j_frame = ToJavaTextureFrame(&video_frame);
61 break;
62 case AndroidVideoFrameBuffer::AndroidType::kJavaBuffer:
63 j_frame = static_cast<AndroidVideoBuffer*>(android_buffer)
64 ->ToJavaI420Frame(jni(), video_frame.width(),
65 video_frame.height(),
66 video_frame.rotation());
67 break;
68 default:
69 RTC_NOTREACHED();
70 }
71 } else {
72 j_frame = ToJavaI420Frame(&video_frame);
73 }
74 // |j_callbacks_| is responsible for releasing |j_frame| with
75 // VideoRenderer.renderFrameDone().
76 jni()->CallVoidMethod(*j_callbacks_, j_render_frame_id_, j_frame);
77 CHECK_EXCEPTION(jni());
78 }
79
80 private:
81 // Make a shallow copy of |frame| to be used with Java. The callee has
82 // ownership of the frame, and the frame should be released with
83 // VideoRenderer.releaseNativeFrame().
84 static jlong javaShallowCopy(const webrtc::VideoFrame* frame) {
85 return jlongFromPointer(new webrtc::VideoFrame(*frame));
86 }
87
88 // Return a VideoRenderer.I420Frame referring to the data in |frame|.
89 jobject ToJavaI420Frame(const webrtc::VideoFrame* frame) {
90 jintArray strides = jni()->NewIntArray(3);
91 jint* strides_array = jni()->GetIntArrayElements(strides, NULL);
92 rtc::scoped_refptr<webrtc::I420BufferInterface> i420_buffer =
93 frame->video_frame_buffer()->ToI420();
94 strides_array[0] = i420_buffer->StrideY();
95 strides_array[1] = i420_buffer->StrideU();
96 strides_array[2] = i420_buffer->StrideV();
97 jni()->ReleaseIntArrayElements(strides, strides_array, 0);
98 jobjectArray planes = jni()->NewObjectArray(3, *j_byte_buffer_class_, NULL);
99 jobject y_buffer = jni()->NewDirectByteBuffer(
100 const_cast<uint8_t*>(i420_buffer->DataY()),
101 i420_buffer->StrideY() * i420_buffer->height());
102 size_t chroma_height = i420_buffer->ChromaHeight();
103 jobject u_buffer =
104 jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataU()),
105 i420_buffer->StrideU() * chroma_height);
106 jobject v_buffer =
107 jni()->NewDirectByteBuffer(const_cast<uint8_t*>(i420_buffer->DataV()),
108 i420_buffer->StrideV() * chroma_height);
109
110 jni()->SetObjectArrayElement(planes, 0, y_buffer);
111 jni()->SetObjectArrayElement(planes, 1, u_buffer);
112 jni()->SetObjectArrayElement(planes, 2, v_buffer);
113 return jni()->NewObject(*j_frame_class_, j_i420_frame_ctor_id_,
114 frame->width(), frame->height(),
115 static_cast<int>(frame->rotation()), strides,
116 planes, javaShallowCopy(frame));
117 }
118
119 // Return a VideoRenderer.I420Frame referring texture object in |frame|.
120 jobject ToJavaTextureFrame(const webrtc::VideoFrame* frame) {
121 NativeHandleImpl handle =
122 static_cast<AndroidTextureBuffer*>(frame->video_frame_buffer().get())
123 ->native_handle_impl();
124 jfloatArray sampling_matrix = handle.sampling_matrix.ToJava(jni());
125
126 return jni()->NewObject(
127 *j_frame_class_, j_texture_frame_ctor_id_, frame->width(),
128 frame->height(), static_cast<int>(frame->rotation()),
129 handle.oes_texture_id, sampling_matrix, javaShallowCopy(frame));
130 }
131
132 JNIEnv* jni() { return AttachCurrentThreadIfNeeded(); }
133
134 ScopedGlobalRef<jobject> j_callbacks_;
135 jmethodID j_render_frame_id_;
136 ScopedGlobalRef<jclass> j_frame_class_;
137 jmethodID j_i420_frame_ctor_id_;
138 jmethodID j_texture_frame_ctor_id_;
139 ScopedGlobalRef<jclass> j_byte_buffer_class_;
140 };
141
142 JOW(void, VideoRenderer_freeWrappedVideoRenderer)(JNIEnv*, jclass, jlong j_p) {
143 delete reinterpret_cast<JavaVideoRendererWrapper*>(j_p);
144 }
145
146 JOW(void, VideoRenderer_releaseNativeFrame)
147 (JNIEnv* jni, jclass, jlong j_frame_ptr) {
148 delete reinterpret_cast<const webrtc::VideoFrame*>(j_frame_ptr);
149 }
150
151 JOW(jlong, VideoRenderer_nativeWrapVideoRenderer)
152 (JNIEnv* jni, jclass, jobject j_callbacks) {
153 std::unique_ptr<JavaVideoRendererWrapper> renderer(
154 new JavaVideoRendererWrapper(jni, j_callbacks));
155 return (jlong)renderer.release();
156 }
157
158 JOW(void, VideoRenderer_nativeCopyPlane)
159 (JNIEnv* jni,
160 jclass,
161 jobject j_src_buffer,
162 jint width,
163 jint height,
164 jint src_stride,
165 jobject j_dst_buffer,
166 jint dst_stride) {
167 size_t src_size = jni->GetDirectBufferCapacity(j_src_buffer);
168 size_t dst_size = jni->GetDirectBufferCapacity(j_dst_buffer);
169 RTC_CHECK(src_stride >= width) << "Wrong source stride " << src_stride;
170 RTC_CHECK(dst_stride >= width) << "Wrong destination stride " << dst_stride;
171 RTC_CHECK(src_size >= src_stride * height)
172 << "Insufficient source buffer capacity " << src_size;
173 RTC_CHECK(dst_size >= dst_stride * height)
174 << "Insufficient destination buffer capacity " << dst_size;
175 uint8_t* src =
176 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_src_buffer));
177 uint8_t* dst =
178 reinterpret_cast<uint8_t*>(jni->GetDirectBufferAddress(j_dst_buffer));
179 if (src_stride == dst_stride) {
180 memcpy(dst, src, src_stride * height);
181 } else {
182 for (int i = 0; i < height; i++) {
183 memcpy(dst, src, width);
184 src += src_stride;
185 dst += dst_stride;
186 }
187 }
188 }
189
190 } // namespace webrtc_jni
OLDNEW
« no previous file with comments | « 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