<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body><div>Ah, I thought your previous patch was already doing it good (moving the load library into LibVlcUtil).<br></div>
<div> </div>
<div>When you call static LibVlcUtil.isLibraryLoaded() ; the code inside the static { } block that load libraries will be first executed, then the function will return true if there was no errors.<br></div>
<div> </div>
<div>On Tue, Dec 2, 2014, at 04:46, Paulo Vitor Magacho da Silva wrote:<br></div>
<blockquote type="cite"><div dir="ltr"><div>To use the <span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">NativeCrashHandler inside </span></span><span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">VLCApplication::onCreate I need to statically load the dynamic libraries, which now are loaded in LibVLC.java.</span></span><br></div>
<div><span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">Should I move this static block to </span></span><span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">NativeCrashHandler or to </span></span><span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">VLCApplication::onCreate as a normal init method?</span></span><br></div>
<div><span style="font-family:arial,sans-serif" class="font"><span style="font-size:13px" class="size">Thanks</span></span><br></div>
</div>
<div><div> </div>
<div defang_data-gmailquote="yes"><div>2014-12-01 7:23 GMT-02:00 Thomas Guillem <span dir="ltr"><<a href="mailto:thomas@gllm.fr" target="_blank">thomas@gllm.fr</a>></span>:<br></div>
<blockquote defang_data-gmailquote="yes" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div> </div>
<div> </div>
<div>
On Sat, Nov 29, 2014, at 06:22, Paulo Vitor Magacho da Silva wrote:<br></div>
<div>
> ---<br></div>
<div>
>  libvlc/jni/libvlcjni-equalizer.c                   |   4 +-<br></div>
<div>
>  libvlc/jni/libvlcjni-util.c                        |  17 --<br></div>
<div>
>  libvlc/jni/libvlcjni.c                             | 187<br></div>
<div>
>  ++++++++++++---------<br></div>
<div>
>  libvlc/jni/native_crash_handler.c                  | 119 +++++++++++--<br></div>
<div>
>  libvlc/jni/native_crash_handler.h                  |   8 +-<br></div>
<div>
>  libvlc/jni/utils.h                                 |   2 -<br></div>
<div>
>  libvlc/jni/vout.c                                  | 186<br></div>
<div>
>  +++++++++++---------<br></div>
<div>
>  libvlc/jni/vout.h                                  |  25 ++-<br></div>
<div>
>  libvlc/src/org/videolan/libvlc/EventHandler.java   |   8 -<br></div>
<div>
>  libvlc/src/org/videolan/libvlc/LibVLC.java         |  35 ++--<br></div>
<div>
>  .../src/org/videolan/vlc/audio/AudioService.java   |  14 +-<br></div>
<div>
>  .../org/videolan/vlc/gui/PreferencesActivity.java  |   2 +-<br></div>
<div>
>  .../vlc/gui/video/VideoPlayerActivity.java         |   9 +-<br></div>
<div>
>  13 files changed, 381 insertions(+), 235 deletions(-)<br></div>
<div>
><br></div>
<div>
> diff --git a/libvlc/jni/libvlcjni-equalizer.c<br></div>
<div>
> b/libvlc/jni/libvlcjni-equalizer.c<br></div>
<div>
> index 2dad0e4..d11f24d 100644<br></div>
<div>
> --- a/libvlc/jni/libvlcjni-equalizer.c<br></div>
<div>
> +++ b/libvlc/jni/libvlcjni-equalizer.c<br></div>
<div>
> @@ -89,10 +89,10 @@ jfloatArray<br></div>
<div>
> Java_org_videolan_libvlc_LibVLC_getPreset(JNIEnv *env, jobject thiz,<br></div>
<div>
>   * apply equalizer settings (param bands is float[] (first element is<br></div>
<div>
>   preamp, then bands))<br></div>
<div>
>   */<br></div>
<div>
>  //"--audio-filter=equalizer", "--equalizer-bands=-3.5 -4.5 -1 0 0 5 8 8<br></div>
<div>
>  8 8",<br></div>
<div>
> -jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,<br></div>
<div>
> jobject thiz, jlong media_player, jfloatArray bands)<br></div>
<div>
> +jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,<br></div>
<div>
> jobject thiz, jfloatArray bands)<br></div>
<div>
>  {<br></div>
<div>
>      jint res = -1;<br></div>
<div>
> -    libvlc_media_player_t *mp =<br></div>
<div>
> (libvlc_media_player_t*)(intptr_t)media_player;<br></div>
<div>
> +    libvlc_media_player_t *mp = getMediaPlayer(env, thiz);<br></div>
<div>
>      if (!mp)<br></div>
<div>
>          return res;<br></div>
<div>
><br></div>
<div>
> diff --git a/libvlc/jni/libvlcjni-util.c b/libvlc/jni/libvlcjni-util.c<br></div>
<div>
> index 205d59d..67c2554 100644<br></div>
<div>
> --- a/libvlc/jni/libvlcjni-util.c<br></div>
<div>
> +++ b/libvlc/jni/libvlcjni-util.c<br></div>
<div>
> @@ -131,23 +131,6 @@ void arrayListStringAdd(JNIEnv *env, jclass class,<br></div>
<div>
> jmethodID methodID, jobject a<br></div>
<div>
>      (*env)->DeleteLocalRef(env, jstr);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -jobject getEventHandlerReference(JNIEnv *env, jobject thiz, jobject<br></div>
<div>
> eventHandler)<br></div>
<div>
> -{<br></div>
<div>
> -    jclass cls = (*env)->GetObjectClass(env, eventHandler);<br></div>
<div>
> -    if (!cls) {<br></div>
<div>
> -        LOGE("setEventHandler: failed to get class reference");<br></div>
<div>
> -        return NULL;<br></div>
<div>
> -    }<br></div>
<div>
> -<br></div>
<div>
> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",<br></div>
<div>
> "(ILandroid/os/Bundle;)V");<br></div>
<div>
> -    if (!methodID) {<br></div>
<div>
> -        LOGE("setEventHandler: failed to get the callback method");<br></div>
<div>
> -        return NULL;<br></div>
<div>
> -    }<br></div>
<div>
> -<br></div>
<div>
> -    return (*env)->NewGlobalRef(env, eventHandler);<br></div>
<div>
> -}<br></div>
<div>
> -<br></div>
<div>
>  static void debug_buffer_log(void *data, int level, const char *fmt,<br></div>
<div>
>  va_list ap)<br></div>
<div>
>  {<br></div>
<div>
>      bool isAttached = false;<br></div>
<div>
> diff --git a/libvlc/jni/libvlcjni.c b/libvlc/jni/libvlcjni.c<br></div>
<div>
> index b2c0cce..eaca4ca 100644<br></div>
<div>
> --- a/libvlc/jni/libvlcjni.c<br></div>
<div>
> +++ b/libvlc/jni/libvlcjni.c<br></div>
<div>
> @@ -72,6 +72,26 @@ static void add_media_options(libvlc_media_t *p_md,<br></div>
<div>
> JNIEnv *env, jobjectArray me<br></div>
<div>
>      }<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> +static void setLibVlcSysInstance(JNIEnv *env, jobject thiz,<br></div>
<div>
> libvlc_instance_sys_t *p_sys)<br></div>
<div>
> +{<br></div>
<div>
> +    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) p_sys);<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
> +static libvlc_instance_sys_t *getLibVlcSysInstance(JNIEnv *env, jobject<br></div>
<div>
> thiz)<br></div>
<div>
> +{<br></div>
<div>
> +    return (libvlc_instance_sys_t *)(intptr_t)getLong(env, thiz,<br></div>
<div>
> "mLibVlcInstance");<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
> +static void releaseMediaPlayer(JNIEnv *env, jobject thiz)<br></div>
<div>
> +{<br></div>
<div>
> +    libvlc_media_player_t *p_mp = getMediaPlayer(env, thiz);<br></div>
<div>
> +    if (p_mp)<br></div>
<div>
> +    {<br></div>
<div>
> +        libvlc_media_player_stop(p_mp);<br></div>
<div>
> +        libvlc_media_player_release(p_mp);<br></div>
<div>
> +    }<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
>  libvlc_media_t *new_media(JNIEnv *env, jobject thiz, jstring<br></div>
<div>
>  fileLocation, bool noOmx, bool noVideo)<br></div>
<div>
>  {<br></div>
<div>
>      libvlc_instance_t *libvlc = getLibVlcInstance(env, thiz);<br></div>
<div>
> @@ -98,24 +118,20 @@ libvlc_media_t *new_media(JNIEnv *env, jobject thiz,<br></div>
<div>
> jstring fileLocation, bool<br></div>
<div>
><br></div>
<div>
>  libvlc_instance_t *getLibVlcInstance(JNIEnv *env, jobject thiz)<br></div>
<div>
>  {<br></div>
<div>
> -    return (libvlc_instance_t*)(intptr_t)getLong(env, thiz,<br></div>
<div>
> "mLibVlcInstance");<br></div>
<div>
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);<br></div>
<div>
> +    return p_sys ? p_sys->p_libvlc : NULL;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)<br></div>
<div>
> +android_surf_value_t *getAndroidSurfaceInstance(JNIEnv *env, jobject<br></div>
<div>
> thiz)<br></div>
<div>
>  {<br></div>
<div>
> -    return (libvlc_media_player_t*)(intptr_t)getLong(env, thiz,<br></div>
<div>
> "mInternalMediaPlayerInstance");<br></div>
<div>
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);<br></div>
<div>
> +    return p_sys ? p_sys->p_surf : NULL;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -<br></div>
<div>
> -static void releaseMediaPlayer(JNIEnv *env, jobject thiz)<br></div>
<div>
> +libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)<br></div>
<div>
>  {<br></div>
<div>
> -    libvlc_media_player_t* p_mp = getMediaPlayer(env, thiz);<br></div>
<div>
> -    if (p_mp)<br></div>
<div>
> -    {<br></div>
<div>
> -        libvlc_media_player_stop(p_mp);<br></div>
<div>
> -        libvlc_media_player_release(p_mp);<br></div>
<div>
> -        setLong(env, thiz, "mInternalMediaPlayerInstance", 0);<br></div>
<div>
> -    }<br></div>
<div>
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);<br></div>
<div>
> +    return p_sys ? p_sys->p_mp : NULL;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  /* Pointer to the Java virtual machine<br></div>
<div>
> @@ -124,17 +140,12 @@ static void releaseMediaPlayer(JNIEnv *env, jobject<br></div>
<div>
> thiz)<br></div>
<div>
>   */<br></div>
<div>
>  static JavaVM *myVm;<br></div>
<div>
><br></div>
<div>
> -static jobject eventHandlerInstance = NULL;<br></div>
<div>
> -<br></div>
<div>
>  static void vlc_event_callback(const libvlc_event_t *ev, void *data)<br></div>
<div>
>  {<br></div>
<div>
>      JNIEnv *env;<br></div>
<div>
><br></div>
<div>
>      bool isAttached = false;<br></div>
<div>
><br></div>
<div>
> -    if (eventHandlerInstance == NULL)<br></div>
<div>
> -        return;<br></div>
<div>
> -<br></div>
<div>
>      if (jni_get_env(&env) < 0) {<br></div>
<div>
>          if (jni_attach_thread(&env, THREAD_NAME) < 0)<br></div>
<div>
>              return;<br></div>
<div>
> @@ -193,20 +204,31 @@ static void vlc_event_callback(const libvlc_event_t<br></div>
<div>
> *ev, void *data)<br></div>
<div>
>          free(mrl);<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> +    /* The LibVLC object */<br></div>
<div>
> +    jobject vlcObject = (jobject) data;<br></div>
<div>
> +<br></div>
<div>
> +    /* Get the event handler object */<br></div>
<div>
> +    jclass cls = (*env)->GetObjectClass(env, vlcObject);<br></div>
<div>
> +    jmethodID methodId = (*env)->GetMethodID(env, cls,<br></div>
<div>
> "getEventHandler", "()Lorg/videolan/libvlc/EventHandler;");<br></div>
<div>
> +    jobject eventHandlerInstance = (*env)->CallObjectMethod(env,<br></div>
<div>
> vlcObject, methodId);<br></div>
<div>
> +<br></div>
<div>
> +    (*env)->DeleteLocalRef(env, cls);<br></div>
<div>
> +<br></div>
<div>
>      /* Get the object class */<br></div>
<div>
> -    jclass cls = (*env)->GetObjectClass(env, eventHandlerInstance);<br></div>
<div>
> +    cls = (*env)->GetObjectClass(env, eventHandlerInstance);<br></div>
<div>
>      if (!cls) {<br></div>
<div>
>          LOGE("EventHandler: failed to get class reference");<br></div>
<div>
>          goto end;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      /* Find the callback ID */<br></div>
<div>
> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",<br></div>
<div>
> "(ILandroid/os/Bundle;)V");<br></div>
<div>
> -    if (methodID) {<br></div>
<div>
> -        (*env)->CallVoidMethod(env, eventHandlerInstance, methodID,<br></div>
<div>
> ev->type, bundle);<br></div>
<div>
> +    methodId = (*env)->GetMethodID(env, cls, "callback",<br></div>
<div>
> "(ILandroid/os/Bundle;)V");<br></div>
<div>
> +    if (methodId) {<br></div>
<div>
> +        (*env)->CallVoidMethod(env, eventHandlerInstance, methodId,<br></div>
<div>
> ev->type, bundle);<br></div>
<div>
>      } else {<br></div>
<div>
>          LOGE("EventHandler: failed to get the callback method");<br></div>
<div>
>      }<br></div>
<div>
> +    (*env)->DeleteLocalRef(env, cls);<br></div>
<div>
><br></div>
<div>
>  end:<br></div>
<div>
>      (*env)->DeleteLocalRef(env, bundle);<br></div>
<div>
> @@ -219,16 +241,16 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)<br></div>
<div>
>      // Keep a reference on the Java VM.<br></div>
<div>
>      myVm = vm;<br></div>
<div>
><br></div>
<div>
> -    pthread_mutex_init(&vout_android_lock, NULL);<br></div>
<div>
> -    pthread_cond_init(&vout_android_surf_attached, NULL);<br></div>
<div>
> +    init_native_crash_handler();<br></div>
<div>
><br></div>
<div>
>      LOGD("JNI interface loaded.");<br></div>
<div>
>      return VLC_JNI_VERSION;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void JNI_OnUnload(JavaVM* vm, void* reserved) {<br></div>
<div>
> -    pthread_mutex_destroy(&vout_android_lock);<br></div>
<div>
> -    pthread_cond_destroy(&vout_android_surf_attached);<br></div>
<div>
> +    destroy_native_crash_handler();<br></div>
<div>
> +<br></div>
<div>
> +    LOGD("JNI interface un-loaded.");<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  int jni_attach_thread(JNIEnv **env, const char *thread_name)<br></div>
<div>
> @@ -353,8 +375,6 @@ void<br></div>
<div>
> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)<br></div>
<div>
>      };<br></div>
<div>
>      libvlc_instance_t *instance = libvlc_new(sizeof(argv) /<br></div>
<div>
>      sizeof(*argv), argv);<br></div>
<div>
><br></div>
<div>
> -    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) instance);<br></div>
<div>
> -<br></div>
<div>
>      (*env)->ReleaseStringUTFChars(env, chroma, chromastr);<br></div>
<div>
>      (*env)->ReleaseStringUTFChars(env, subsencoding, subsencodingstr);<br></div>
<div>
><br></div>
<div>
> @@ -364,45 +384,50 @@ void<br></div>
<div>
> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)<br></div>
<div>
>          (*env)->ThrowNew(env, exc, "Unable to instantiate LibVLC");<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> +    /* Set values to libvlc sys instance */<br></div>
<div>
> +    libvlc_instance_sys_t  *p_sys = (libvlc_instance_sys_t *) calloc(1,<br></div>
<div>
> sizeof(libvlc_instance_sys_t));<br></div>
<div>
> +    p_sys->p_libvlc = instance;<br></div>
<div>
> +    p_sys->p_surf = (android_surf_value_t *) calloc(1,<br></div>
<div>
> sizeof(android_surf_value_t));<br></div>
<div>
> +    p_sys->p_this = (*env)->NewGlobalRef(env, thiz);<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_init(&p_sys->p_surf->vout_android_lock, NULL);<br></div>
<div>
> +    pthread_cond_init(&p_sys->p_surf->vout_android_surf_attached, NULL);<br></div>
<div>
> +<br></div>
<div>
> +    setLibVlcSysInstance(env, thiz, p_sys);<br></div>
<div>
> +<br></div>
<div>
>      LOGI("LibVLC initialized: %p", instance);<br></div>
<div>
><br></div>
<div>
>      libvlc_log_set(instance, debug_log, &verbosity);<br></div>
<div>
><br></div>
<div>
> -    init_native_crash_handler(env, thiz);<br></div>
<div>
> +    add_native_crash_handler(env, p_sys->p_this);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject<br></div>
<div>
>  thiz)<br></div>
<div>
>  {<br></div>
<div>
> -    destroy_native_crash_handler(env);<br></div>
<div>
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);<br></div>
<div>
> +<br></div>
<div>
> +    remove_native_crash_handler(env, p_sys->p_this);<br></div>
<div>
><br></div>
<div>
>      releaseMediaPlayer(env, thiz);<br></div>
<div>
> -    jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");<br></div>
<div>
> -    if (!libVlcInstance)<br></div>
<div>
> -        return; // Already destroyed<br></div>
<div> </div>
</div>
<div>this "Already destroyed" check should be done just after<br></div>
<div> <span class="">libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);</span><br></div>
<div><span class="">
> +</span><br></div>
<div> </div>
<div><span class="">
></span><br></div>
<div> </div>
<div><div>> -    libvlc_instance_t *instance = (libvlc_instance_t*)(intptr_t)<br></div>
<div>
> libVlcInstance;<br></div>
<div>
> -    libvlc_log_unset(instance);<br></div>
<div>
> -    libvlc_release(instance);<br></div>
<div>
> +    if (p_sys->p_this != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env, p_sys->p_this);<br></div>
<div>
><br></div>
<div>
> -    setLong(env, thiz, "mLibVlcInstance", 0);<br></div>
<div>
> -}<br></div>
<div>
> +    pthread_mutex_destroy(&p_sys->p_surf->vout_android_lock);<br></div>
<div>
> +    pthread_cond_destroy(&p_sys->p_surf->vout_android_surf_attached);<br></div>
<div>
><br></div>
<div>
> -void Java_org_videolan_libvlc_LibVLC_detachEventHandler(JNIEnv *env,<br></div>
<div>
> jobject thiz)<br></div>
<div>
> -{<br></div>
<div>
> -    if (eventHandlerInstance != NULL) {<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);<br></div>
<div>
> -        eventHandlerInstance = NULL;<br></div>
<div>
> -    }<br></div>
<div>
> -}<br></div>
<div>
> +    free(p_sys->p_surf);<br></div>
<div>
><br></div>
<div>
> -void Java_org_videolan_libvlc_LibVLC_setEventHandler(JNIEnv *env,<br></div>
<div>
> jobject thiz, jobject eventHandler)<br></div>
<div>
> -{<br></div>
<div>
> -    if (eventHandlerInstance != NULL) {<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);<br></div>
<div>
> -        eventHandlerInstance = NULL;<br></div>
<div>
> -    }<br></div>
<div>
> +    if (!p_sys->p_libvlc)<br></div>
<div>
> +        return; // Already destroyed<br></div>
<div>
><br></div>
<div>
> -    eventHandlerInstance = getEventHandlerReference(env, thiz,<br></div>
<div>
> eventHandler);<br></div>
<div>
> +    libvlc_instance_t *instance = p_sys->p_libvlc;<br></div>
<div>
> +    LOGI("LibVLC destroyed: %p", instance);<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_log_unset(instance);<br></div>
<div>
> +    libvlc_release(instance);<br></div>
<div>
> +<br></div>
<div>
> +    setLibVlcSysInstance(env, thiz, NULL);<br></div>
<div> </div>
</div>
<div>you forgot to free p_sys<br></div>
<div><div> </div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,<br></div>
<div>
> @@ -411,25 +436,24 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv<br></div>
<div>
> *env, jobject thiz,<br></div>
<div>
>      /* Release previous media player, if any */<br></div>
<div>
>      releaseMediaPlayer(env, thiz);<br></div>
<div>
><br></div>
<div>
> -    libvlc_instance_t *p_instance = getLibVlcInstance(env, thiz);<br></div>
<div>
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);<br></div>
<div>
><br></div>
<div>
>      /* Create a media player playing environment */<br></div>
<div>
> -    libvlc_media_player_t *mp = libvlc_media_player_new(p_instance);<br></div>
<div>
> -    libvlc_media_player_set_video_title_display(mp,<br></div>
<div>
> libvlc_position_disable, 0);<br></div>
<div>
> -    jobject myJavaLibVLC = (*env)->NewGlobalRef(env, thiz);<br></div>
<div>
> +    p_sys->p_mp = libvlc_media_player_new(p_sys->p_libvlc);<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_media_player_set_video_title_display(p_sys->p_mp,<br></div>
<div>
> libvlc_position_disable, 0);<br></div>
<div>
><br></div>
<div>
>      //if AOUT_AUDIOTRACK_JAVA, we use amem<br></div>
<div>
>      jclass cls = (*env)->GetObjectClass(env, thiz);<br></div>
<div>
>      jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout",<br></div>
<div>
>      "()I");<br></div>
<div>
>      if ( (*env)->CallIntMethod(env, thiz, methodId) ==<br></div>
<div>
>      AOUT_AUDIOTRACK_JAVA )<br></div>
<div>
>      {<br></div>
<div>
> -        libvlc_audio_set_callbacks(mp, aout_play, aout_pause, NULL,<br></div>
<div>
> NULL, NULL,<br></div>
<div>
> -                                   (void*) myJavaLibVLC);<br></div>
<div>
> -        libvlc_audio_set_format_callbacks(mp, aout_open, aout_close);<br></div>
<div>
> +        libvlc_audio_set_callbacks(p_sys->p_mp, aout_play, aout_pause,<br></div>
<div>
> NULL, NULL, NULL, p_sys->p_this);<br></div>
<div>
> +        libvlc_audio_set_format_callbacks(p_sys->p_mp, aout_open,<br></div>
<div>
> aout_close);<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      /* Connect the event manager */<br></div>
<div>
> -    libvlc_event_manager_t *ev = libvlc_media_player_event_manager(mp);<br></div>
<div>
> +    libvlc_event_manager_t *ev =<br></div>
<div>
> libvlc_media_player_event_manager(p_sys->p_mp);<br></div>
<div>
>      static const libvlc_event_type_t mp_events[] = {<br></div>
<div>
>          libvlc_MediaPlayerPlaying,<br></div>
<div>
>          libvlc_MediaPlayerPaused,<br></div>
<div>
> @@ -441,10 +465,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv<br></div>
<div>
> *env, jobject thiz,<br></div>
<div>
>          libvlc_MediaPlayerEncounteredError<br></div>
<div>
>      };<br></div>
<div>
>      for(int i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); i++)<br></div>
<div>
> -        libvlc_event_attach(ev, mp_events[i], vlc_event_callback, myVm);<br></div>
<div>
> -<br></div>
<div>
> -    /* Keep a pointer to this media player */<br></div>
<div>
> -    setLong(env, thiz, "mInternalMediaPlayerInstance",<br></div>
<div>
> (jlong)(intptr_t)mp);<br></div>
<div>
> +        libvlc_event_attach(ev, mp_events[i], vlc_event_callback,<br></div>
<div>
> p_sys->p_this);<br></div>
<div>
><br></div>
<div>
>      cls = (*env)->GetObjectClass(env, thiz);<br></div>
<div>
>      jmethodID methodID = (*env)->GetMethodID(env, cls, "applyEqualizer",<br></div>
<div>
>      "()V");<br></div>
<div>
> @@ -452,13 +473,16 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv<br></div>
<div>
> *env, jobject thiz,<br></div>
<div>
><br></div>
<div>
>      const char* p_mrl = (*env)->GetStringUTFChars(env, mrl, 0);<br></div>
<div>
><br></div>
<div>
> -    libvlc_media_t* p_md = libvlc_media_new_location(p_instance, p_mrl);<br></div>
<div>
> +    libvlc_media_t* p_md = libvlc_media_new_location(p_sys->p_libvlc,<br></div>
<div>
> p_mrl);<br></div>
<div>
>      /* media options */<br></div>
<div>
>      if (mediaOptions != NULL)<br></div>
<div>
>          add_media_options(p_md, env, mediaOptions);<br></div>
<div>
><br></div>
<div>
>      (*env)->ReleaseStringUTFChars(env, mrl, p_mrl);<br></div>
<div>
><br></div>
<div>
> +    /* set the Android surface value structure before playing */<br></div>
<div>
> +    libvlc_media_player_set_surfacevalue(p_sys->p_mp, p_sys->p_surf);<br></div>
<div>
> +<br></div>
<div> </div>
</div>
<div>again, I would call that function: libvlc_media_player_set_androidobject<br></div>
<div><div> </div>
<div>
>      /* Connect the media event manager. */<br></div>
<div>
>      libvlc_event_manager_t *ev_media = libvlc_media_event_manager(p_md);<br></div>
<div>
>      static const libvlc_event_type_t mp_media_events[] = {<br></div>
<div>
> @@ -466,10 +490,10 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv<br></div>
<div>
> *env, jobject thiz,<br></div>
<div>
>          libvlc_MediaMetaChanged,<br></div>
<div>
>      };<br></div>
<div>
>      for(int i = 0; i < (sizeof(mp_media_events) /<br></div>
<div>
>      sizeof(*mp_media_events)); i++)<br></div>
<div>
> -        libvlc_event_attach(ev_media, mp_media_events[i],<br></div>
<div>
> vlc_event_callback, myVm);<br></div>
<div>
> +        libvlc_event_attach(ev_media, mp_media_events[i],<br></div>
<div>
> vlc_event_callback, p_sys->p_this);<br></div>
<div>
><br></div>
<div>
> -    libvlc_media_player_set_media(mp, p_md);<br></div>
<div>
> -    libvlc_media_player_play(mp);<br></div>
<div>
> +    libvlc_media_player_set_media(p_sys->p_mp, p_md);<br></div>
<div>
> +    libvlc_media_player_play(p_sys->p_mp);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  jfloat Java_org_videolan_libvlc_LibVLC_getRate(JNIEnv *env, jobject<br></div>
<div>
>  thiz) {<br></div>
<div>
> @@ -654,23 +678,26 @@ void<br></div>
<div>
> Java_org_videolan_libvlc_LibVLC_playerNavigate(JNIEnv *env, jobject thiz,<br></div>
<div>
> j<br></div>
<div>
>          libvlc_media_player_navigate(mp, (unsigned) nav);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -// TODO: remove static variables<br></div>
<div>
> -static int i_window_width = 0;<br></div>
<div>
> -static int i_window_height = 0;<br></div>
<div>
> -<br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_setWindowSize(JNIEnv *env, jobject<br></div>
<div>
>  thiz, jint width, jint height)<br></div>
<div>
>  {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    i_window_width = width;<br></div>
<div>
> -    i_window_height = height;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t *android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    android_surface->i_window_width = width;<br></div>
<div>
> +    android_surface->i_window_height = height;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -int jni_GetWindowSize(int *width, int *height)<br></div>
<div>
> +int jni_GetWindowSize(android_surf_value_t *android_surface, int *width,<br></div>
<div>
> int *height)<br></div>
<div>
>  {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    *width = i_window_width;<br></div>
<div>
> -    *height = i_window_height;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    *width = android_surface->i_window_width;<br></div>
<div>
> +    *height = android_surface->i_window_height;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>      return 0;<br></div>
<div>
>  }<br></div>
<div>
> diff --git a/libvlc/jni/native_crash_handler.c<br></div>
<div>
> b/libvlc/jni/native_crash_handler.c<br></div>
<div>
> index 2cb1590..1a41c5b 100644<br></div>
<div>
> --- a/libvlc/jni/native_crash_handler.c<br></div>
<div>
> +++ b/libvlc/jni/native_crash_handler.c<br></div>
<div>
> @@ -19,11 +19,22 @@<br></div>
<div>
>   *****************************************************************************/<br></div>
<div>
><br></div>
<div>
>  #include <signal.h><br></div>
<div>
> +#include <pthread.h><br></div>
<div>
><br></div>
<div>
>  #include "native_crash_handler.h"<br></div>
<div>
><br></div>
<div>
> +#define LOG_TAG "VLC/JNI/crash"<br></div>
<div>
> +#include "log.h"<br></div>
<div>
> +<br></div>
<div>
> +struct libvlc_crash_handler_t {<br></div>
<div>
> +    void                    *j_libVLC;<br></div>
<div>
> +    libvlc_crash_handler_t  *next;<br></div>
<div>
> +    libvlc_crash_handler_t  *prev;<br></div>
<div>
> +};<br></div>
<div>
> +<br></div>
<div>
>  static struct sigaction old_actions[NSIG];<br></div>
<div>
> -static jobject j_libVLC;<br></div>
<div>
> +static libvlc_crash_handler_t *first = NULL;<br></div>
<div>
> +static libvlc_crash_handler_t *last = NULL;<br></div>
<div>
><br></div>
<div>
>  #define THREAD_NAME "native_crash_handler"<br></div>
<div>
>  extern int jni_attach_thread(JNIEnv **env, const char *thread_name);<br></div>
<div>
> @@ -44,6 +55,7 @@ static const int monitored_signals[] = {<br></div>
<div>
>      SIGPIPE<br></div>
<div>
>  };<br></div>
<div>
><br></div>
<div>
> +pthread_mutex_t native_handler_lock;<br></div>
<div>
><br></div>
<div>
>  /**<br></div>
<div>
>   * Callback called when a monitored signal is triggered.<br></div>
<div>
> @@ -54,21 +66,32 @@ void sigaction_callback(int signal, siginfo_t *info,<br></div>
<div>
> void *reserved)<br></div>
<div>
>      JNIEnv *env;<br></div>
<div>
>      jni_attach_thread(&env, THREAD_NAME);<br></div>
<div>
><br></div>
<div>
> -    jclass cls = (*env)->GetObjectClass(env, j_libVLC);<br></div>
<div>
> -    jmethodID methodId = (*env)->GetMethodID(env, cls, "onNativeCrash",<br></div>
<div>
> "()V");<br></div>
<div>
> -    (*env)->CallVoidMethod(env, j_libVLC, methodId);<br></div>
<div>
> +    pthread_mutex_lock(&native_handler_lock);<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_crash_handler_t *lp = first;<br></div>
<div>
> +    while (lp != NULL)<br></div>
<div>
> +    {<br></div>
<div>
> +        jclass cls = (*env)->GetObjectClass(env, lp->j_libVLC);<br></div>
<div>
> +        jmethodID methodId = (*env)->GetMethodID(env, cls,<br></div>
<div>
> "onNativeCrash", "()V");<br></div>
<div>
> +        (*env)->CallVoidMethod(env, lp->j_libVLC, methodId);<br></div>
<div>
> +<br></div>
<div>
> +        (*env)->DeleteLocalRef(env, cls);<br></div>
<div>
> +<br></div>
<div>
> +        libvlc_crash_handler_t *todelete = lp;<br></div>
<div>
> +        lp = lp->next;<br></div>
<div>
> +<br></div>
<div>
> +        free(todelete);<br></div>
<div>
> +    }<br></div>
<div>
> +    pthread_mutex_unlock(&native_handler_lock);<br></div>
<div>
><br></div>
<div>
> -    (*env)->DeleteLocalRef(env, cls);<br></div>
<div>
>      jni_detach_thread();<br></div>
<div>
><br></div>
<div>
>      // Call the old signal handler.<br></div>
<div>
>      old_actions[signal].sa_handler(signal);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -<br></div>
<div>
> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)<br></div>
<div>
> +void init_native_crash_handler()<br></div>
<div>
>  {<br></div>
<div>
> -    j_libVLC = (*env)->NewGlobalRef(env, j_libVLC_local);<br></div>
<div>
>      struct sigaction handler;<br></div>
<div>
>      memset(&handler, 0, sizeof(struct sigaction));<br></div>
<div>
><br></div>
<div>
> @@ -81,10 +104,13 @@ void init_native_crash_handler(JNIEnv *env, jobject<br></div>
<div>
> j_libVLC_local)<br></div>
<div>
>          const int s = monitored_signals[i];<br></div>
<div>
>          sigaction(s, &handler, &old_actions[s]);<br></div>
<div>
>      }<br></div>
<div>
> -}<br></div>
<div>
><br></div>
<div>
> +    pthread_mutex_init(&native_handler_lock, NULL);<br></div>
<div>
> +<br></div>
<div>
> +    LOGI("Native crash handler initialized");<br></div>
<div>
> +}<br></div>
<div>
><br></div>
<div>
> -void destroy_native_crash_handler(JNIEnv *env)<br></div>
<div>
> +void destroy_native_crash_handler()<br></div>
<div>
>  {<br></div>
<div>
>      // Uninstall the signal handlers and restore their old actions.<br></div>
<div>
>      for (unsigned i = 0; i < sizeof(monitored_signals) / sizeof(int);<br></div>
<div>
>      ++i)<br></div>
<div>
> @@ -93,5 +119,76 @@ void destroy_native_crash_handler(JNIEnv *env)<br></div>
<div>
>          sigaction(s, &old_actions[s], NULL);<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    (*env)->DeleteGlobalRef(env, j_libVLC);<br></div>
<div>
> +    pthread_mutex_destroy(&native_handler_lock);<br></div>
<div>
> +<br></div>
<div>
> +    LOGI("Native crash handler destroyed");<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
> +void add_native_crash_handler(JNIEnv *env, void *j_libVLC_local)<br></div>
<div>
> +{<br></div>
<div>
> +    LOGI("Add crash handler to %p", j_libVLC_local);<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&native_handler_lock);<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_crash_handler_t *current = (libvlc_crash_handler_t *)<br></div>
<div>
> malloc(sizeof(libvlc_crash_handler_t));<br></div>
<div>
> +    current->j_libVLC = j_libVLC_local;<br></div>
<div>
> +    current->prev = last;<br></div>
<div>
> +    current->next = NULL;<br></div>
<div>
> +<br></div>
<div>
> +    // update values<br></div>
<div>
> +    if (first == NULL)<br></div>
<div>
> +        first = current;<br></div>
<div>
> +    if (last != NULL)<br></div>
<div>
> +        last->next = current;<br></div>
<div>
> +<br></div>
<div>
> +    last = current;<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_crash_handler_t *lp = first;<br></div>
<div>
> +    while (lp != NULL)<br></div>
<div>
> +    {<br></div>
<div>
> +        LOGI("Current handlers: %p", lp);<br></div>
<div>
> +        lp = lp->next;<br></div>
<div>
> +    }<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_unlock(&native_handler_lock);<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
> +<br></div>
<div>
> +void remove_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)<br></div>
<div>
> +{<br></div>
<div>
> +    LOGI("Remove crash handler to %p", j_libVLC_local);<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&native_handler_lock);<br></div>
<div>
> +<br></div>
<div>
> +    libvlc_crash_handler_t *lp = first;<br></div>
<div>
> +    while (lp != NULL)<br></div>
<div>
> +    {<br></div>
<div>
> +        if (j_libVLC_local == lp->j_libVLC)<br></div>
<div>
> +        {<br></div>
<div>
> +            LOGI("Destroying handler: %p", lp);<br></div>
<div>
> +<br></div>
<div>
> +            libvlc_crash_handler_t *todelete = lp;<br></div>
<div>
> +            libvlc_crash_handler_t *prev = lp->prev;<br></div>
<div>
> +            libvlc_crash_handler_t *next = lp->next;<br></div>
<div>
> +            if (lp == first) {<br></div>
<div>
> +                first = next;<br></div>
<div>
> +                if (first != NULL)<br></div>
<div>
> +                    first->prev = NULL;<br></div>
<div>
> +            } else if (lp == last) {<br></div>
<div>
> +                last = prev;<br></div>
<div>
> +                last->next = NULL;<br></div>
<div>
> +            } else {<br></div>
<div>
> +                 prev->next = next;<br></div>
<div>
> +                 next->prev = prev;<br></div>
<div>
> +            }<br></div>
<div>
> +<br></div>
<div>
> +            free(todelete);<br></div>
<div>
> +<br></div>
<div>
> +            break;<br></div>
<div>
> +        }<br></div>
<div>
> +<br></div>
<div>
> +        lp = lp->next;<br></div>
<div>
> +    }<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_unlock(&native_handler_lock);<br></div>
<div>
>  }<br></div>
<div>
> diff --git a/libvlc/jni/native_crash_handler.h<br></div>
<div>
> b/libvlc/jni/native_crash_handler.h<br></div>
<div>
> index a57e61e..080fc0b 100644<br></div>
<div>
> --- a/libvlc/jni/native_crash_handler.h<br></div>
<div>
> +++ b/libvlc/jni/native_crash_handler.h<br></div>
<div>
> @@ -23,7 +23,11 @@<br></div>
<div>
><br></div>
<div>
>  #include <jni.h><br></div>
<div>
><br></div>
<div>
> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);<br></div>
<div>
> -void destroy_native_crash_handler(JNIEnv *env);<br></div>
<div>
> +typedef struct libvlc_crash_handler_t libvlc_crash_handler_t;<br></div>
<div>
> +<br></div>
<div>
> +void init_native_crash_handler();<br></div>
<div>
> +void destroy_native_crash_handler();<br></div>
<div>
> +void add_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);<br></div>
<div>
> +void remove_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);<br></div>
<div> </div>
<div> </div>
</div>
<div>You don't need all that for nativecrash handler. It must be a singleton.<br></div>
<div>
on vlc-android, you can check how it is used:<br></div>
<div>
public void onNativeCrash() {<br></div>
<div>
  Intent i = new Intent(context, NativeCrashActivity.class);<br></div>
<div>
  i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);<br></div>
<div>
  i.putExtra("PID", android.os.Process.myPid());<br></div>
<div>
  context.startActivity(i);<br></div>
<div>
}<br></div>
<div> </div>
<div>
You see, it start a new activity and it just need a context.<br></div>
<div> </div>
<div>
So I would add NativeCrashHandler.java in libvlc with a static native<br></div>
<div>
function: Java_org_videolan_libvlc_NativeCrashHandler_setListener.<br></div>
<div>
And I would set the listener in VLCApplication::onCreate by calling<br></div>
<div>
NativeCrashHandler.setListener()<br></div>
<div><div> </div>
<div>
><br></div>
<div>
>  #endif // LIBVLCJNI_NATIVE_CRASH_HANDLER_H<br></div>
<div>
> diff --git a/libvlc/jni/utils.h b/libvlc/jni/utils.h<br></div>
<div>
> index 5da3514..ac23660 100644<br></div>
<div>
> --- a/libvlc/jni/utils.h<br></div>
<div>
> +++ b/libvlc/jni/utils.h<br></div>
<div>
> @@ -43,8 +43,6 @@ void arrayListGetIDs(JNIEnv *env, jclass* p_class,<br></div>
<div>
> jmethodID* p_add, jmethodID*<br></div>
<div>
><br></div>
<div>
>  void arrayListStringAdd(JNIEnv *env, jclass class, jmethodID methodID,<br></div>
<div>
>  jobject arrayList, const char* str);<br></div>
<div>
><br></div>
<div>
> -jobject getEventHandlerReference(JNIEnv *env, jobject thiz, jobject<br></div>
<div>
> eventHandler);<br></div>
<div>
> -<br></div>
<div>
>  void debug_log(void *data, int level, const libvlc_log_t *ctx, const<br></div>
<div>
>  char *fmt, va_list ap);<br></div>
<div>
><br></div>
<div>
>  #endif // LIBVLCJNI_UTILS_H<br></div>
<div>
> diff --git a/libvlc/jni/vout.c b/libvlc/jni/vout.c<br></div>
<div>
> index 04c933c..7cdc234 100644<br></div>
<div>
> --- a/libvlc/jni/vout.c<br></div>
<div>
> +++ b/libvlc/jni/vout.c<br></div>
<div>
> @@ -22,100 +22,104 @@<br></div>
<div>
>  #include <vlc_common.h><br></div>
<div>
><br></div>
<div>
>  #include <jni.h><br></div>
<div>
> +#include "vout.h"<br></div>
<div>
> +<br></div>
<div>
> +#define LOG_TAG "VLC/JNI/vout"<br></div>
<div>
> +#include "log.h"<br></div>
<div>
><br></div>
<div>
>  #define THREAD_NAME "jni_vout"<br></div>
<div>
>  extern int jni_attach_thread(JNIEnv **env, const char *thread_name);<br></div>
<div>
>  extern void jni_detach_thread();<br></div>
<div>
>  extern int jni_get_env(JNIEnv **env);<br></div>
<div>
><br></div>
<div>
> -pthread_mutex_t vout_android_lock;<br></div>
<div>
> -pthread_cond_t vout_android_surf_attached;<br></div>
<div>
> -static void *vout_android_gui = NULL;<br></div>
<div>
> -static jobject vout_android_java_surf = NULL;<br></div>
<div>
> -static jobject vout_android_subtitles_surf = NULL;<br></div>
<div>
> -static bool vout_video_player_activity_created = false;<br></div>
<div>
> -<br></div>
<div>
> -void *jni_LockAndGetSubtitlesSurface() {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    while (vout_android_subtitles_surf == NULL)<br></div>
<div>
> -        pthread_cond_wait(&vout_android_surf_attached,<br></div>
<div>
> &vout_android_lock);<br></div>
<div>
> -    return vout_android_subtitles_surf;<br></div>
<div>
> +void *jni_LockAndGetSubtitlesSurface(android_surf_value_t<br></div>
<div>
> *android_surface) {<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    while (android_surface->vout_android_subtitles_surf == NULL)<br></div>
<div>
> +        pthread_cond_wait(&android_surface->vout_android_surf_attached,<br></div>
<div>
> &android_surface->vout_android_lock);<br></div>
<div>
> +    return android_surface->vout_android_subtitles_surf;<br></div>
<div>
> +}<br></div>
<div>
> +<br></div>
<div>
> +jobject jni_LockAndGetAndroidJavaSurface(android_surf_value_t<br></div>
<div>
> *android_surface) {<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    while (android_surface->vout_android_java_surf == NULL)<br></div>
<div>
> +        pthread_cond_wait(&android_surface->vout_android_surf_attached,<br></div>
<div>
> &android_surface->vout_android_lock);<br></div>
<div>
> +    return android_surface->vout_android_java_surf;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -jobject jni_LockAndGetAndroidJavaSurface() {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    while (vout_android_java_surf == NULL)<br></div>
<div>
> -        pthread_cond_wait(&vout_android_surf_attached,<br></div>
<div>
> &vout_android_lock);<br></div>
<div>
> -    return vout_android_java_surf;<br></div>
<div>
> +void jni_LockAndroidSurface(android_surf_value_t *android_surface) {<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -void jni_UnlockAndroidSurface() {<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +void jni_UnlockAndroidSurface(android_surf_value_t *android_surface) {<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -void jni_EventHardwareAccelerationError()<br></div>
<div>
> +void jni_EventHardwareAccelerationError(android_surf_value_t<br></div>
<div>
> *android_surface)<br></div>
<div>
>  {<br></div>
<div>
>      JNIEnv *env;<br></div>
<div>
>      bool isAttached = false;<br></div>
<div>
><br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_gui == NULL) {<br></div>
<div>
> -        pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_gui == NULL) {<br></div>
<div>
> +        pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>          return;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      if (jni_get_env(&env) < 0) {<br></div>
<div>
>          if (jni_attach_thread(&env, THREAD_NAME) < 0) {<br></div>
<div>
> -            pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +            pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>              return;<br></div>
<div>
>          }<br></div>
<div>
>          isAttached = true;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    jclass cls = (*env)->GetObjectClass(env, vout_android_gui);<br></div>
<div>
> +    jclass cls = (*env)->GetObjectClass(env,<br></div>
<div>
> android_surface->vout_android_gui);<br></div>
<div>
>      jmethodID methodId = (*env)->GetMethodID(env, cls,<br></div>
<div>
>      "eventHardwareAccelerationError", "()V");<br></div>
<div>
> -    (*env)->CallVoidMethod(env, vout_android_gui, methodId);<br></div>
<div>
> +    (*env)->CallVoidMethod(env, android_surface->vout_android_gui,<br></div>
<div>
> methodId);<br></div>
<div>
><br></div>
<div>
>      (*env)->DeleteLocalRef(env, cls);<br></div>
<div>
>      if (isAttached)<br></div>
<div>
>          jni_detach_thread();<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -static void jni_SetSurfaceLayoutEnv(JNIEnv *p_env, int width, int<br></div>
<div>
> height, int visible_width, int visible_height, int sar_num, int sar_den)<br></div>
<div>
> +void jni_SetSurfaceLayoutEnv(JNIEnv *p_env, android_surf_value_t<br></div>
<div>
> *android_surface, int width, int height, int visible_width, int<br></div>
<div>
> visible_height, int sar_num, int sar_den)<br></div>
<div>
>  {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_gui == NULL) {<br></div>
<div>
> -        pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_gui == NULL) {<br></div>
<div>
> +        pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>          return;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    jclass cls = (*p_env)->GetObjectClass (p_env, vout_android_gui);<br></div>
<div>
> +    jclass cls = (*p_env)->GetObjectClass (p_env,<br></div>
<div>
> android_surface->vout_android_gui);<br></div>
<div>
>      jmethodID methodId = (*p_env)->GetMethodID (p_env, cls,<br></div>
<div>
>      "setSurfaceLayout", "(IIIIII)V");<br></div>
<div>
><br></div>
<div>
> -    (*p_env)->CallVoidMethod (p_env, vout_android_gui, methodId, width,<br></div>
<div>
> height, visible_width, visible_height, sar_num, sar_den);<br></div>
<div>
> +    (*p_env)->CallVoidMethod (p_env, android_surface->vout_android_gui,<br></div>
<div>
> methodId, width, height, visible_width, visible_height, sar_num,<br></div>
<div>
> sar_den);<br></div>
<div>
><br></div>
<div>
>      (*p_env)->DeleteLocalRef(p_env, cls);<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -void jni_SetSurfaceLayout(int width, int height, int visible_width, int<br></div>
<div>
> visible_height, int sar_num, int sar_den)<br></div>
<div>
> +void jni_SetSurfaceLayout(android_surf_value_t *android_surface, int<br></div>
<div>
> width, int height, int visible_width, int visible_height, int sar_num,<br></div>
<div>
> int sar_den)<br></div>
<div>
>  {<br></div>
<div>
>      JNIEnv *p_env;<br></div>
<div>
>      bool isAttached = false;<br></div>
<div>
><br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
>      if (jni_get_env(&p_env) < 0) {<br></div>
<div>
>          if (jni_attach_thread(&p_env, THREAD_NAME) < 0)<br></div>
<div>
>              return;<br></div>
<div>
>          isAttached = true;<br></div>
<div>
>      }<br></div>
<div>
> -    jni_SetSurfaceLayoutEnv(p_env, width, height, visible_width,<br></div>
<div>
> visible_height, sar_num, sar_den);<br></div>
<div>
> +    jni_SetSurfaceLayoutEnv(p_env, android_surface, width, height,<br></div>
<div>
> visible_width, visible_height, sar_num, sar_den);<br></div>
<div>
><br></div>
<div>
>      if (isAttached)<br></div>
<div>
>          jni_detach_thread();<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -void *jni_AndroidJavaSurfaceToNativeSurface(jobject *surf)<br></div>
<div>
> +void *jni_AndroidJavaSurfaceToNativeSurface(jobject surf)<br></div>
<div>
>  {<br></div>
<div>
>      JNIEnv *p_env;<br></div>
<div>
>      jclass clz;<br></div>
<div>
> @@ -154,28 +158,29 @@ void *jni_AndroidJavaSurfaceToNativeSurface(jobject<br></div>
<div>
> *surf)<br></div>
<div>
>      return native_surface;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -int jni_ConfigureSurface(jobject jsurf, int width, int height, int hal,<br></div>
<div>
> bool *configured)<br></div>
<div>
> +int jni_ConfigureSurface(android_surf_value_t *android_surface, int<br></div>
<div>
> width, int height, int hal, bool *configured)<br></div>
<div>
>  {<br></div>
<div>
>      JNIEnv *p_env;<br></div>
<div>
>      bool isAttached = false;<br></div>
<div>
>      int ret;<br></div>
<div>
><br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_gui == NULL) {<br></div>
<div>
> -        pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_gui == NULL) {<br></div>
<div>
> +        pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>          return -1;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      if (jni_get_env(&p_env) < 0) {<br></div>
<div>
>          if (jni_attach_thread(&p_env, THREAD_NAME) < 0) {<br></div>
<div>
> -            pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +            pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>              return -1;<br></div>
<div>
>          }<br></div>
<div>
>          isAttached = true;<br></div>
<div>
>      }<br></div>
<div>
> -    jclass clz = (*p_env)->GetObjectClass (p_env, vout_android_gui);<br></div>
<div>
> +    jclass clz = (*p_env)->GetObjectClass (p_env,<br></div>
<div>
> android_surface->vout_android_gui);<br></div>
<div>
>      jmethodID methodId = (*p_env)->GetMethodID (p_env, clz,<br></div>
<div>
>      "configureSurface", "(Landroid/view/Surface;III)I");<br></div>
<div>
> -    ret = (*p_env)->CallIntMethod (p_env, vout_android_gui, methodId,<br></div>
<div>
> jsurf, width, height, hal);<br></div>
<div>
> +    ret = (*p_env)->CallIntMethod (p_env,<br></div>
<div>
> android_surface->vout_android_gui, methodId,<br></div>
<div>
> +<br></div>
<div>
> android_surface->vout_android_java_surf, width, height, hal);<br></div>
<div>
>      if (ret >= 0 && configured)<br></div>
<div>
>          *configured = ret == 1;<br></div>
<div>
><br></div>
<div>
> @@ -183,62 +188,81 @@ int jni_ConfigureSurface(jobject jsurf, int width,<br></div>
<div>
> int height, int hal, bool *co<br></div>
<div>
><br></div>
<div>
>      if (isAttached)<br></div>
<div>
>          jni_detach_thread();<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>      return ret == -1 ? -1 : 0;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
> -bool jni_IsVideoPlayerActivityCreated() {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    bool result = vout_video_player_activity_created;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +bool jni_IsVideoPlayerActivityCreated(android_surf_value_t<br></div>
<div>
> *android_surface) {<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    bool result = android_surface->vout_video_player_activity_created;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>      return result;<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void<br></div>
<div>
>  Java_org_videolan_libvlc_LibVLC_eventVideoPlayerActivityCreated(JNIEnv<br></div>
<div>
>  *env, jobject thiz, jboolean created) {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    vout_video_player_activity_created = created;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t * android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    android_surface->vout_video_player_activity_created = created;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_attachSurface(JNIEnv *env, jobject<br></div>
<div>
>  thiz, jobject surf, jobject gui) {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -<br></div>
<div>
> -    if (vout_android_gui != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_gui);<br></div>
<div>
> -    if (vout_android_java_surf != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_java_surf);<br></div>
<div>
> -    vout_android_gui = (*env)->NewGlobalRef(env, gui);<br></div>
<div>
> -    vout_android_java_surf = (*env)->NewGlobalRef(env, surf);<br></div>
<div>
> -    pthread_cond_signal(&vout_android_surf_attached);<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t * android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_gui != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env, android_surface->vout_android_gui);<br></div>
<div>
> +    if (android_surface->vout_android_java_surf != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env,<br></div>
<div>
> android_surface->vout_android_java_surf);<br></div>
<div>
> +    android_surface->vout_android_gui = (*env)->NewGlobalRef(env, gui);<br></div>
<div>
> +    android_surface->vout_android_java_surf = (*env)->NewGlobalRef(env,<br></div>
<div>
> surf);<br></div>
<div>
> +    pthread_cond_signal(&android_surface->vout_android_surf_attached);<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_detachSurface(JNIEnv *env, jobject<br></div>
<div>
>  thiz) {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_gui != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_gui);<br></div>
<div>
> -    if (vout_android_java_surf != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_java_surf);<br></div>
<div>
> -    vout_android_gui = NULL;<br></div>
<div>
> -    vout_android_java_surf = NULL;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t * android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_gui != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env, android_surface->vout_android_gui);<br></div>
<div>
> +    if (android_surface->vout_android_java_surf != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env,<br></div>
<div>
> android_surface->vout_android_java_surf);<br></div>
<div>
> +    android_surface->vout_android_gui = NULL;<br></div>
<div>
> +    android_surface->vout_android_java_surf = NULL;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_attachSubtitlesSurface(JNIEnv *env,<br></div>
<div>
>  jobject thiz, jobject surf) {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_subtitles_surf != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);<br></div>
<div>
> -    vout_android_subtitles_surf = (*env)->NewGlobalRef(env, surf);<br></div>
<div>
> -    pthread_cond_signal(&vout_android_surf_attached);<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t * android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_subtitles_surf != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env,<br></div>
<div>
> android_surface->vout_android_subtitles_surf);<br></div>
<div>
> +    android_surface->vout_android_subtitles_surf =<br></div>
<div>
> (*env)->NewGlobalRef(env, surf);<br></div>
<div>
> +    pthread_cond_signal(&android_surface->vout_android_surf_attached);<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  void Java_org_videolan_libvlc_LibVLC_detachSubtitlesSurface(JNIEnv *env,<br></div>
<div>
>  jobject thiz) {<br></div>
<div>
> -    pthread_mutex_lock(&vout_android_lock);<br></div>
<div>
> -    if (vout_android_subtitles_surf != NULL)<br></div>
<div>
> -        (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);<br></div>
<div>
> -    vout_android_subtitles_surf = NULL;<br></div>
<div>
> -    pthread_mutex_unlock(&vout_android_lock);<br></div>
<div>
> +    android_surf_value_t * android_surface =<br></div>
<div>
> getAndroidSurfaceInstance(env, thiz);<br></div>
<div>
> +    if (android_surface == NULL)<br></div>
<div>
> +        return;<br></div>
<div>
> +<br></div>
<div>
> +    pthread_mutex_lock(&android_surface->vout_android_lock);<br></div>
<div>
> +    if (android_surface->vout_android_subtitles_surf != NULL)<br></div>
<div>
> +        (*env)->DeleteGlobalRef(env,<br></div>
<div>
> android_surface->vout_android_subtitles_surf);<br></div>
<div>
> +    android_surface->vout_android_subtitles_surf = NULL;<br></div>
<div>
> +    pthread_mutex_unlock(&android_surface->vout_android_lock);<br></div>
<div>
>  }<br></div>
<div>
><br></div>
<div>
>  static int mouse_x = -1;<br></div>
<div>
> diff --git a/libvlc/jni/vout.h b/libvlc/jni/vout.h<br></div>
<div>
> index c3d4fd7..6681b59 100644<br></div>
<div>
> --- a/libvlc/jni/vout.h<br></div>
<div>
> +++ b/libvlc/jni/vout.h<br></div>
<div>
> @@ -21,8 +21,27 @@<br></div>
<div>
>  #ifndef LIBVLCJNI_VOUT_H<br></div>
<div>
>  #define LIBVLCJNI_VOUT_H<br></div>
<div>
><br></div>
<div>
> -/* vout lock initialized in vout.c */<br></div>
<div>
> -pthread_mutex_t vout_android_lock;<br></div>
<div>
> -pthread_cond_t vout_android_surf_attached;<br></div>
<div>
> +#include <pthread.h><br></div>
<div>
> +<br></div>
<div>
> +<br></div>
<div>
> +typedef struct android_surf_value_t {<br></div>
<div>
> +    pthread_mutex_t   vout_android_lock;<br></div>
<div>
> +    pthread_cond_t    vout_android_surf_attached;<br></div>
<div>
> +    void             *vout_android_gui;<br></div>
<div>
> +    jobject           vout_android_java_surf;<br></div>
<div>
> +    jobject           vout_android_subtitles_surf;<br></div>
<div>
> +    bool              vout_video_player_activity_created;<br></div>
<div>
> +    int               i_window_width;<br></div>
<div>
> +    int               i_window_height;<br></div>
<div>
> +} android_surf_value_t;<br></div>
<div>
> +<br></div>
<div>
> +typedef struct libvlc_instance_sys_t {<br></div>
<div>
> +    void                    *p_this;<br></div>
<div>
> +    libvlc_instance_t       *p_libvlc;<br></div>
<div>
> +    libvlc_media_player_t   *p_mp;<br></div>
<div>
> +    android_surf_value_t    *p_surf;<br></div>
<div>
> +} libvlc_instance_sys_t;<br></div>
<div>
> +<br></div>
<div>
> +android_surf_value_t *getAndroidSurfaceInstance(JNIEnv *env, jobject<br></div>
<div>
> thiz);<br></div>
<div>
><br></div>
<div>
>  #endif // LIBVLCJNI_VOUT_H<br></div>
<div>
> diff --git a/libvlc/src/org/videolan/libvlc/EventHandler.java<br></div>
<div>
> b/libvlc/src/org/videolan/libvlc/EventHandler.java<br></div>
<div>
> index 4ec0861..2d13d30 100644<br></div>
<div>
> --- a/libvlc/src/org/videolan/libvlc/EventHandler.java<br></div>
<div>
> +++ b/libvlc/src/org/videolan/libvlc/EventHandler.java<br></div>
<div>
> @@ -97,19 +97,11 @@ public class EventHandler {<br></div>
<div>
>      public static final int HardwareAccelerationError         = 0x3000;<br></div>
<div>
><br></div>
<div>
>      private ArrayList<Handler> mEventHandler;<br></div>
<div>
> -    private static EventHandler mInstance;<br></div>
<div>
><br></div>
<div>
>      EventHandler() {<br></div>
<div>
>          mEventHandler = new ArrayList<Handler>();<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    public static EventHandler getInstance() {<br></div>
<div>
> -        if (mInstance == null) {<br></div>
<div>
> -            mInstance = new EventHandler();<br></div>
<div>
> -        }<br></div>
<div>
> -        return mInstance;<br></div>
<div>
> -    }<br></div>
<div>
> -<br></div>
<div>
>      public void addHandler(Handler handler) {<br></div>
<div>
>          if (!mEventHandler.contains(handler))<br></div>
<div>
>              mEventHandler.add(handler);<br></div>
<div>
> diff --git a/libvlc/src/org/videolan/libvlc/LibVLC.java<br></div>
<div>
> b/libvlc/src/org/videolan/libvlc/LibVLC.java<br></div>
<div>
> index 5d1f830..5273887 100644<br></div>
<div>
> --- a/libvlc/src/org/videolan/libvlc/LibVLC.java<br></div>
<div>
> +++ b/libvlc/src/org/videolan/libvlc/LibVLC.java<br></div>
<div>
> @@ -61,11 +61,12 @@ public class LibVLC {<br></div>
<div>
><br></div>
<div>
>      private static LibVLC sInstance;<br></div>
<div>
><br></div>
<div>
> +    private final EventHandler eventHandler = new EventHandler();<br></div>
<div>
> +<br></div>
<div>
>      /** libVLC instance C pointer */<br></div>
<div>
>      private long mLibVlcInstance = 0; // Read-only, reserved for JNI<br></div>
<div>
>      /** libvlc_media_player pointer and index */<br></div>
<div>
>      private int mInternalMediaPlayerIndex = 0; // Read-only, reserved<br></div>
<div>
>      for JNI<br></div>
<div>
> -    private long mInternalMediaPlayerInstance = 0; // Read-only,<br></div>
<div>
> reserved for JNI<br></div>
<div>
><br></div>
<div>
>      private MediaList mMediaList; // Pointer to media list being<br></div>
<div>
>      followed<br></div>
<div>
>      private MediaList mPrimaryList; // Primary/default media list; see<br></div>
<div>
>      getPrimaryMediaList()<br></div>
<div>
> @@ -190,10 +191,9 @@ public class LibVLC {<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      /**<br></div>
<div>
> -     * Constructor<br></div>
<div>
> -     * It is private because this class is a singleton.<br></div>
<div>
> +     * Constructor.<br></div>
<div>
>       */<br></div>
<div>
> -    private LibVLC() {<br></div>
<div>
> +    public LibVLC() {<br></div>
<div>
>          mAout = new AudioOutput();<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> @@ -259,7 +259,7 @@ public class LibVLC {<br></div>
<div>
>       */<br></div>
<div>
>      public native void setSurface(Surface f);<br></div>
<div>
><br></div>
<div>
> -    public static synchronized void restart(Context context) {<br></div>
<div>
> +    public static synchronized void restartInstance(Context context) {<br></div>
<div>
>          if (sInstance != null) {<br></div>
<div>
>              try {<br></div>
<div>
>                  sInstance.destroy();<br></div>
<div>
> @@ -270,6 +270,15 @@ public class LibVLC {<br></div>
<div>
>          }<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> +    public void restart(Context context) {<br></div>
<div>
> +        try {<br></div>
<div>
> +            this.destroy();<br></div>
<div>
> +            this.init(context);<br></div>
<div>
> +        } catch (LibVlcException lve) {<br></div>
<div>
> +            Log.e(TAG, "Unable to reinit libvlc: " + lve);<br></div>
<div>
> +        }<br></div>
<div>
> +    }<br></div>
<div>
> +<br></div>
<div>
>      /**<br></div>
<div>
>       * those get/is* are called from native code to get settings values.<br></div>
<div>
>       */<br></div>
<div>
> @@ -488,11 +497,11 @@ public class LibVLC {<br></div>
<div>
>          applyEqualizer();<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    private void applyEqualizer()<br></div>
<div>
> +    protected void applyEqualizer()<br></div>
<div>
>      {<br></div>
<div>
> -        setNativeEqualizer(mInternalMediaPlayerInstance,<br></div>
<div>
> this.equalizer);<br></div>
<div>
> +        setNativeEqualizer(this.equalizer);<br></div>
<div>
>      }<br></div>
<div>
> -    private native int setNativeEqualizer(long mediaPlayer, float[]<br></div>
<div>
> bands);<br></div>
<div>
> +    private native int setNativeEqualizer(float[] bands);<br></div>
<div>
><br></div>
<div>
>      public boolean frameSkipEnabled() {<br></div>
<div>
>          return frameSkip;<br></div>
<div>
> @@ -538,7 +547,6 @@ public class LibVLC {<br></div>
<div>
>              mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath()<br></div>
<div>
>              : null;<br></div>
<div>
>              nativeInit();<br></div>
<div>
>              mMediaList = mPrimaryList = new MediaList(this);<br></div>
<div>
> -            setEventHandler(EventHandler.getInstance());<br></div>
<div>
>              mIsInitialized = true;<br></div>
<div>
>          }<br></div>
<div>
>      }<br></div>
<div>
> @@ -550,7 +558,6 @@ public class LibVLC {<br></div>
<div>
>      public void destroy() {<br></div>
<div>
>          Log.v(TAG, "Destroying LibVLC instance");<br></div>
<div>
>          nativeDestroy();<br></div>
<div>
> -        detachEventHandler();<br></div>
<div>
>          mIsInitialized = false;<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> @@ -830,10 +837,6 @@ public class LibVLC {<br></div>
<div>
>          return mMediaList.expandMedia(mInternalMediaPlayerIndex);<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> -    private native void setEventHandler(EventHandler eventHandler);<br></div>
<div>
> -<br></div>
<div>
> -    private native void detachEventHandler();<br></div>
<div>
> -<br></div>
<div>
>      public native float[] getBands();<br></div>
<div>
><br></div>
<div>
>      public native String[] getPresets();<br></div>
<div>
> @@ -853,6 +856,10 @@ public class LibVLC {<br></div>
<div>
>              mOnNativeCrashListener.onNativeCrash();<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> +    public EventHandler getEventHandler() {<br></div>
<div>
> +        return eventHandler;<br></div>
<div>
> +    }<br></div>
<div>
> +<br></div>
<div>
>      public String getCachePath() {<br></div>
<div>
>          return mCachePath;<br></div>
<div>
>      }<br></div>
<div>
> diff --git a/vlc-android/src/org/videolan/vlc/audio/AudioService.java<br></div>
<div>
> b/vlc-android/src/org/videolan/vlc/audio/AudioService.java<br></div>
<div>
> index c33abc8..d039fba 100644<br></div>
<div>
> --- a/vlc-android/src/org/videolan/vlc/audio/AudioService.java<br></div>
<div>
> +++ b/vlc-android/src/org/videolan/vlc/audio/AudioService.java<br></div>
<div>
> @@ -116,7 +116,6 @@ public class AudioService extends Service {<br></div>
<div>
><br></div>
<div>
>      private LibVLC mLibVLC;<br></div>
<div>
>      private HashMap<IAudioServiceCallback, Integer> mCallback;<br></div>
<div>
> -    private EventHandler mEventHandler;<br></div>
<div>
>      private OnAudioFocusChangeListener audioFocusListener;<br></div>
<div>
>      private boolean mDetectHeadset = true;<br></div>
<div>
>      private PowerManager.WakeLock mWakeLock;<br></div>
<div>
> @@ -165,7 +164,6 @@ public class AudioService extends Service {<br></div>
<div>
>          mPrevIndex = -1;<br></div>
<div>
>          mNextIndex = -1;<br></div>
<div>
>          mPrevious = new Stack<Integer>();<br></div>
<div>
> -        mEventHandler = EventHandler.getInstance();<br></div>
<div>
>          mRemoteControlClientReceiverComponent = new<br></div>
<div>
>          ComponentName(getPackageName(),<br></div>
<div>
>                  RemoteControlClientReceiver.class.getName());<br></div>
<div>
><br></div>
<div>
> @@ -346,7 +344,7 @@ public class AudioService extends Service {<br></div>
<div>
>              }<br></div>
<div>
><br></div>
<div>
>              /*<br></div>
<div>
> -             * Incoming Call : Pause if VLC is playing audio or video.<br></div>
<div>
> +             * Incoming Call : Pause if VLC is playing audio or video.<br></div>
<div>
>               */<br></div>
<div>
>              if<br></div>
<div>
>              (action.equalsIgnoreCase(VLCApplication.INCOMING_CALL_INTENT))<br></div>
<div>
>              {<br></div>
<div>
>                  mWasPlayingAudio = mLibVLC.isPlaying() &&<br></div>
<div>
>                  mLibVLC.getVideoTracksCount() < 1;<br></div>
<div>
> @@ -625,7 +623,7 @@ public class AudioService extends Service {<br></div>
<div>
>          String MRL = mLibVLC.getMediaList().getMRL(mCurrentIndex);<br></div>
<div>
>          int index = mCurrentIndex;<br></div>
<div>
>          mCurrentIndex = -1;<br></div>
<div>
> -        mEventHandler.removeHandler(mVlcEventHandler);<br></div>
<div>
> +        mLibVLC.getEventHandler().removeHandler(mVlcEventHandler);<br></div>
<div>
>          // Preserve playback when switching to video<br></div>
<div>
>          hideNotification(false);<br></div>
<div>
><br></div>
<div>
> @@ -833,7 +831,7 @@ public class AudioService extends Service {<br></div>
<div>
><br></div>
<div>
>      private void stop() {<br></div>
<div>
>          mLibVLC.stop();<br></div>
<div>
> -        mEventHandler.removeHandler(mVlcEventHandler);<br></div>
<div>
> +        mLibVLC.getEventHandler().removeHandler(mVlcEventHandler);<br></div>
<div>
>          mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);<br></div>
<div>
>          setRemoteControlClientPlaybackState(EventHandler.MediaPlayerStopped);<br></div>
<div>
>          mCurrentIndex = -1;<br></div>
<div>
> @@ -1158,7 +1156,7 @@ public class AudioService extends Service {<br></div>
<div>
>                  throws RemoteException {<br></div>
<div>
><br></div>
<div>
>              Log.v(TAG, "Loading position " +<br></div>
<div>
>              ((Integer)position).toString() + " in " +<br></div>
<div>
>              mediaPathList.toString());<br></div>
<div>
> -            mEventHandler.addHandler(mVlcEventHandler);<br></div>
<div>
> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);<br></div>
<div>
><br></div>
<div>
>              mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);<br></div>
<div>
>              mLibVLC.setMediaList();<br></div>
<div>
> @@ -1226,7 +1224,7 @@ public class AudioService extends Service {<br></div>
<div>
>                  mCurrentIndex = 0;<br></div>
<div>
>              }<br></div>
<div>
><br></div>
<div>
> -            mEventHandler.addHandler(mVlcEventHandler);<br></div>
<div>
> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);<br></div>
<div>
>              mLibVLC.playIndex(mCurrentIndex);<br></div>
<div>
>              mHandler.sendEmptyMessage(SHOW_PROGRESS);<br></div>
<div>
>              setUpRemoteControlClient();<br></div>
<div>
> @@ -1250,7 +1248,7 @@ public class AudioService extends Service {<br></div>
<div>
><br></div>
<div>
>              if(URI == null || !mLibVLC.isPlaying())<br></div>
<div>
>                  return;<br></div>
<div>
> -            mEventHandler.addHandler(mVlcEventHandler);<br></div>
<div>
> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);<br></div>
<div>
>              mCurrentIndex = index;<br></div>
<div>
><br></div>
<div>
>              // Notify everyone<br></div>
<div>
> diff --git<br></div>
<div>
> a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java<br></div>
<div>
> b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java<br></div>
<div>
> index 9f0109c..b069452 100644<br></div>
<div>
> --- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java<br></div>
<div>
> +++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java<br></div>
<div>
> @@ -292,7 +292,7 @@ public class PreferencesActivity extends<br></div>
<div>
> PreferenceActivity implements OnSharedP<br></div>
<div>
>                  || key.equalsIgnoreCase("network_caching")<br></div>
<div>
>                  || key.equalsIgnoreCase("dev_hardware_decoder")) {<br></div>
<div>
>              VLCInstance.updateLibVlcSettings(sharedPreferences);<br></div>
<div>
> -            LibVLC.restart(this);<br></div>
<div>
> +            LibVLC.restartInstance(this);<br></div>
<div>
>          }<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
> diff --git<br></div>
<div>
> a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br></div>
<div>
> b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br></div>
<div>
> index 4cf4793..195de50 100644<br></div>
<div>
> --- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br></div>
<div>
> +++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java<br></div>
<div>
> @@ -439,8 +439,7 @@ public class VideoPlayerActivity extends<br></div>
<div>
> ActionBarActivity implements IVideoPlay<br></div>
<div>
>          // SurfaceView is now available for MediaCodec direct rendering.<br></div>
<div>
>          mLibVLC.eventVideoPlayerActivityCreated(true);<br></div>
<div>
><br></div>
<div>
> -        EventHandler em = EventHandler.getInstance();<br></div>
<div>
> -        em.addHandler(eventHandler);<br></div>
<div>
> +        mLibVLC.getEventHandler().addHandler(eventHandler);<br></div>
<div>
><br></div>
<div>
>          this.setVolumeControlStream(AudioManager.STREAM_MUSIC);<br></div>
<div>
><br></div>
<div>
> @@ -590,8 +589,7 @@ public class VideoPlayerActivity extends<br></div>
<div>
> ActionBarActivity implements IVideoPlay<br></div>
<div>
>          super.onDestroy();<br></div>
<div>
>          unregisterReceiver(mReceiver);<br></div>
<div>
><br></div>
<div>
> -        EventHandler em = EventHandler.getInstance();<br></div>
<div>
> -        em.removeHandler(eventHandler);<br></div>
<div>
> +        mLibVLC.getEventHandler().removeHandler(eventHandler);<br></div>
<div>
><br></div>
<div>
>          // MediaCodec opaque direct rendering should not be used anymore<br></div>
<div>
>          since there is no surface to attach.<br></div>
<div>
>          mLibVLC.eventVideoPlayerActivityCreated(false);<br></div>
<div>
> @@ -1228,8 +1226,7 @@ public class VideoPlayerActivity extends<br></div>
<div>
> ActionBarActivity implements IVideoPlay<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      public void eventHardwareAccelerationError() {<br></div>
<div>
> -        EventHandler em = EventHandler.getInstance();<br></div>
<div>
> -        em.callback(EventHandler.HardwareAccelerationError, new<br></div>
<div>
> Bundle());<br></div>
<div>
> +<br></div>
<div>
> mLibVLC.getEventHandler().callback(EventHandler.HardwareAccelerationError,<br></div>
<div>
> new Bundle());<br></div>
<div>
>      }<br></div>
<div>
><br></div>
<div>
>      private void handleHardwareAccelerationError() {<br></div>
<div>
> --<br></div>
<div>
> 1.9.3 (Apple Git-50)<br></div>
<div>
><br></div>
<div>
><br></div>
</div>
<div>> _______________________________________________<br></div>
<div>
> Android mailing list<br></div>
<div>
> <a href="mailto:Android@videolan.org">Android@videolan.org</a><br></div>
<div>
> <a href="https://mailman.videolan.org/listinfo/android" target="_blank">https://mailman.videolan.org/listinfo/android</a><br></div>
<div>
><br></div>
<div> </div>
<div>
The rest is good.<br></div>
<div>
_______________________________________________<br></div>
<div>
Android mailing list<br></div>
<div> <a href="mailto:Android@videolan.org">Android@videolan.org</a><br></div>
<div> <a href="https://mailman.videolan.org/listinfo/android" target="_blank">https://mailman.videolan.org/listinfo/android</a><br></div>
</blockquote></div>
<div> </div>
</div>
<div><u>_______________________________________________</u><br></div>
<div>Android mailing list<br></div>
<div><a href="mailto:Android@videolan.org">Android@videolan.org</a><br></div>
<div><a href="https://mailman.videolan.org/listinfo/android">https://mailman.videolan.org/listinfo/android</a><br></div>
</blockquote><div> </div>
</body>
</html>