Commit 16c0f37b authored by Thomas Guillem's avatar Thomas Guillem Committed by Jean-Baptiste Kempf

android: simplify/improve the attachment of a thread to the Java VM

There is now only one way to get a JNIEnv: jni_get_env. This function use the
thread-specific data (TSD) areas to save a JNIEnv into a TSD key. The thread
will be automatically detached to the Java VM when it's canceled or exited.
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 70a0829a
......@@ -149,10 +149,7 @@ struct thread_cmd
};
#define THREAD_NAME "android_audiotrack"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern int jni_get_env(JNIEnv **env);
extern JNIEnv *jni_get_env(const char *name);
static struct
{
......@@ -220,7 +217,7 @@ InitJNIFields( audio_output_t *p_aout )
{
static vlc_mutex_t lock = VLC_STATIC_MUTEX;
static int i_init_state = -1;
bool ret, b_attached = false;
bool ret;
jclass clazz;
jfieldID field;
JNIEnv* env = NULL;
......@@ -230,15 +227,10 @@ InitJNIFields( audio_output_t *p_aout )
if( i_init_state != -1 )
goto end;
if( jni_get_env(&env) < 0 )
if (!(env = jni_get_env(THREAD_NAME)))
{
jni_attach_thread( &env, THREAD_NAME );
if( !env )
{
i_init_state = 0;
goto end;
}
b_attached = true;
i_init_state = 0;
goto end;
}
#define CHECK_EXCEPTION( what, critical ) do { \
......@@ -378,8 +370,6 @@ end:
ret = i_init_state == 1;
if( !ret )
msg_Err( p_aout, "AudioTrack jni init failed" );
if( b_attached )
jni_detach_thread();
vlc_mutex_unlock( &lock );
return ret;
}
......@@ -1264,7 +1254,7 @@ JNIThread( void *data )
mtime_t i_play_deadline = 0;
JNIEnv* env;
jni_attach_thread( &env, THREAD_NAME );
env = jni_get_env(THREAD_NAME);
vlc_mutex_lock( &p_sys->mutex );
if( !env )
......@@ -1420,7 +1410,6 @@ end:
(*env)->DeleteGlobalRef( env, p_sys->p_floatarray );
if( p_sys->p_bytebuffer )
(*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer );
jni_detach_thread();
}
vlc_mutex_unlock( &p_sys->mutex );
return NULL;
......
......@@ -49,9 +49,8 @@
#define INFO_TRY_AGAIN_LATER -1
#define THREAD_NAME "android_mediacodec"
extern JNIEnv *jni_get_env(const char *name);
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
/* JNI functions to get/set an Android Surface object. */
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
......@@ -372,7 +371,8 @@ static int OpenDecoder(vlc_object_t *p_this)
p_dec->b_need_packetized = true;
JNIEnv* env = NULL;
jni_attach_thread(&env, THREAD_NAME);
if (!(env = jni_get_env(THREAD_NAME)))
goto error;
for (int i = 0; classes[i].name; i++) {
*(jclass*)((uint8_t*)p_sys + classes[i].offset) =
......@@ -651,8 +651,6 @@ loopclean:
p_sys->buffer_info = (*env)->NewGlobalRef(env, p_sys->buffer_info);
(*env)->DeleteLocalRef(env, format);
jni_detach_thread();
const int timestamp_fifo_size = 32;
p_sys->timestamp_fifo = timestamp_FifoNew(timestamp_fifo_size);
if (!p_sys->timestamp_fifo)
......@@ -661,7 +659,6 @@ loopclean:
return VLC_SUCCESS;
error:
jni_detach_thread();
CloseDecoder(p_this);
return VLC_EGENERIC;
}
......@@ -679,7 +676,10 @@ static void CloseDecoder(vlc_object_t *p_this)
* to prevent the vout from using destroyed output buffers. */
if (p_sys->direct_rendering)
InvalidateAllPictures(p_dec);
jni_attach_thread(&env, THREAD_NAME);
if (!(env = jni_get_env(THREAD_NAME)))
goto cleanup;
if (p_sys->input_buffers)
(*env)->DeleteGlobalRef(env, p_sys->input_buffers);
if (p_sys->output_buffers)
......@@ -701,8 +701,8 @@ static void CloseDecoder(vlc_object_t *p_this)
}
if (p_sys->buffer_info)
(*env)->DeleteGlobalRef(env, p_sys->buffer_info);
jni_detach_thread();
cleanup:
free(p_sys->name);
ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
free(p_sys->pp_inflight_pictures);
......@@ -752,9 +752,8 @@ static void UnlockPicture(picture_t* p_pic, bool b_render)
/* Release the MediaCodec buffer. */
JNIEnv *env = NULL;
jni_attach_thread(&env, THREAD_NAME);
ReleaseOutputBuffer(p_dec, env, i_index, b_render);
jni_detach_thread();
if ((env = jni_get_env(THREAD_NAME)))
ReleaseOutputBuffer(p_dec, env, i_index, b_render);
p_picsys->priv.hw.b_valid = false;
vlc_mutex_unlock(get_android_opaque_mutex());
......@@ -1020,8 +1019,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
if (p_sys->error_state)
goto endclean;
jni_attach_thread(&env, THREAD_NAME);
if (!env)
if (!(env = jni_get_env(THREAD_NAME)))
goto endclean;
if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
......@@ -1115,8 +1113,6 @@ endclean:
p_sys->error_event_sent = true;
}
}
if (env != NULL)
jni_detach_thread();
return p_pic;
}
......@@ -68,8 +68,7 @@
#if defined(USE_IOMX)
/* JNI functions to get/set an Android Surface object. */
#define THREAD_NAME "omxil"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern JNIEnv *jni_get_env(const char *name);
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
extern bool jni_IsVideoPlayerActivityCreated();
......@@ -2096,9 +2095,8 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
goto error;
}
jni_attach_thread( &p_env, THREAD_NAME );
p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
jni_detach_thread();
if ((p_env = jni_get_env(THREAD_NAME)))
p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
jni_UnlockAndroidSurface();
if( !p_port->p_hwbuf->window ) {
......
......@@ -66,8 +66,7 @@ vlc_module_end()
*****************************************************************************/
#define THREAD_NAME "android_window"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern JNIEnv *jni_get_env(const char *name);
extern jobject jni_LockAndGetAndroidJavaSurface();
extern jobject jni_LockAndGetSubtitlesSurface();
......@@ -368,11 +367,9 @@ static int AndroidWindow_SetSurface(vout_display_sys_t *sys,
if (!p_window->p_handle && !p_window->b_opaque) {
JNIEnv *p_env;
jni_attach_thread(&p_env, THREAD_NAME);
if (!p_env)
if (!(p_env = jni_get_env(THREAD_NAME)))
return -1;
p_window->p_handle = sys->anw.winFromSurface(p_env, p_window->jsurf);
jni_detach_thread();
if (!p_window->p_handle)
return -1;
}
......
......@@ -38,8 +38,7 @@
#include "utils.h"
#define THREAD_NAME "ANativeWindow"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern JNIEnv *jni_get_env(const char *name);
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
extern void jni_SetSurfaceLayout(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
......@@ -95,9 +94,9 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
goto error;
JNIEnv *p_env;
jni_attach_thread(&p_env, THREAD_NAME);
if (!(p_env = jni_get_env(THREAD_NAME)))
goto error;
p_sys->window = p_sys->native_window.winFromSurface(p_env, javaSurface); // ANativeWindow_fromSurface call.
jni_detach_thread();
jni_UnlockAndroidSurface();
......
......@@ -73,9 +73,6 @@ vlc_module_end()
* JNI prototypes
*****************************************************************************/
#define THREAD_NAME "AndroidSurface"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface();
extern void *jni_AndroidJavaSurfaceToNativeSurface(jobject surf);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment