diff options
author | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2016-07-01 09:59:13 +0200 |
---|---|---|
committer | Matthieu Bouron <matthieu.bouron@stupeflix.com> | 2016-07-27 15:43:39 +0200 |
commit | 376d8fb2c5742e6718323d6a69479c6ee68dd75b (patch) | |
tree | bcf8a1bc9c40fd3b46359cc481632fad95855082 /libavcodec/ffjni.c | |
parent | 293676c476733e81d7b596736add6cd510eb6960 (diff) | |
download | ffmpeg-376d8fb2c5742e6718323d6a69479c6ee68dd75b.tar.gz |
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.c | 43 |
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(¤t_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; |