2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/modules/video_render/android/video_render_android_impl.h"
13 #include "webrtc/modules/video_render/video_render_internal.h"
14 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
15 #include "webrtc/system_wrappers/interface/event_wrapper.h"
16 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
17 #include "webrtc/system_wrappers/interface/tick_util.h"
20 #include <android/log.h>
24 #define WEBRTC_TRACE(a,b,c,...) __android_log_print(ANDROID_LOG_DEBUG, "*WEBRTCN*", __VA_ARGS__)
26 #include "webrtc/system_wrappers/interface/trace.h"
31 JavaVM* VideoRenderAndroid::g_jvm = NULL;
33 int32_t SetRenderAndroidVM(JavaVM* javaVM) {
34 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, -1, "%s", __FUNCTION__);
35 VideoRenderAndroid::g_jvm = javaVM;
39 VideoRenderAndroid::VideoRenderAndroid(
41 const VideoRenderType videoRenderType,
43 const bool /*fullscreen*/):
45 _critSect(*CriticalSectionWrapper::CreateCriticalSection()),
46 _renderType(videoRenderType),
47 _ptrWindow((jobject)(window)),
48 _javaShutDownFlag(false),
49 _javaShutdownEvent(*EventWrapper::Create()),
50 _javaRenderEvent(*EventWrapper::Create()),
51 _lastJavaRenderEvent(0),
52 _javaRenderJniEnv(NULL),
53 _javaRenderThread(NULL) {
56 VideoRenderAndroid::~VideoRenderAndroid() {
57 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
58 "VideoRenderAndroid dtor");
60 if (_javaRenderThread)
63 for (AndroidStreamMap::iterator it = _streamsMap.begin();
64 it != _streamsMap.end();
68 delete &_javaShutdownEvent;
69 delete &_javaRenderEvent;
73 int32_t VideoRenderAndroid::ChangeUniqueId(const int32_t id) {
74 CriticalSectionScoped cs(&_critSect);
80 int32_t VideoRenderAndroid::ChangeWindow(void* /*window*/) {
85 VideoRenderAndroid::AddIncomingRenderStream(const uint32_t streamId,
86 const uint32_t zOrder,
87 const float left, const float top,
90 CriticalSectionScoped cs(&_critSect);
92 AndroidStream* renderStream = NULL;
93 AndroidStreamMap::iterator item = _streamsMap.find(streamId);
94 if (item != _streamsMap.end() && item->second != NULL) {
95 WEBRTC_TRACE(kTraceInfo,
98 "%s: Render stream already exists",
103 renderStream = CreateAndroidRenderChannel(streamId, zOrder, left, top,
104 right, bottom, *this);
106 _streamsMap[streamId] = renderStream;
109 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
110 "(%s:%d): renderStream is NULL", __FUNCTION__, __LINE__);
116 int32_t VideoRenderAndroid::DeleteIncomingRenderStream(
117 const uint32_t streamId) {
118 CriticalSectionScoped cs(&_critSect);
120 AndroidStreamMap::iterator item = _streamsMap.find(streamId);
121 if (item == _streamsMap.end()) {
122 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
123 "(%s:%d): renderStream is NULL", __FUNCTION__, __LINE__);
127 _streamsMap.erase(item);
131 int32_t VideoRenderAndroid::GetIncomingRenderStreamProperties(
132 const uint32_t streamId,
137 float& bottom) const {
141 int32_t VideoRenderAndroid::StartRender() {
142 CriticalSectionScoped cs(&_critSect);
144 if (_javaRenderThread) {
145 // StartRender is called when this stream should start render.
146 // However StopRender is not called when the streams stop rendering.
147 // Thus the the thread is only deleted when the renderer is removed.
148 WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id,
149 "%s, Render thread already exist", __FUNCTION__);
153 _javaRenderThread = ThreadWrapper::CreateThread(JavaRenderThreadFun, this,
155 "AndroidRenderThread");
156 if (!_javaRenderThread) {
157 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
158 "%s: No thread", __FUNCTION__);
162 unsigned int tId = 0;
163 if (_javaRenderThread->Start(tId))
164 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
165 "%s: thread started: %u", __FUNCTION__, tId);
167 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
168 "%s: Could not start send thread", __FUNCTION__);
174 int32_t VideoRenderAndroid::StopRender() {
175 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s:", __FUNCTION__);
177 CriticalSectionScoped cs(&_critSect);
178 if (!_javaRenderThread)
182 _javaShutDownFlag = true;
183 _javaRenderEvent.Set();
186 _javaShutdownEvent.Wait(3000);
187 CriticalSectionScoped cs(&_critSect);
188 _javaRenderThread->SetNotAlive();
189 if (_javaRenderThread->Stop()) {
190 delete _javaRenderThread;
191 _javaRenderThread = NULL;
195 WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
196 "%s: Not able to stop thread, leaking", __FUNCTION__);
197 _javaRenderThread = NULL;
202 void VideoRenderAndroid::ReDraw() {
203 CriticalSectionScoped cs(&_critSect);
204 // Allow redraw if it was more than 20ms since last.
205 if (_lastJavaRenderEvent < TickTime::MillisecondTimestamp() - 20) {
206 _lastJavaRenderEvent = TickTime::MillisecondTimestamp();
207 _javaRenderEvent.Set();
211 bool VideoRenderAndroid::JavaRenderThreadFun(void* obj) {
212 return static_cast<VideoRenderAndroid*> (obj)->JavaRenderThreadProcess();
215 bool VideoRenderAndroid::JavaRenderThreadProcess()
217 _javaRenderEvent.Wait(1000);
219 CriticalSectionScoped cs(&_critSect);
220 if (!_javaRenderJniEnv) {
221 // try to attach the thread and get the env
222 // Attach this thread to JVM
223 jint res = g_jvm->AttachCurrentThread(&_javaRenderJniEnv, NULL);
225 // Get the JNI env for this thread
226 if ((res < 0) || !_javaRenderJniEnv) {
227 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
228 "%s: Could not attach thread to JVM (%d, %p)",
229 __FUNCTION__, res, _javaRenderJniEnv);
234 for (AndroidStreamMap::iterator it = _streamsMap.begin();
235 it != _streamsMap.end();
237 it->second->DeliverFrame(_javaRenderJniEnv);
240 if (_javaShutDownFlag) {
241 if (g_jvm->DetachCurrentThread() < 0)
242 WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id,
243 "%s: Could not detach thread from JVM", __FUNCTION__);
245 WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id,
246 "%s: Java thread detached", __FUNCTION__);
248 _javaRenderJniEnv = NULL;
249 _javaShutDownFlag = false;
250 _javaShutdownEvent.Set();
251 return false; // Do not run this thread again.
256 VideoRenderType VideoRenderAndroid::RenderType() {
260 RawVideoType VideoRenderAndroid::PerferedVideoType() {
264 bool VideoRenderAndroid::FullScreen() {
268 int32_t VideoRenderAndroid::GetGraphicsMemory(
269 uint64_t& /*totalGraphicsMemory*/,
270 uint64_t& /*availableGraphicsMemory*/) const {
271 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
272 "%s - not supported on Android", __FUNCTION__);
276 int32_t VideoRenderAndroid::GetScreenResolution(
277 uint32_t& /*screenWidth*/,
278 uint32_t& /*screenHeight*/) const {
279 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
280 "%s - not supported on Android", __FUNCTION__);
284 uint32_t VideoRenderAndroid::RenderFrameRate(
285 const uint32_t /*streamId*/) {
286 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
287 "%s - not supported on Android", __FUNCTION__);
291 int32_t VideoRenderAndroid::SetStreamCropping(
292 const uint32_t /*streamId*/,
293 const float /*left*/,
295 const float /*right*/,
296 const float /*bottom*/) {
297 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
298 "%s - not supported on Android", __FUNCTION__);
302 int32_t VideoRenderAndroid::SetTransparentBackground(const bool enable) {
303 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
304 "%s - not supported on Android", __FUNCTION__);
308 int32_t VideoRenderAndroid::ConfigureRenderer(
309 const uint32_t streamId,
310 const unsigned int zOrder,
314 const float bottom) {
315 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
316 "%s - not supported on Android", __FUNCTION__);
320 int32_t VideoRenderAndroid::SetText(
321 const uint8_t textId,
323 const int32_t textLength,
324 const uint32_t textColorRef,
325 const uint32_t backgroundColorRef,
326 const float left, const float top,
327 const float rigth, const float bottom) {
328 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
329 "%s - not supported on Android", __FUNCTION__);
333 int32_t VideoRenderAndroid::SetBitmap(const void* bitMap,
334 const uint8_t pictureId,
335 const void* colorKey,
336 const float left, const float top,
338 const float bottom) {
339 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
340 "%s - not supported on Android", __FUNCTION__);
344 } // namespace webrtc