[Android] [PATCH] MediaCodec: simplify jni thread attach/detach
Felix Abecassis
felix.abecassis at gmail.com
Mon Feb 10 19:12:08 CET 2014
LGTM, but I agree with Edward regarding naming.
2014-02-10 18:41 GMT+01:00 <edward.c.wang at compdigitec.com>:
>
>
>
> Zhang Rui <bbcallen at gmail.com> a écrit :
> >Avoid repeatly AttachCurrentThread()/DetachCurrentThread()
> >---
> >modules/codec/omxil/android_mediacodec.c | 57
> >+++++++++++++++++++++++++-------
> > 1 file changed, 45 insertions(+), 12 deletions(-)
> >
> >diff --git a/modules/codec/omxil/android_mediacodec.c
> >b/modules/codec/omxil/android_mediacodec.c
> >index bf53e76..59846cc 100644
> >--- a/modules/codec/omxil/android_mediacodec.c
> >+++ b/modules/codec/omxil/android_mediacodec.c
> >@@ -201,6 +201,47 @@ static int jstrcmp(JNIEnv* env, jobject str, const
> >char* str2)
> > return ret;
> > }
> >
> >+static pthread_key_t g_thread_key;
> >+static pthread_once_t g_key_once = PTHREAD_ONCE_INIT;
> >+static JavaVMAttachArgs g_vlc_thr_args = {JNI_VERSION_1_2,
> >"MediaCodec", NULL};
> >+
> >+static void VlcJniThreadDestroy(void* value)
> >+{
> >+ JNIEnv *env = (JNIEnv*) value;
> >+ if (env != NULL) {
> >+ (*myVm)->DetachCurrentThread(myVm);
> >+ pthread_setspecific(g_thread_key, NULL);
> >+ }
> >+}
> >+
> >+static void VlcMakeThreadKey()
> >+{
> >+ pthread_key_create(&g_thread_key, VlcJniThreadDestroy);
> >+}
> >+
> >+jint VlcSetupThreadEnv(JNIEnv **p_env)
> >+{
> >+ JavaVM *jvm = myVm;
> >+ if (!jvm)
> >+ return -1;
> >+
> >+ pthread_once(&g_key_once, VlcMakeThreadKey);
> >+
> >+ JNIEnv *env = (JNIEnv*) pthread_getspecific(g_thread_key);
> >+ if (env) {
> >+ *p_env = env;
> >+ return 0;
> >+ }
> >+
> >+ if ((*jvm)->AttachCurrentThread(jvm, &env, &g_vlc_thr_args) ==
> >JNI_OK) {
> >+ pthread_setspecific(g_thread_key, env);
> >+ *p_env = env;
> >+ return 0;
> >+ }
> >+
> >+ return -1;
> >+}
> >+
>
> >/*****************************************************************************
> > * OpenDecoder: Create the decoder instance
>
> >*****************************************************************************/
> >@@ -246,7 +287,7 @@ static int OpenDecoder(vlc_object_t *p_this)
> > p_dec->b_need_packetized = true;
> >
> > JNIEnv* env = NULL;
> >- (*myVm)->AttachCurrentThread(myVm, &env, NULL);
> >+ VlcSetupThreadEnv(&env);
> >
> > for (int i = 0; classes[i].name; i++) {
> > *(jclass*)((uint8_t*)p_sys + classes[i].offset) =
> >@@ -413,11 +454,9 @@ static int OpenDecoder(vlc_object_t *p_this)
> > goto error;
> > (*env)->DeleteLocalRef(env, format);
> >
> >- (*myVm)->DetachCurrentThread(myVm);
> > return VLC_SUCCESS;
> >
> > error:
> >- (*myVm)->DetachCurrentThread(myVm);
> > CloseDecoder(p_this);
> > return VLC_EGENERIC;
> > }
> >@@ -435,7 +474,7 @@ 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);
> >- (*myVm)->AttachCurrentThread(myVm, &env, NULL);
> >+ VlcSetupThreadEnv(&env);
> > if (p_sys->input_buffers)
> > (*env)->DeleteGlobalRef(env, p_sys->input_buffers);
> > if (p_sys->output_buffers)
> >@@ -448,7 +487,6 @@ static void CloseDecoder(vlc_object_t *p_this)
> > }
> > if (p_sys->buffer_info)
> > (*env)->DeleteGlobalRef(env, p_sys->buffer_info);
> >- (*myVm)->DetachCurrentThread(myVm);
> >
> > free(p_sys->name);
> >ArchitectureSpecificCopyHooksDestroy(p_sys->pixel_format,
> >&p_sys->architecture_specific_data);
> >@@ -481,14 +519,13 @@ static void DisplayBuffer(picture_sys_t*
> >p_picsys, bool b_render)
> >
> > /* Release the MediaCodec buffer. */
> > JNIEnv *env = NULL;
> >- (*myVm)->AttachCurrentThread(myVm, &env, NULL);
> >+ VlcSetupThreadEnv(&env);
> >(*env)->CallVoidMethod(env, p_sys->codec, p_sys->release_output_buffer,
> >i_index, b_render);
> > if ((*env)->ExceptionOccurred(env)) {
> >msg_Err(p_dec, "Exception in MediaCodec.releaseOutputBuffer
> >(DisplayBuffer)");
> > (*env)->ExceptionClear(env);
> > }
> >
> >- (*myVm)->DetachCurrentThread(myVm);
> > p_picsys->b_valid = false;
> >
> > vlc_mutex_unlock(get_android_opaque_mutex());
> >@@ -686,7 +723,7 @@ static picture_t *DecodeVideo(decoder_t *p_dec,
> >block_t **pp_block)
> >
> > block_t *p_block = *pp_block;
> >
> >- (*myVm)->AttachCurrentThread(myVm, &env, NULL);
> >+ VlcSetupThreadEnv(&env);
> >
> >if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
> >{
> > block_Release(p_block);
> >@@ -704,7 +741,6 @@ static picture_t *DecodeVideo(decoder_t *p_dec,
> >block_t **pp_block)
> > }
> > }
> > p_sys->decoded = false;
> >- (*myVm)->DetachCurrentThread(myVm);
> > return NULL;
> > }
> >
> >@@ -730,7 +766,6 @@ static picture_t *DecodeVideo(decoder_t *p_dec,
> >block_t **pp_block)
> > * without assigning NULL to *pp_block. The next call
> > * to DecodeVideo will try to send the input packet again.
> > */
> >- (*myVm)->DetachCurrentThread(myVm);
> > return p_pic;
> > }
> > timeout = 30*1000;
> >@@ -756,7 +791,6 @@ static picture_t *DecodeVideo(decoder_t *p_dec,
> >block_t **pp_block)
> > block_Release(p_block);
> > *pp_block = NULL;
> > }
> >- (*myVm)->DetachCurrentThread(myVm);
> > return invalid_picture;
> > }
> > continue;
> >@@ -780,7 +814,6 @@ static picture_t *DecodeVideo(decoder_t *p_dec,
> >block_t **pp_block)
> > }
> > if (!p_pic)
> > GetOutput(p_dec, env, &p_pic);
> >- (*myVm)->DetachCurrentThread(myVm);
> >
> > block_Release(p_block);
> > *pp_block = NULL;
>
>
> I would prefer the style vlcjni_thread_destroy over VlcJniThreadDestroy,
> but otherwise it looks OK.
>
>
>
> Regards,
> Edward Wang
> _______________________________________________
> Android mailing list
> Android at videolan.org
> https://mailman.videolan.org/listinfo/android
>
--
Félix Abecassis
http://felix.abecassis.me
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/android/attachments/20140210/887e4e22/attachment-0001.html>
More information about the Android
mailing list