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

Side by Side Diff: webrtc/modules/video_render/android/video_render_android_surface_view.cc

Issue 1929223003: Reland of Delete video_render module. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 7 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) 2012 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 "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
12 #include "webrtc/modules/video_render/android/video_render_android_surface_view. h"
13 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
14 #include "webrtc/system_wrappers/include/tick_util.h"
15
16 #ifdef ANDROID_LOG
17 #include <android/log.h>
18 #include <stdio.h>
19
20 #undef WEBRTC_TRACE
21 #define WEBRTC_TRACE(a,b,c,...) __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTC *", __VA_ARGS__)
22 #else
23 #include "webrtc/system_wrappers/include/trace.h"
24 #endif
25
26 namespace webrtc {
27
28 AndroidSurfaceViewRenderer::AndroidSurfaceViewRenderer(
29 const int32_t id,
30 const VideoRenderType videoRenderType,
31 void* window,
32 const bool fullscreen) :
33 VideoRenderAndroid(id,videoRenderType,window,fullscreen),
34 _javaRenderObj(NULL),
35 _javaRenderClass(NULL) {
36 }
37
38 AndroidSurfaceViewRenderer::~AndroidSurfaceViewRenderer() {
39 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
40 "AndroidSurfaceViewRenderer dtor");
41 if(g_jvm) {
42 // get the JNI env for this thread
43 bool isAttached = false;
44 JNIEnv* env = NULL;
45 if (g_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
46 // try to attach the thread and get the env
47 // Attach this thread to JVM
48 jint res = g_jvm->AttachCurrentThread(&env, NULL);
49
50 // Get the JNI env for this thread
51 if ((res < 0) || !env) {
52 WEBRTC_TRACE(kTraceError,
53 kTraceVideoRenderer,
54 _id,
55 "%s: Could not attach thread to JVM (%d, %p)",
56 __FUNCTION__,
57 res,
58 env);
59 env=NULL;
60 }
61 else {
62 isAttached = true;
63 }
64 }
65 env->DeleteGlobalRef(_javaRenderObj);
66 env->DeleteGlobalRef(_javaRenderClass);
67
68 if (isAttached) {
69 if (g_jvm->DetachCurrentThread() < 0) {
70 WEBRTC_TRACE(kTraceWarning,
71 kTraceVideoRenderer,
72 _id,
73 "%s: Could not detach thread from JVM",
74 __FUNCTION__);
75 }
76 }
77 }
78 }
79
80 int32_t AndroidSurfaceViewRenderer::Init() {
81 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s", __FUNCTION__);
82 if (!g_jvm) {
83 WEBRTC_TRACE(kTraceError,
84 kTraceVideoRenderer,
85 _id,
86 "(%s): Not a valid Java VM pointer.",
87 __FUNCTION__);
88 return -1;
89 }
90 if(!_ptrWindow) {
91 WEBRTC_TRACE(kTraceWarning,
92 kTraceVideoRenderer,
93 _id,
94 "(%s): No window have been provided.",
95 __FUNCTION__);
96 return -1;
97 }
98
99 // get the JNI env for this thread
100 bool isAttached = false;
101 JNIEnv* env = NULL;
102 if (g_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
103 // try to attach the thread and get the env
104 // Attach this thread to JVM
105 jint res = g_jvm->AttachCurrentThread(&env, NULL);
106
107 // Get the JNI env for this thread
108 if ((res < 0) || !env) {
109 WEBRTC_TRACE(kTraceError,
110 kTraceVideoRenderer,
111 _id,
112 "%s: Could not attach thread to JVM (%d, %p)",
113 __FUNCTION__,
114 res,
115 env);
116 return -1;
117 }
118 isAttached = true;
119 }
120
121 // get the ViESurfaceRender class
122 jclass javaRenderClassLocal =
123 env->FindClass("org/webrtc/videoengine/ViESurfaceRenderer");
124 if (!javaRenderClassLocal) {
125 WEBRTC_TRACE(kTraceError,
126 kTraceVideoRenderer,
127 _id,
128 "%s: could not find ViESurfaceRenderer",
129 __FUNCTION__);
130 return -1;
131 }
132
133 // create a global reference to the class (to tell JNI that
134 // we are referencing it after this function has returned)
135 _javaRenderClass =
136 reinterpret_cast<jclass>(env->NewGlobalRef(javaRenderClassLocal));
137 if (!_javaRenderClass) {
138 WEBRTC_TRACE(kTraceError,
139 kTraceVideoRenderer,
140 _id,
141 "%s: could not create Java ViESurfaceRenderer class reference",
142 __FUNCTION__);
143 return -1;
144 }
145
146 // Delete local class ref, we only use the global ref
147 env->DeleteLocalRef(javaRenderClassLocal);
148
149 // get the method ID for the constructor
150 jmethodID cid = env->GetMethodID(_javaRenderClass,
151 "<init>",
152 "(Landroid/view/SurfaceView;)V");
153 if (cid == NULL) {
154 WEBRTC_TRACE(kTraceError,
155 kTraceVideoRenderer,
156 _id,
157 "%s: could not get constructor ID",
158 __FUNCTION__);
159 return -1; /* exception thrown */
160 }
161
162 // construct the object
163 jobject javaRenderObjLocal = env->NewObject(_javaRenderClass,
164 cid,
165 _ptrWindow);
166 if (!javaRenderObjLocal) {
167 WEBRTC_TRACE(kTraceError,
168 kTraceVideoRenderer,
169 _id,
170 "%s: could not create Java Render",
171 __FUNCTION__);
172 return -1;
173 }
174
175 // create a reference to the object (to tell JNI that we are referencing it
176 // after this function has returned)
177 _javaRenderObj = env->NewGlobalRef(javaRenderObjLocal);
178 if (!_javaRenderObj) {
179 WEBRTC_TRACE(kTraceError,
180 kTraceVideoRenderer,
181 _id,
182 "%s: could not create Java SurfaceRender object reference",
183 __FUNCTION__);
184 return -1;
185 }
186
187 // Detach this thread if it was attached
188 if (isAttached) {
189 if (g_jvm->DetachCurrentThread() < 0) {
190 WEBRTC_TRACE(kTraceWarning,
191 kTraceVideoRenderer,
192 _id,
193 "%s: Could not detach thread from JVM", __FUNCTION__);
194 }
195 }
196
197 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s done", __FUNCTION__);
198 return 0;
199 }
200
201 AndroidStream*
202 AndroidSurfaceViewRenderer::CreateAndroidRenderChannel(
203 int32_t streamId,
204 int32_t zOrder,
205 const float left,
206 const float top,
207 const float right,
208 const float bottom,
209 VideoRenderAndroid& renderer) {
210 WEBRTC_TRACE(kTraceDebug,
211 kTraceVideoRenderer,
212 _id,
213 "%s: Id %d",
214 __FUNCTION__,
215 streamId);
216 AndroidSurfaceViewChannel* stream =
217 new AndroidSurfaceViewChannel(streamId, g_jvm, renderer, _javaRenderObj);
218 if(stream && stream->Init(zOrder, left, top, right, bottom) == 0)
219 return stream;
220 else
221 delete stream;
222 return NULL;
223 }
224
225 AndroidSurfaceViewChannel::AndroidSurfaceViewChannel(
226 uint32_t streamId,
227 JavaVM* jvm,
228 VideoRenderAndroid& renderer,
229 jobject javaRenderObj) :
230 _id(streamId),
231 _renderCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
232 _renderer(renderer),
233 _jvm(jvm),
234 _javaRenderObj(javaRenderObj),
235 #ifndef ANDROID_NDK_8_OR_ABOVE
236 _javaByteBufferObj(NULL),
237 _directBuffer(NULL),
238 #endif
239 _bitmapWidth(0),
240 _bitmapHeight(0) {
241 }
242
243 AndroidSurfaceViewChannel::~AndroidSurfaceViewChannel() {
244 WEBRTC_TRACE(kTraceInfo,
245 kTraceVideoRenderer,
246 _id,
247 "AndroidSurfaceViewChannel dtor");
248 delete &_renderCritSect;
249 if(_jvm) {
250 // get the JNI env for this thread
251 bool isAttached = false;
252 JNIEnv* env = NULL;
253 if ( _jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
254 // try to attach the thread and get the env
255 // Attach this thread to JVM
256 jint res = _jvm->AttachCurrentThread(&env, NULL);
257
258 // Get the JNI env for this thread
259 if ((res < 0) || !env) {
260 WEBRTC_TRACE(kTraceError,
261 kTraceVideoRenderer,
262 _id,
263 "%s: Could not attach thread to JVM (%d, %p)",
264 __FUNCTION__,
265 res,
266 env);
267 env=NULL;
268 }
269 else {
270 isAttached = true;
271 }
272 }
273
274 env->DeleteGlobalRef(_javaByteBufferObj);
275 if (isAttached) {
276 if (_jvm->DetachCurrentThread() < 0) {
277 WEBRTC_TRACE(kTraceWarning,
278 kTraceVideoRenderer,
279 _id,
280 "%s: Could not detach thread from JVM",
281 __FUNCTION__);
282 }
283 }
284 }
285 }
286
287 int32_t AndroidSurfaceViewChannel::Init(
288 int32_t /*zOrder*/,
289 const float left,
290 const float top,
291 const float right,
292 const float bottom) {
293
294 WEBRTC_TRACE(kTraceDebug,
295 kTraceVideoRenderer,
296 _id,
297 "%s: AndroidSurfaceViewChannel",
298 __FUNCTION__);
299 if (!_jvm) {
300 WEBRTC_TRACE(kTraceError,
301 kTraceVideoRenderer,
302 _id,
303 "%s: Not a valid Java VM pointer",
304 __FUNCTION__);
305 return -1;
306 }
307
308 if( (top > 1 || top < 0) ||
309 (right > 1 || right < 0) ||
310 (bottom > 1 || bottom < 0) ||
311 (left > 1 || left < 0)) {
312 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
313 "%s: Wrong coordinates", __FUNCTION__);
314 return -1;
315 }
316
317 // get the JNI env for this thread
318 bool isAttached = false;
319 JNIEnv* env = NULL;
320 if (_jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
321 // try to attach the thread and get the env
322 // Attach this thread to JVM
323 jint res = _jvm->AttachCurrentThread(&env, NULL);
324
325 // Get the JNI env for this thread
326 if ((res < 0) || !env) {
327 WEBRTC_TRACE(kTraceError,
328 kTraceVideoRenderer,
329 _id,
330 "%s: Could not attach thread to JVM (%d, %p)",
331 __FUNCTION__,
332 res,
333 env);
334 return -1;
335 }
336 isAttached = true;
337 }
338
339 jclass javaRenderClass =
340 env->FindClass("org/webrtc/videoengine/ViESurfaceRenderer");
341 if (!javaRenderClass) {
342 WEBRTC_TRACE(kTraceError,
343 kTraceVideoRenderer,
344 _id,
345 "%s: could not find ViESurfaceRenderer",
346 __FUNCTION__);
347 return -1;
348 }
349
350 // get the method ID for the CreateIntArray
351 _createByteBufferCid =
352 env->GetMethodID(javaRenderClass,
353 "CreateByteBuffer",
354 "(II)Ljava/nio/ByteBuffer;");
355 if (_createByteBufferCid == NULL) {
356 WEBRTC_TRACE(kTraceError,
357 kTraceVideoRenderer,
358 _id,
359 "%s: could not get CreateByteBuffer ID",
360 __FUNCTION__);
361 return -1; /* exception thrown */
362 }
363
364 // get the method ID for the DrawByteBuffer function
365 _drawByteBufferCid = env->GetMethodID(javaRenderClass,
366 "DrawByteBuffer",
367 "()V");
368 if (_drawByteBufferCid == NULL) {
369 WEBRTC_TRACE(kTraceError,
370 kTraceVideoRenderer,
371 _id,
372 "%s: could not get DrawByteBuffer ID",
373 __FUNCTION__);
374 return -1; /* exception thrown */
375 }
376
377 // get the method ID for the SetCoordinates function
378 _setCoordinatesCid = env->GetMethodID(javaRenderClass,
379 "SetCoordinates",
380 "(FFFF)V");
381 if (_setCoordinatesCid == NULL) {
382 WEBRTC_TRACE(kTraceError,
383 kTraceVideoRenderer,
384 _id,
385 "%s: could not get SetCoordinates ID",
386 __FUNCTION__);
387 return -1; /* exception thrown */
388 }
389
390 env->CallVoidMethod(_javaRenderObj, _setCoordinatesCid,
391 left, top, right, bottom);
392
393 // Detach this thread if it was attached
394 if (isAttached) {
395 if (_jvm->DetachCurrentThread() < 0) {
396 WEBRTC_TRACE(kTraceWarning,
397 kTraceVideoRenderer,
398 _id,
399 "%s: Could not detach thread from JVM",
400 __FUNCTION__);
401 }
402 }
403
404 WEBRTC_TRACE(kTraceDebug,
405 kTraceVideoRenderer,
406 _id,
407 "%s: AndroidSurfaceViewChannel done",
408 __FUNCTION__);
409 return 0;
410 }
411
412 int32_t AndroidSurfaceViewChannel::RenderFrame(const uint32_t /*streamId*/,
413 const VideoFrame& videoFrame) {
414 // WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer,_id, "%s:" ,__FUNCTION__);
415 _renderCritSect.Enter();
416 _bufferToRender = videoFrame;
417 _renderCritSect.Leave();
418 _renderer.ReDraw();
419 return 0;
420 }
421
422
423 /*Implements AndroidStream
424 * Calls the Java object and render the buffer in _bufferToRender
425 */
426 void AndroidSurfaceViewChannel::DeliverFrame(JNIEnv* jniEnv) {
427 _renderCritSect.Enter();
428
429 if (_bitmapWidth != _bufferToRender.width() ||
430 _bitmapHeight != _bufferToRender.height()) {
431 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s: New render size %d "
432 "%d",__FUNCTION__,
433 _bufferToRender.width(), _bufferToRender.height());
434 if (_javaByteBufferObj) {
435 jniEnv->DeleteGlobalRef(_javaByteBufferObj);
436 _javaByteBufferObj = NULL;
437 _directBuffer = NULL;
438 }
439
440 jobject javaByteBufferObj =
441 jniEnv->CallObjectMethod(_javaRenderObj, _createByteBufferCid,
442 _bufferToRender.width(),
443 _bufferToRender.height());
444 _javaByteBufferObj = jniEnv->NewGlobalRef(javaByteBufferObj);
445 if (!_javaByteBufferObj) {
446 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: could not "
447 "create Java ByteBuffer object reference", __FUNCTION__);
448 _renderCritSect.Leave();
449 return;
450 } else {
451 _directBuffer = static_cast<unsigned char*>
452 (jniEnv->GetDirectBufferAddress(_javaByteBufferObj));
453 _bitmapWidth = _bufferToRender.width();
454 _bitmapHeight = _bufferToRender.height();
455 }
456 }
457
458 if(_javaByteBufferObj && _bitmapWidth && _bitmapHeight) {
459 const int conversionResult =
460 ConvertFromI420(_bufferToRender, kRGB565, 0, _directBuffer);
461
462 if (conversionResult < 0) {
463 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s: Color conversion"
464 " failed.", __FUNCTION__);
465 _renderCritSect.Leave();
466 return;
467 }
468 }
469 _renderCritSect.Leave();
470 // Draw the Surface
471 jniEnv->CallVoidMethod(_javaRenderObj, _drawByteBufferCid);
472 }
473
474 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698