From d4803ced607c552fac061d1381af907185fcd192 Mon Sep 17 00:00:00 2001 From: "yujie.mao@webrtc.org" Date: Mon, 1 Jul 2013 14:55:37 +0000 Subject: [PATCH] WebRTCViEDemo: Use global reference when passing variables across different threads There are JNI local reference changes in ICS when Android SDK target level API >= 14. http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html BUG=NONE TEST=WebRTCViEDemo works well using MediaCodec Decoder/Renderer R=fischman@webrtc.org Review URL: https://webrtc-codereview.appspot.com/1744004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@4283 4adac7df-926f-26a2-2b94-8c16560cd09d --- .../jni/android_media_codec_decoder.cc | 22 +++++++++++++++++-- .../android/jni/android_media_codec_decoder.h | 4 +++- .../test/android/jni/vie_android_java_api.cc | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/webrtc/video_engine/test/android/jni/android_media_codec_decoder.cc b/webrtc/video_engine/test/android/jni/android_media_codec_decoder.cc index 47dfb82772..d7ef87b440 100644 --- a/webrtc/video_engine/test/android/jni/android_media_codec_decoder.cc +++ b/webrtc/video_engine/test/android/jni/android_media_codec_decoder.cc @@ -21,12 +21,30 @@ AndroidMediaCodecDecoder::AndroidMediaCodecDecoder( JavaVM* vm, jobject surface, jclass decoderClass) : decode_complete_callback_(NULL), vm_(vm), - surface_(surface), + surface_(NULL), mediaCodecDecoder_(NULL), - decoderClass_(decoderClass), + decoderClass_(NULL), env_(NULL), setEncodedImageID_(NULL), vm_attached_(false) { + Initialize(vm, surface, decoderClass); +} + +AndroidMediaCodecDecoder::~AndroidMediaCodecDecoder() { + env_->DeleteGlobalRef(decoderClass_); + env_->DeleteGlobalRef(surface_); +} + +void AndroidMediaCodecDecoder::Initialize( + JavaVM* vm, jobject surface, jclass decoderClass) { + int ret = vm->GetEnv(reinterpret_cast(&env_), JNI_VERSION_1_4); + if ((ret < 0) || !env_) { + __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, + "Could not get JNI env (%d, %p)", ret, env_); + assert(false); + } + surface_ = env_->NewGlobalRef(surface); + decoderClass_ = reinterpret_cast(env_->NewGlobalRef(decoderClass)); } int32_t AndroidMediaCodecDecoder::InitDecode( diff --git a/webrtc/video_engine/test/android/jni/android_media_codec_decoder.h b/webrtc/video_engine/test/android/jni/android_media_codec_decoder.h index 029425c1a9..978d1f3eb3 100644 --- a/webrtc/video_engine/test/android/jni/android_media_codec_decoder.h +++ b/webrtc/video_engine/test/android/jni/android_media_codec_decoder.h @@ -18,7 +18,7 @@ namespace webrtc { class AndroidMediaCodecDecoder : public VideoDecoder { public: AndroidMediaCodecDecoder(JavaVM* vm, jobject surface, jclass decoderClass); - virtual ~AndroidMediaCodecDecoder() { } + virtual ~AndroidMediaCodecDecoder(); // Initialize the decoder with the information from the VideoCodec. // @@ -92,6 +92,8 @@ class AndroidMediaCodecDecoder : public VideoDecoder { virtual VideoDecoder* Copy() { return NULL; } private: + void Initialize(JavaVM* vm, jobject surface, jclass decoderClass); + DecodedImageCallback* decode_complete_callback_; JavaVM* vm_; jobject surface_; diff --git a/webrtc/video_engine/test/android/jni/vie_android_java_api.cc b/webrtc/video_engine/test/android/jni/vie_android_java_api.cc index ef744fb689..3455107356 100644 --- a/webrtc/video_engine/test/android/jni/vie_android_java_api.cc +++ b/webrtc/video_engine/test/android/jni/vie_android_java_api.cc @@ -34,6 +34,7 @@ #include "webrtc/common_types.h" #include "webrtc/video_engine/test/android/jni/android_media_codec_decoder.h" +#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h" #include "webrtc/system_wrappers/interface/scoped_ptr.h" #include "webrtc/test/channel_transport/include/channel_transport.h" @@ -1012,7 +1013,6 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetExter ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetExternalMediaCodecDecoder"); jclass cls = env->FindClass("org/webrtc/videoengine/ViEMediaCodecDecoder"); - env->NewGlobalRef(cls); AndroidMediaCodecDecoder* mediaCodecDecoder = new AndroidMediaCodecDecoder(webrtcGlobalVM, glSurface, cls); @@ -1020,7 +1020,7 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetExter // TODO(dwkang): Check the ownership of decoder object and release it // if needed. return vieData.externalCodec->RegisterExternalReceiveCodec( - channel, 120, mediaCodecDecoder, true); + channel, VCM_VP8_PAYLOAD_TYPE, mediaCodecDecoder, true); } /*