diff options
author | Andreas Huber <andih@google.com> | 2013-08-12 09:19:45 -0700 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2013-08-12 09:23:49 -0700 |
commit | 8d5f3e31c914e29129f50fe9830d71adf52ab5cf (patch) | |
tree | 6f59027499de3b89add6dfd870eb1ee5222cde45 /media/jni/android_media_Utils.cpp | |
parent | 9a68f82f3730432399618bf2e4f73208f84dc87f (diff) |
Manage jclass objects (and most jobjects) in jni code using ScopedLocalRef
for safer refcounting. Previously jclass objects were not DeleteLocalRef'ed
at all, leading us to exhaust the local ref pool quickly in certain
circumstances.
This change also makes sure we properly serialize int64_t entries when
converting from AMessage to HashMap and boosts thread priority for
java-instantiated MediaCodecs slightly from NORMAL to FOREGROUND.
Change-Id: I4ebdd8a5ca6b3442698c9f86fcc31af8c199aaf5
Diffstat (limited to 'media/jni/android_media_Utils.cpp')
-rw-r--r-- | media/jni/android_media_Utils.cpp | 97 |
1 files changed, 55 insertions, 42 deletions
diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp index e35ace38829e..54c5e9bdd267 100644 --- a/media/jni/android_media_Utils.cpp +++ b/media/jni/android_media_Utils.cpp @@ -24,6 +24,8 @@ #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/AMessage.h> +#include <nativehelper/ScopedLocalRef.h> + namespace android { bool ConvertKeyValueArraysToKeyedVector( @@ -76,33 +78,35 @@ bool ConvertKeyValueArraysToKeyedVector( } static jobject makeIntegerObject(JNIEnv *env, int32_t value) { - jclass clazz = env->FindClass("java/lang/Integer"); - CHECK(clazz != NULL); + ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Integer")); + CHECK(clazz.get() != NULL); - jmethodID integerConstructID = env->GetMethodID(clazz, "<init>", "(I)V"); + jmethodID integerConstructID = + env->GetMethodID(clazz.get(), "<init>", "(I)V"); CHECK(integerConstructID != NULL); - return env->NewObject(clazz, integerConstructID, value); + return env->NewObject(clazz.get(), integerConstructID, value); } static jobject makeLongObject(JNIEnv *env, int64_t value) { - jclass clazz = env->FindClass("java/lang/Long"); - CHECK(clazz != NULL); + ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Long")); + CHECK(clazz.get() != NULL); - jmethodID longConstructID = env->GetMethodID(clazz, "<init>", "(J)V"); + jmethodID longConstructID = env->GetMethodID(clazz.get(), "<init>", "(J)V"); CHECK(longConstructID != NULL); - return env->NewObject(clazz, longConstructID, value); + return env->NewObject(clazz.get(), longConstructID, value); } static jobject makeFloatObject(JNIEnv *env, float value) { - jclass clazz = env->FindClass("java/lang/Float"); - CHECK(clazz != NULL); + ScopedLocalRef<jclass> clazz(env, env->FindClass("java/lang/Float")); + CHECK(clazz.get() != NULL); - jmethodID floatConstructID = env->GetMethodID(clazz, "<init>", "(F)V"); + jmethodID floatConstructID = + env->GetMethodID(clazz.get(), "<init>", "(F)V"); CHECK(floatConstructID != NULL); - return env->NewObject(clazz, floatConstructID, value); + return env->NewObject(clazz.get(), floatConstructID, value); } static jobject makeByteBufferObject( @@ -110,15 +114,16 @@ static jobject makeByteBufferObject( jbyteArray byteArrayObj = env->NewByteArray(size); env->SetByteArrayRegion(byteArrayObj, 0, size, (const jbyte *)data); - jclass clazz = env->FindClass("java/nio/ByteBuffer"); - CHECK(clazz != NULL); + ScopedLocalRef<jclass> clazz(env, env->FindClass("java/nio/ByteBuffer")); + CHECK(clazz.get() != NULL); jmethodID byteBufWrapID = - env->GetStaticMethodID(clazz, "wrap", "([B)Ljava/nio/ByteBuffer;"); + env->GetStaticMethodID( + clazz.get(), "wrap", "([B)Ljava/nio/ByteBuffer;"); CHECK(byteBufWrapID != NULL); jobject byteBufObj = env->CallStaticObjectMethod( - clazz, byteBufWrapID, byteArrayObj); + clazz.get(), byteBufWrapID, byteArrayObj); env->DeleteLocalRef(byteArrayObj); byteArrayObj = NULL; @@ -140,14 +145,15 @@ static void SetMapInt32( status_t ConvertMessageToMap( JNIEnv *env, const sp<AMessage> &msg, jobject *map) { - jclass hashMapClazz = env->FindClass("java/util/HashMap"); + ScopedLocalRef<jclass> hashMapClazz( + env, env->FindClass("java/util/HashMap")); - if (hashMapClazz == NULL) { + if (hashMapClazz.get() == NULL) { return -EINVAL; } jmethodID hashMapConstructID = - env->GetMethodID(hashMapClazz, "<init>", "()V"); + env->GetMethodID(hashMapClazz.get(), "<init>", "()V"); if (hashMapConstructID == NULL) { return -EINVAL; @@ -155,7 +161,7 @@ status_t ConvertMessageToMap( jmethodID hashMapPutID = env->GetMethodID( - hashMapClazz, + hashMapClazz.get(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); @@ -163,7 +169,7 @@ status_t ConvertMessageToMap( return -EINVAL; } - jobject hashMap = env->NewObject(hashMapClazz, hashMapConstructID); + jobject hashMap = env->NewObject(hashMapClazz.get(), hashMapConstructID); for (size_t i = 0; i < msg->countEntries(); ++i) { AMessage::Type valueType; @@ -276,17 +282,16 @@ status_t ConvertMessageToMap( status_t ConvertKeyValueArraysToMessage( JNIEnv *env, jobjectArray keys, jobjectArray values, sp<AMessage> *out) { - jclass stringClass = env->FindClass("java/lang/String"); - CHECK(stringClass != NULL); - - jclass integerClass = env->FindClass("java/lang/Integer"); - CHECK(integerClass != NULL); - - jclass floatClass = env->FindClass("java/lang/Float"); - CHECK(floatClass != NULL); - - jclass byteBufClass = env->FindClass("java/nio/ByteBuffer"); - CHECK(byteBufClass != NULL); + ScopedLocalRef<jclass> stringClass(env, env->FindClass("java/lang/String")); + CHECK(stringClass.get() != NULL); + ScopedLocalRef<jclass> integerClass(env, env->FindClass("java/lang/Integer")); + CHECK(integerClass.get() != NULL); + ScopedLocalRef<jclass> longClass(env, env->FindClass("java/lang/Long")); + CHECK(longClass.get() != NULL); + ScopedLocalRef<jclass> floatClass(env, env->FindClass("java/lang/Float")); + CHECK(floatClass.get() != NULL); + ScopedLocalRef<jclass> byteBufClass(env, env->FindClass("java/nio/ByteBuffer")); + CHECK(byteBufClass.get() != NULL); sp<AMessage> msg = new AMessage; @@ -309,7 +314,7 @@ status_t ConvertKeyValueArraysToMessage( for (jsize i = 0; i < numEntries; ++i) { jobject keyObj = env->GetObjectArrayElement(keys, i); - if (!env->IsInstanceOf(keyObj, stringClass)) { + if (!env->IsInstanceOf(keyObj, stringClass.get())) { return -EINVAL; } @@ -326,7 +331,7 @@ status_t ConvertKeyValueArraysToMessage( jobject valueObj = env->GetObjectArrayElement(values, i); - if (env->IsInstanceOf(valueObj, stringClass)) { + if (env->IsInstanceOf(valueObj, stringClass.get())) { const char *value = env->GetStringUTFChars((jstring)valueObj, NULL); if (value == NULL) { @@ -337,29 +342,37 @@ status_t ConvertKeyValueArraysToMessage( env->ReleaseStringUTFChars((jstring)valueObj, value); value = NULL; - } else if (env->IsInstanceOf(valueObj, integerClass)) { + } else if (env->IsInstanceOf(valueObj, integerClass.get())) { jmethodID intValueID = - env->GetMethodID(integerClass, "intValue", "()I"); + env->GetMethodID(integerClass.get(), "intValue", "()I"); CHECK(intValueID != NULL); jint value = env->CallIntMethod(valueObj, intValueID); msg->setInt32(key.c_str(), value); - } else if (env->IsInstanceOf(valueObj, floatClass)) { + } else if (env->IsInstanceOf(valueObj, longClass.get())) { + jmethodID longValueID = + env->GetMethodID(longClass.get(), "longValue", "()J"); + CHECK(longValueID != NULL); + + jlong value = env->CallLongMethod(valueObj, longValueID); + + msg->setInt64(key.c_str(), value); + } else if (env->IsInstanceOf(valueObj, floatClass.get())) { jmethodID floatValueID = - env->GetMethodID(floatClass, "floatValue", "()F"); + env->GetMethodID(floatClass.get(), "floatValue", "()F"); CHECK(floatValueID != NULL); jfloat value = env->CallFloatMethod(valueObj, floatValueID); msg->setFloat(key.c_str(), value); - } else if (env->IsInstanceOf(valueObj, byteBufClass)) { + } else if (env->IsInstanceOf(valueObj, byteBufClass.get())) { jmethodID positionID = - env->GetMethodID(byteBufClass, "position", "()I"); + env->GetMethodID(byteBufClass.get(), "position", "()I"); CHECK(positionID != NULL); jmethodID limitID = - env->GetMethodID(byteBufClass, "limit", "()I"); + env->GetMethodID(byteBufClass.get(), "limit", "()I"); CHECK(limitID != NULL); jint position = env->CallIntMethod(valueObj, positionID); @@ -375,7 +388,7 @@ status_t ConvertKeyValueArraysToMessage( buffer->size()); } else { jmethodID arrayID = - env->GetMethodID(byteBufClass, "array", "()[B"); + env->GetMethodID(byteBufClass.get(), "array", "()[B"); CHECK(arrayID != NULL); jbyteArray byteArray = |