1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
266487e16299d868af6602258c72675b220518235leozwang@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
115aa3f1b4c0272597ab349a3a2fa125d64dd72071pbos@webrtc.org#include "webrtc/modules/video_render/android/video_render_android_native_opengl2.h"
1298f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
1398f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/tick_util.h"
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef ANDROID_LOG
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <android/log.h>
175aa3f1b4c0272597ab349a3a2fa125d64dd72071pbos@webrtc.org#include <stdio.h>
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#undef WEBRTC_TRACE
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#define WEBRTC_TRACE(a,b,c,...)  __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTC*", __VA_ARGS__)
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
2298f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/trace.h"
23470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
24470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
25470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc {
26470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAndroidNativeOpenGl2Renderer::AndroidNativeOpenGl2Renderer(
28ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org    const int32_t id,
29ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const VideoRenderType videoRenderType,
30ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    void* window,
31ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const bool fullscreen) :
32470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    VideoRenderAndroid(id, videoRenderType, window, fullscreen),
33470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _javaRenderObj(NULL),
34f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    _javaRenderClass(NULL) {
35470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
36470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
37f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.orgbool AndroidNativeOpenGl2Renderer::UseOpenGL2(void* window) {
38f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!g_jvm) {
39f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
40f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "RendererAndroid():UseOpenGL No JVM set.");
41f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return false;
42f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
43f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  bool isAttached = false;
44f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  JNIEnv* env = NULL;
45f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
46f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // try to attach the thread and get the env
47f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Attach this thread to JVM
48f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    jint res = g_jvm->AttachCurrentThread(&env, NULL);
49f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
50f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Get the JNI env for this thread
51f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if ((res < 0) || !env) {
52f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(
53f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org          kTraceError,
54f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org          kTraceVideoRenderer,
55f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org          -1,
56f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org          "RendererAndroid(): Could not attach thread to JVM (%d, %p)",
57f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org          res, env);
58f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      return false;
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
60f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    isAttached = true;
61f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
62f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
63f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the renderer class
64f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jclass javaRenderClassLocal =
65f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      env->FindClass("org/webrtc/videoengine/ViEAndroidGLES20");
66f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!javaRenderClassLocal) {
67f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
68f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not find ViEAndroidRenderer class",
69f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 __FUNCTION__);
70f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return false;
71f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
72f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
73f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the method ID for UseOpenGL
74f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jmethodID cidUseOpenGL = env->GetStaticMethodID(javaRenderClassLocal,
75f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                                  "UseOpenGL2",
76f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                                  "(Ljava/lang/Object;)Z");
77f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (cidUseOpenGL == NULL) {
78f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
79f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not get UseOpenGL ID", __FUNCTION__);
80f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return false;
81f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
82f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jboolean res = env->CallStaticBooleanMethod(javaRenderClassLocal,
83f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                              cidUseOpenGL, (jobject) window);
84f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
85f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // Detach this thread if it was attached
86f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (isAttached) {
87f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (g_jvm->DetachCurrentThread() < 0) {
88f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1,
89f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   "%s: Could not detach thread from JVM", __FUNCTION__);
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
91f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
92f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  return res;
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
95f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.orgAndroidNativeOpenGl2Renderer::~AndroidNativeOpenGl2Renderer() {
96f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
97f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               "AndroidNativeOpenGl2Renderer dtor");
98f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (g_jvm) {
99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    // get the JNI env for this thread
100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    bool isAttached = false;
101470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    JNIEnv* env = NULL;
102f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
103f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // try to attach the thread and get the env
104f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // Attach this thread to JVM
105f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      jint res = g_jvm->AttachCurrentThread(&env, NULL);
106470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
107f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // Get the JNI env for this thread
108f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      if ((res < 0) || !env) {
109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
110f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     "%s: Could not attach thread to JVM (%d, %p)",
111f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     __FUNCTION__, res, env);
112f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        env = NULL;
113f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      }
114f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      else {
115f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        isAttached = true;
116f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      }
117470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
118470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
119f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    env->DeleteGlobalRef(_javaRenderObj);
120f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    env->DeleteGlobalRef(_javaRenderClass);
121f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
122f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (isAttached) {
123f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      if (g_jvm->DetachCurrentThread() < 0) {
124f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
125f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     "%s: Could not detach thread from JVM",
126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                     __FUNCTION__);
127f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      }
128470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
129f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
130f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org}
131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
132ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.orgint32_t AndroidNativeOpenGl2Renderer::Init() {
133f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s", __FUNCTION__);
134f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!g_jvm) {
135f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
136f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "(%s): Not a valid Java VM pointer.", __FUNCTION__);
137f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
138f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
139f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!_ptrWindow) {
140f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
141f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "(%s): No window have been provided.", __FUNCTION__);
142f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
143f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
144f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
145f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the JNI env for this thread
146f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  bool isAttached = false;
147f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  JNIEnv* env = NULL;
148f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (g_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
149f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // try to attach the thread and get the env
150f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Attach this thread to JVM
151f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    jint res = g_jvm->AttachCurrentThread(&env, NULL);
152f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
153f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Get the JNI env for this thread
154f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if ((res < 0) || !env) {
155f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
156f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   "%s: Could not attach thread to JVM (%d, %p)",
157f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   __FUNCTION__, res, env);
158f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      return -1;
159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
160f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    isAttached = true;
161f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
162f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
163f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the ViEAndroidGLES20 class
164f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jclass javaRenderClassLocal =
165f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      env->FindClass("org/webrtc/videoengine/ViEAndroidGLES20");
166f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!javaRenderClassLocal) {
167f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
168f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not find ViEAndroidGLES20", __FUNCTION__);
169f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
170f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
171f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
172f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // create a global reference to the class (to tell JNI that
173f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // we are referencing it after this function has returned)
174f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _javaRenderClass =
175f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      reinterpret_cast<jclass> (env->NewGlobalRef(javaRenderClassLocal));
176f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!_javaRenderClass) {
177f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
178f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not create Java SurfaceHolder class reference",
179f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 __FUNCTION__);
180f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
181f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
182f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
183f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // Delete local class ref, we only use the global ref
184f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  env->DeleteLocalRef(javaRenderClassLocal);
185f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
186f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // create a reference to the object (to tell JNI that we are referencing it
187f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // after this function has returned)
188f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _javaRenderObj = env->NewGlobalRef(_ptrWindow);
189f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!_javaRenderObj) {
190f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(
191f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        kTraceError,
192f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        kTraceVideoRenderer,
193f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        _id,
194f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        "%s: could not create Java SurfaceRender object reference",
195f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        __FUNCTION__);
196f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
197f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
198f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
199f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // Detach this thread if it was attached
200f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (isAttached) {
201f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (g_jvm->DetachCurrentThread() < 0) {
202f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
203f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   "%s: Could not detach thread from JVM", __FUNCTION__);
204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
205f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
207f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s done",
208f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               __FUNCTION__);
209f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  return 0;
210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAndroidStream*
213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAndroidNativeOpenGl2Renderer::CreateAndroidRenderChannel(
214ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org    int32_t streamId,
215ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org    int32_t zOrder,
216ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const float left,
217ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const float top,
218ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const float right,
219ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    const float bottom,
220f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    VideoRenderAndroid& renderer) {
221f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s: Id %d",
222f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               __FUNCTION__, streamId);
223f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  AndroidNativeOpenGl2Channel* stream =
224f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      new AndroidNativeOpenGl2Channel(streamId, g_jvm, renderer,
225f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                      _javaRenderObj);
226f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (stream && stream->Init(zOrder, left, top, right, bottom) == 0)
227f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return stream;
228f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  else {
229f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    delete stream;
230f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
231f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  return NULL;
232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
234ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.orgAndroidNativeOpenGl2Channel::AndroidNativeOpenGl2Channel(
235ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org    uint32_t streamId,
236ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    JavaVM* jvm,
237ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    VideoRenderAndroid& renderer,jobject javaRenderObj):
238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _id(streamId),
239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _renderCritSect(*CriticalSectionWrapper::CreateCriticalSection()),
240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _renderer(renderer), _jvm(jvm), _javaRenderObj(javaRenderObj),
241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    _registerNativeCID(NULL), _deRegisterNativeCID(NULL),
242f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    _openGLRenderer(streamId) {
243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
244470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
245f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.orgAndroidNativeOpenGl2Channel::~AndroidNativeOpenGl2Channel() {
246f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
247f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               "AndroidNativeOpenGl2Channel dtor");
248f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_jvm) {
249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    // get the JNI env for this thread
250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    bool isAttached = false;
251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    JNIEnv* env = NULL;
252f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
253f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // try to attach the thread and get the env
254f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // Attach this thread to JVM
255f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      jint res = _jvm->AttachCurrentThread(&env, NULL);
256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
257f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      // Get the JNI env for this thread
258f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      if ((res < 0) || !env) {
259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com        WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
260f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     "%s: Could not attach thread to JVM (%d, %p)",
261f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     __FUNCTION__, res, env);
262f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        env = NULL;
263f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      } else {
264f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        isAttached = true;
265f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      }
266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
267f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (env && _deRegisterNativeCID) {
268f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      env->CallVoidMethod(_javaRenderObj, _deRegisterNativeCID);
269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
271f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (isAttached) {
272f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      if (_jvm->DetachCurrentThread() < 0) {
273f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
274f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                     "%s: Could not detach thread from JVM",
275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                     __FUNCTION__);
276f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      }
277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
278f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
27921f7d6d2fecce113b129d94e51882c81bd201732braveyao@webrtc.org
28021f7d6d2fecce113b129d94e51882c81bd201732braveyao@webrtc.org  delete &_renderCritSect;
281f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org}
282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
283ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.orgint32_t AndroidNativeOpenGl2Channel::Init(int32_t zOrder,
284ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org                                          const float left,
285ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org                                          const float top,
286ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org                                          const float right,
287ddf94e71e524371f0cc2f6bcfed9ee5a972f11e9pbos@webrtc.org                                          const float bottom)
288f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org{
289f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
290f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               "%s: AndroidNativeOpenGl2Channel", __FUNCTION__);
291f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!_jvm) {
292f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
293f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: Not a valid Java VM pointer", __FUNCTION__);
294f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
295f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
296f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
297f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the JNI env for this thread
298f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  bool isAttached = false;
299f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  JNIEnv* env = NULL;
300f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
301f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // try to attach the thread and get the env
302f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Attach this thread to JVM
303f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    jint res = _jvm->AttachCurrentThread(&env, NULL);
304f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
305f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    // Get the JNI env for this thread
306f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if ((res < 0) || !env) {
307f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
308f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   "%s: Could not attach thread to JVM (%d, %p)",
309f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   __FUNCTION__, res, env);
310f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      return -1;
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
312f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    isAttached = true;
313f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
314f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
315f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jclass javaRenderClass =
316f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      env->FindClass("org/webrtc/videoengine/ViEAndroidGLES20");
317f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (!javaRenderClass) {
318f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
319f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not find ViESurfaceRenderer", __FUNCTION__);
320f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
321f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
322f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
323f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // get the method ID for the ReDraw function
324f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _redrawCid = env->GetMethodID(javaRenderClass, "ReDraw", "()V");
325f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_redrawCid == NULL) {
326f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
327f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not get ReDraw ID", __FUNCTION__);
328f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
329f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
330f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
331f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _registerNativeCID = env->GetMethodID(javaRenderClass,
332f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                        "RegisterNativeObject", "(J)V");
333f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_registerNativeCID == NULL) {
334f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
335f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not get RegisterNativeObject ID", __FUNCTION__);
336f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
337f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
338f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
339f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _deRegisterNativeCID = env->GetMethodID(javaRenderClass,
340f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                                          "DeRegisterNativeObject", "()V");
341f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_deRegisterNativeCID == NULL) {
342f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
343f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: could not get DeRegisterNativeObject ID",
344f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 __FUNCTION__);
345f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
346f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
347f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
348f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  JNINativeMethod nativeFunctions[2] = {
349f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    { "DrawNative",
350f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      "(J)V",
351f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      (void*) &AndroidNativeOpenGl2Channel::DrawNativeStatic, },
352f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    { "CreateOpenGLNative",
353f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      "(JII)I",
354f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      (void*) &AndroidNativeOpenGl2Channel::CreateOpenGLNativeStatic },
355f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  };
356f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (env->RegisterNatives(javaRenderClass, nativeFunctions, 2) == 0) {
357f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, -1,
358f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: Registered native functions", __FUNCTION__);
359f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
360f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  else {
361f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
362f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                 "%s: Failed to register native functions", __FUNCTION__);
363f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
364f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
365f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
366f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  env->CallVoidMethod(_javaRenderObj, _registerNativeCID, (jlong) this);
367f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
368f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // Detach this thread if it was attached
369f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (isAttached) {
370f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    if (_jvm->DetachCurrentThread() < 0) {
371f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org      WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
372f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org                   "%s: Could not detach thread from JVM", __FUNCTION__);
373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
374f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
375f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org
376f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  if (_openGLRenderer.SetCoordinates(zOrder, left, top, right, bottom) != 0) {
377f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org    return -1;
378f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  }
379f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
380f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org               "%s: AndroidNativeOpenGl2Channel done", __FUNCTION__);
381f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  return 0;
382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3844765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchezint32_t AndroidNativeOpenGl2Channel::RenderFrame(const uint32_t /*streamId*/,
3854765070b8d6f024509c717c04d9b708750666927Miguel Casas-Sanchez                                                 const VideoFrame& videoFrame) {
386f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  //   WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer,_id, "%s:" ,__FUNCTION__);
387f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _renderCritSect.Enter();
388deafa7b3c9a247106ad190a14c823b053eb13cf5magjed@webrtc.org  _bufferToRender = videoFrame;
389f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _renderCritSect.Leave();
390f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  _renderer.ReDraw();
391f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  return 0;
392470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
393470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
394470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*Implements AndroidStream
395470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Calls the Java object and render the buffer in _bufferToRender
396470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
397f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.orgvoid AndroidNativeOpenGl2Channel::DeliverFrame(JNIEnv* jniEnv) {
398f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  //TickTime timeNow=TickTime::Now();
399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
400f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  //Draw the Surface
401f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  jniEnv->CallVoidMethod(_javaRenderObj, _redrawCid);
402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
403f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer,_id,
404f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // "%s: time to deliver %lld" ,__FUNCTION__,
405f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.org  // (TickTime::Now()-timeNow).Milliseconds());
406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
409ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org * JNI callback from Java class. Called when the render
410ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org * want to render a frame. Called from the GLRenderThread
411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Method:    DrawNative
412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Signature: (J)V
413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
414ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.orgvoid JNICALL AndroidNativeOpenGl2Channel::DrawNativeStatic(
415ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    JNIEnv * env, jobject, jlong context) {
416ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  AndroidNativeOpenGl2Channel* renderChannel =
417ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org      reinterpret_cast<AndroidNativeOpenGl2Channel*>(context);
418ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  renderChannel->DrawNative();
419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
421f3dc22f7d19f750a47919196e6285fc21d81dae5leozwang@webrtc.orgvoid AndroidNativeOpenGl2Channel::DrawNative() {
42290cc3b95b795eee97f18abe8ad31b5d27cd74a9bbraveyao@webrtc.org  _renderCritSect.Enter();
423ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  _openGLRenderer.Render(_bufferToRender);
42490cc3b95b795eee97f18abe8ad31b5d27cd74a9bbraveyao@webrtc.org  _renderCritSect.Leave();
425470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
426ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org
427470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
428ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org * JNI callback from Java class. Called when the GLSurfaceview
429ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org * have created a surface. Called from the GLRenderThread
430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Method:    CreateOpenGLNativeStatic
431470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com * Signature: (JII)I
432470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
433ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.orgjint JNICALL AndroidNativeOpenGl2Channel::CreateOpenGLNativeStatic(
434ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    JNIEnv * env,
435ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    jobject,
436ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    jlong context,
437ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    jint width,
438ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    jint height) {
439ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  AndroidNativeOpenGl2Channel* renderChannel =
440ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org      reinterpret_cast<AndroidNativeOpenGl2Channel*> (context);
441ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, -1, "%s:", __FUNCTION__);
442ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  return renderChannel->CreateOpenGLNative(width, height);
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
445ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.orgjint AndroidNativeOpenGl2Channel::CreateOpenGLNative(
446ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org    int width, int height) {
447ac9fd8af0964158842792daf9e6ab1ba3bc748a7leozwang@webrtc.org  return _openGLRenderer.Setup(width, height);
448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
450d900e8bea84c474696bf0219aed1353ce65ffd8epbos@webrtc.org}  // namespace webrtc
451