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 ...@@ -149,10 +149,7 @@ struct thread_cmd
}; };
#define THREAD_NAME "android_audiotrack" #define THREAD_NAME "android_audiotrack"
extern JNIEnv *jni_get_env(const char *name);
extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
extern void jni_detach_thread();
extern int jni_get_env(JNIEnv **env);
static struct static struct
{ {
...@@ -220,7 +217,7 @@ InitJNIFields( audio_output_t *p_aout ) ...@@ -220,7 +217,7 @@ InitJNIFields( audio_output_t *p_aout )
{ {
static vlc_mutex_t lock = VLC_STATIC_MUTEX; static vlc_mutex_t lock = VLC_STATIC_MUTEX;
static int i_init_state = -1; static int i_init_state = -1;
bool ret, b_attached = false; bool ret;
jclass clazz; jclass clazz;
jfieldID field; jfieldID field;
JNIEnv* env = NULL; JNIEnv* env = NULL;
...@@ -230,15 +227,10 @@ InitJNIFields( audio_output_t *p_aout ) ...@@ -230,15 +227,10 @@ InitJNIFields( audio_output_t *p_aout )
if( i_init_state != -1 ) if( i_init_state != -1 )
goto end; goto end;
if( jni_get_env(&env) < 0 ) if (!(env = jni_get_env(THREAD_NAME)))
{ {
jni_attach_thread( &env, THREAD_NAME ); i_init_state = 0;
if( !env ) goto end;
{
i_init_state = 0;
goto end;
}
b_attached = true;
} }
#define CHECK_EXCEPTION( what, critical ) do { \ #define CHECK_EXCEPTION( what, critical ) do { \
...@@ -378,8 +370,6 @@ end: ...@@ -378,8 +370,6 @@ end:
ret = i_init_state == 1; ret = i_init_state == 1;
if( !ret ) if( !ret )
msg_Err( p_aout, "AudioTrack jni init failed" ); msg_Err( p_aout, "AudioTrack jni init failed" );
if( b_attached )
jni_detach_thread();
vlc_mutex_unlock( &lock ); vlc_mutex_unlock( &lock );
return ret; return ret;
} }
...@@ -1264,7 +1254,7 @@ JNIThread( void *data ) ...@@ -1264,7 +1254,7 @@ JNIThread( void *data )
mtime_t i_play_deadline = 0; mtime_t i_play_deadline = 0;
JNIEnv* env; JNIEnv* env;
jni_attach_thread( &env, THREAD_NAME ); env = jni_get_env(THREAD_NAME);
vlc_mutex_lock( &p_sys->mutex ); vlc_mutex_lock( &p_sys->mutex );
if( !env ) if( !env )
...@@ -1420,7 +1410,6 @@ end: ...@@ -1420,7 +1410,6 @@ end:
(*env)->DeleteGlobalRef( env, p_sys->p_floatarray ); (*env)->DeleteGlobalRef( env, p_sys->p_floatarray );
if( p_sys->p_bytebuffer ) if( p_sys->p_bytebuffer )
(*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer ); (*env)->DeleteGlobalRef( env, p_sys->p_bytebuffer );
jni_detach_thread();
} }
vlc_mutex_unlock( &p_sys->mutex ); vlc_mutex_unlock( &p_sys->mutex );
return NULL; return NULL;
......
...@@ -49,9 +49,8 @@ ...@@ -49,9 +49,8 @@
#define INFO_TRY_AGAIN_LATER -1 #define INFO_TRY_AGAIN_LATER -1
#define THREAD_NAME "android_mediacodec" #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. */ /* JNI functions to get/set an Android Surface object. */
extern jobject jni_LockAndGetAndroidJavaSurface(); extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface(); extern void jni_UnlockAndroidSurface();
...@@ -372,7 +371,8 @@ static int OpenDecoder(vlc_object_t *p_this) ...@@ -372,7 +371,8 @@ static int OpenDecoder(vlc_object_t *p_this)
p_dec->b_need_packetized = true; p_dec->b_need_packetized = true;
JNIEnv* env = NULL; 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++) { for (int i = 0; classes[i].name; i++) {
*(jclass*)((uint8_t*)p_sys + classes[i].offset) = *(jclass*)((uint8_t*)p_sys + classes[i].offset) =
...@@ -651,8 +651,6 @@ loopclean: ...@@ -651,8 +651,6 @@ loopclean:
p_sys->buffer_info = (*env)->NewGlobalRef(env, p_sys->buffer_info); p_sys->buffer_info = (*env)->NewGlobalRef(env, p_sys->buffer_info);
(*env)->DeleteLocalRef(env, format); (*env)->DeleteLocalRef(env, format);
jni_detach_thread();
const int timestamp_fifo_size = 32; const int timestamp_fifo_size = 32;
p_sys->timestamp_fifo = timestamp_FifoNew(timestamp_fifo_size); p_sys->timestamp_fifo = timestamp_FifoNew(timestamp_fifo_size);
if (!p_sys->timestamp_fifo) if (!p_sys->timestamp_fifo)
...@@ -661,7 +659,6 @@ loopclean: ...@@ -661,7 +659,6 @@ loopclean:
return VLC_SUCCESS; return VLC_SUCCESS;
error: error:
jni_detach_thread();
CloseDecoder(p_this); CloseDecoder(p_this);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -679,7 +676,10 @@ static void CloseDecoder(vlc_object_t *p_this) ...@@ -679,7 +676,10 @@ static void CloseDecoder(vlc_object_t *p_this)
* to prevent the vout from using destroyed output buffers. */ * to prevent the vout from using destroyed output buffers. */
if (p_sys->direct_rendering) if (p_sys->direct_rendering)
InvalidateAllPictures(p_dec); InvalidateAllPictures(p_dec);
jni_attach_thread(&env, THREAD_NAME);
if (!(env = jni_get_env(THREAD_NAME)))
goto cleanup;
if (p_sys->input_buffers) if (p_sys->input_buffers)
(*env)->DeleteGlobalRef(env, p_sys->input_buffers); (*env)->DeleteGlobalRef(env, p_sys->input_buffers);
if (p_sys->output_buffers) if (p_sys->output_buffers)
...@@ -701,8 +701,8 @@ static void CloseDecoder(vlc_object_t *p_this) ...@@ -701,8 +701,8 @@ static void CloseDecoder(vlc_object_t *p_this)
} }
if (p_sys->buffer_info) if (p_sys->buffer_info)
(*env)->DeleteGlobalRef(env, p_sys->buffer_info); (*env)->DeleteGlobalRef(env, p_sys->buffer_info);
jni_detach_thread();
cleanup:
free(p_sys->name); free(p_sys->name);
ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data); ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format, &p_sys->architecture_specific_data);
free(p_sys->pp_inflight_pictures); free(p_sys->pp_inflight_pictures);
...@@ -752,9 +752,8 @@ static void UnlockPicture(picture_t* p_pic, bool b_render) ...@@ -752,9 +752,8 @@ static void UnlockPicture(picture_t* p_pic, bool b_render)
/* Release the MediaCodec buffer. */ /* Release the MediaCodec buffer. */
JNIEnv *env = NULL; JNIEnv *env = NULL;
jni_attach_thread(&env, THREAD_NAME); if ((env = jni_get_env(THREAD_NAME)))
ReleaseOutputBuffer(p_dec, env, i_index, b_render); ReleaseOutputBuffer(p_dec, env, i_index, b_render);
jni_detach_thread();
p_picsys->priv.hw.b_valid = false; p_picsys->priv.hw.b_valid = false;
vlc_mutex_unlock(get_android_opaque_mutex()); vlc_mutex_unlock(get_android_opaque_mutex());
...@@ -1020,8 +1019,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block) ...@@ -1020,8 +1019,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec, block_t **pp_block)
if (p_sys->error_state) if (p_sys->error_state)
goto endclean; goto endclean;
jni_attach_thread(&env, THREAD_NAME); if (!(env = jni_get_env(THREAD_NAME)))
if (!env)
goto endclean; goto endclean;
if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) { if ((*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) {
...@@ -1115,8 +1113,6 @@ endclean: ...@@ -1115,8 +1113,6 @@ endclean:
p_sys->error_event_sent = true; p_sys->error_event_sent = true;
} }
} }
if (env != NULL)
jni_detach_thread();
return p_pic; return p_pic;
} }
...@@ -68,8 +68,7 @@ ...@@ -68,8 +68,7 @@
#if defined(USE_IOMX) #if defined(USE_IOMX)
/* JNI functions to get/set an Android Surface object. */ /* JNI functions to get/set an Android Surface object. */
#define THREAD_NAME "omxil" #define THREAD_NAME "omxil"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name); extern JNIEnv *jni_get_env(const char *name);
extern void jni_detach_thread();
extern jobject jni_LockAndGetAndroidJavaSurface(); extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface(); extern void jni_UnlockAndroidSurface();
extern bool jni_IsVideoPlayerActivityCreated(); extern bool jni_IsVideoPlayerActivityCreated();
...@@ -2096,9 +2095,8 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port ) ...@@ -2096,9 +2095,8 @@ static void HwBuffer_Init( decoder_t *p_dec, OmxPort *p_port )
goto error; goto error;
} }
jni_attach_thread( &p_env, THREAD_NAME ); if ((p_env = jni_get_env(THREAD_NAME)))
p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf ); p_port->p_hwbuf->window = p_port->p_hwbuf->native_window.winFromSurface( p_env, surf );
jni_detach_thread();
jni_UnlockAndroidSurface(); jni_UnlockAndroidSurface();
if( !p_port->p_hwbuf->window ) { if( !p_port->p_hwbuf->window ) {
......
...@@ -66,8 +66,7 @@ vlc_module_end() ...@@ -66,8 +66,7 @@ vlc_module_end()
*****************************************************************************/ *****************************************************************************/
#define THREAD_NAME "android_window" #define THREAD_NAME "android_window"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name); extern JNIEnv *jni_get_env(const char *name);
extern void jni_detach_thread();
extern jobject jni_LockAndGetAndroidJavaSurface(); extern jobject jni_LockAndGetAndroidJavaSurface();
extern jobject jni_LockAndGetSubtitlesSurface(); extern jobject jni_LockAndGetSubtitlesSurface();
...@@ -368,11 +367,9 @@ static int AndroidWindow_SetSurface(vout_display_sys_t *sys, ...@@ -368,11 +367,9 @@ static int AndroidWindow_SetSurface(vout_display_sys_t *sys,
if (!p_window->p_handle && !p_window->b_opaque) { if (!p_window->p_handle && !p_window->b_opaque) {
JNIEnv *p_env; JNIEnv *p_env;
jni_attach_thread(&p_env, THREAD_NAME); if (!(p_env = jni_get_env(THREAD_NAME)))
if (!p_env)
return -1; return -1;
p_window->p_handle = sys->anw.winFromSurface(p_env, p_window->jsurf); p_window->p_handle = sys->anw.winFromSurface(p_env, p_window->jsurf);
jni_detach_thread();
if (!p_window->p_handle) if (!p_window->p_handle)
return -1; return -1;
} }
......
...@@ -38,8 +38,7 @@ ...@@ -38,8 +38,7 @@
#include "utils.h" #include "utils.h"
#define THREAD_NAME "ANativeWindow" #define THREAD_NAME "ANativeWindow"
extern int jni_attach_thread(JNIEnv **env, const char *thread_name); extern JNIEnv *jni_get_env(const char *name);
extern void jni_detach_thread();
extern jobject jni_LockAndGetAndroidJavaSurface(); extern jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface(); extern void jni_UnlockAndroidSurface();
extern void jni_SetSurfaceLayout(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den); 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) ...@@ -95,9 +94,9 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
goto error; goto error;
JNIEnv *p_env; 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. p_sys->window = p_sys->native_window.winFromSurface(p_env, javaSurface); // ANativeWindow_fromSurface call.
jni_detach_thread();
jni_UnlockAndroidSurface(); jni_UnlockAndroidSurface();
......
...@@ -73,9 +73,6 @@ vlc_module_end() ...@@ -73,9 +73,6 @@ vlc_module_end()
* JNI prototypes * 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 jobject jni_LockAndGetAndroidJavaSurface();
extern void jni_UnlockAndroidSurface(); extern void jni_UnlockAndroidSurface();
extern void *jni_AndroidJavaSurfaceToNativeSurface(jobject surf); 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