summaryrefslogtreecommitdiff
path: root/libavcodec/ffjni.c
diff options
context:
space:
mode:
authorMatthieu Bouron <matthieu.bouron@stupeflix.com>2016-07-01 09:59:13 +0200
committerMatthieu Bouron <matthieu.bouron@stupeflix.com>2016-07-27 15:43:39 +0200
commit376d8fb2c5742e6718323d6a69479c6ee68dd75b (patch)
treebcf8a1bc9c40fd3b46359cc481632fad95855082 /libavcodec/ffjni.c
parent293676c476733e81d7b596736add6cd510eb6960 (diff)
lavc/ffjni: replace ff_jni_{attach,detach} with ff_jni_get_env
If a JNI environment is not already attached to the thread where the MediaCodec calls are made the current implementation will attach / detach an environment for each MediaCodec call wasting some CPU time. ff_jni_get_env replaces ff_jni_{attach,detach} by permanently attaching an environment (if it is not already the case) to the current thread. The environment will be automatically detached at the thread destruction using a pthread_key callback. Saves around 5% of CPU time (out of 20%) while decoding a stream with MediaCodec.
Diffstat (limited to 'libavcodec/ffjni.c')
-rw-r--r--libavcodec/ffjni.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/libavcodec/ffjni.c b/libavcodec/ffjni.c
index 82ee5d32ae..13eabb0033 100644
--- a/libavcodec/ffjni.c
+++ b/libavcodec/ffjni.c
@@ -31,25 +31,42 @@
#include "jni.h"
#include "ffjni.h"
-static JavaVM *java_vm = NULL;
+static JavaVM *java_vm;
+static pthread_key_t current_env;
+static pthread_once_t once = PTHREAD_ONCE_INIT;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-JNIEnv *ff_jni_attach_env(int *attached, void *log_ctx)
+static void jni_detach_env(void *data)
+{
+ if (java_vm) {
+ (*java_vm)->DetachCurrentThread(java_vm);
+ }
+}
+
+static void jni_create_pthread_key(void)
+{
+ pthread_key_create(&current_env, jni_detach_env);
+}
+
+JNIEnv *ff_jni_get_env(void *log_ctx)
{
int ret = 0;
JNIEnv *env = NULL;
- *attached = 0;
-
pthread_mutex_lock(&lock);
if (java_vm == NULL) {
java_vm = av_jni_get_java_vm(log_ctx);
}
- pthread_mutex_unlock(&lock);
if (!java_vm) {
av_log(log_ctx, AV_LOG_ERROR, "No Java virtual machine has been registered\n");
- return NULL;
+ goto done;
+ }
+
+ pthread_once(&once, jni_create_pthread_key);
+
+ if ((env = pthread_getspecific(current_env)) != NULL) {
+ goto done;
}
ret = (*java_vm)->GetEnv(java_vm, (void **)&env, JNI_VERSION_1_6);
@@ -59,7 +76,7 @@ JNIEnv *ff_jni_attach_env(int *attached, void *log_ctx)
av_log(log_ctx, AV_LOG_ERROR, "Failed to attach the JNI environment to the current thread\n");
env = NULL;
} else {
- *attached = 1;
+ pthread_setspecific(current_env, env);
}
break;
case JNI_OK:
@@ -72,19 +89,11 @@ JNIEnv *ff_jni_attach_env(int *attached, void *log_ctx)
break;
}
+done:
+ pthread_mutex_unlock(&lock);
return env;
}
-int ff_jni_detach_env(void *log_ctx)
-{
- if (java_vm == NULL) {
- av_log(log_ctx, AV_LOG_ERROR, "No Java virtual machine has been registered\n");
- return AVERROR(EINVAL);
- }
-
- return (*java_vm)->DetachCurrentThread(java_vm);
-}
-
char *ff_jni_jstring_to_utf_chars(JNIEnv *env, jstring string, void *log_ctx)
{
char *ret = NULL;