[Android] [PATCH 3/3] Add support for multiple video instances.

Paulo Vitor Magacho da Silva pvmagacho at gmail.com
Thu Jan 15 19:36:04 CET 2015


Hi,
I will probably have to update these patches. Could you tell me if they
could get applied?
Thank you,
Paulo

2014-12-17 21:03 GMT-02:00 Paulo Vitor Magacho da Silva <pvmagacho at gmail.com
>:

> Hi,
> I wonder if this will be applied ?
> Thanks,
> Paulo
>
> 2014-12-11 1:17 GMT-02:00 Paulo Vitor Magacho da Silva <
> pvmagacho at gmail.com>:
>
>> ---
>>  libvlc/jni/libvlcjni-equalizer.c                   |   4 +-
>>  libvlc/jni/libvlcjni-util.c                        |  17 --
>>  libvlc/jni/libvlcjni.c                             | 179
>> +++++++++++---------
>>  libvlc/jni/native_crash_handler.c                  |  25 +--
>>  libvlc/jni/native_crash_handler.h                  |   5 +-
>>  libvlc/jni/utils.h                                 |   2 -
>>  libvlc/jni/vout.c                                  | 188
>> ++++++++++++---------
>>  libvlc/jni/vout.h                                  |  24 ++-
>>  libvlc/src/org/videolan/libvlc/EventHandler.java   |   8 -
>>  libvlc/src/org/videolan/libvlc/LibVLC.java         | 100 +++--------
>>  libvlc/src/org/videolan/libvlc/LibVlcUtil.java     |  56 +++++-
>>  .../org/videolan/libvlc/NativeCrashHandler.java    |  64 +++++++
>>  .../src/org/videolan/vlc/VLCApplication.java       |  15 +-
>>  .../src/org/videolan/vlc/audio/AudioService.java   |  14 +-
>>  .../org/videolan/vlc/gui/PreferencesActivity.java  |   2 +-
>>  .../vlc/gui/video/VideoPlayerActivity.java         |   9 +-
>>  .../src/org/videolan/vlc/util/VLCInstance.java     |  14 +-
>>  17 files changed, 398 insertions(+), 328 deletions(-)
>>  create mode 100644 libvlc/src/org/videolan/libvlc/NativeCrashHandler.java
>>
>> diff --git a/libvlc/jni/libvlcjni-equalizer.c
>> b/libvlc/jni/libvlcjni-equalizer.c
>> index 2dad0e4..d11f24d 100644
>> --- a/libvlc/jni/libvlcjni-equalizer.c
>> +++ b/libvlc/jni/libvlcjni-equalizer.c
>> @@ -89,10 +89,10 @@ jfloatArray
>> Java_org_videolan_libvlc_LibVLC_getPreset(JNIEnv *env, jobject thiz,
>>   * apply equalizer settings (param bands is float[] (first element is
>> preamp, then bands))
>>   */
>>  //"--audio-filter=equalizer", "--equalizer-bands=-3.5 -4.5 -1 0 0 5 8 8
>> 8 8",
>> -jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,
>> jobject thiz, jlong media_player, jfloatArray bands)
>> +jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,
>> jobject thiz, jfloatArray bands)
>>  {
>>      jint res = -1;
>> -    libvlc_media_player_t *mp =
>> (libvlc_media_player_t*)(intptr_t)media_player;
>> +    libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
>>      if (!mp)
>>          return res;
>>
>> diff --git a/libvlc/jni/libvlcjni-util.c b/libvlc/jni/libvlcjni-util.c
>> index 205d59d..67c2554 100644
>> --- a/libvlc/jni/libvlcjni-util.c
>> +++ b/libvlc/jni/libvlcjni-util.c
>> @@ -131,23 +131,6 @@ void arrayListStringAdd(JNIEnv *env, jclass class,
>> jmethodID methodID, jobject a
>>      (*env)->DeleteLocalRef(env, jstr);
>>  }
>>
>> -jobject getEventHandlerReference(JNIEnv *env, jobject thiz, jobject
>> eventHandler)
>> -{
>> -    jclass cls = (*env)->GetObjectClass(env, eventHandler);
>> -    if (!cls) {
>> -        LOGE("setEventHandler: failed to get class reference");
>> -        return NULL;
>> -    }
>> -
>> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",
>> "(ILandroid/os/Bundle;)V");
>> -    if (!methodID) {
>> -        LOGE("setEventHandler: failed to get the callback method");
>> -        return NULL;
>> -    }
>> -
>> -    return (*env)->NewGlobalRef(env, eventHandler);
>> -}
>> -
>>  static void debug_buffer_log(void *data, int level, const char *fmt,
>> va_list ap)
>>  {
>>      bool isAttached = false;
>> diff --git a/libvlc/jni/libvlcjni.c b/libvlc/jni/libvlcjni.c
>> index a9662db..78f5e25 100644
>> --- a/libvlc/jni/libvlcjni.c
>> +++ b/libvlc/jni/libvlcjni.c
>> @@ -38,7 +38,6 @@
>>  #include "aout.h"
>>  #include "vout.h"
>>  #include "utils.h"
>> -#include "native_crash_handler.h"
>>
>>  #define VOUT_ANDROID_SURFACE 0
>>  #define VOUT_OPENGLES2       1
>> @@ -60,6 +59,26 @@ int jni_attach_thread(JNIEnv **env, const char
>> *thread_name);
>>  void jni_detach_thread();
>>  int jni_get_env(JNIEnv **env);
>>
>> +static void setLibVlcSysInstance(JNIEnv *env, jobject thiz,
>> libvlc_instance_sys_t *p_sys)
>> +{
>> +    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) p_sys);
>> +}
>> +
>> +static libvlc_instance_sys_t *getLibVlcSysInstance(JNIEnv *env, jobject
>> thiz)
>> +{
>> +    return (libvlc_instance_sys_t *)(intptr_t)getLong(env, thiz,
>> "mLibVlcInstance");
>> +}
>> +
>> +static void releaseMediaPlayer(JNIEnv *env, jobject thiz)
>> +{
>> +    libvlc_media_player_t *p_mp = getMediaPlayer(env, thiz);
>> +    if (p_mp)
>> +    {
>> +        libvlc_media_player_stop(p_mp);
>> +        libvlc_media_player_release(p_mp);
>> +    }
>> +}
>> +
>>  static void add_media_options(libvlc_media_t *p_md, JNIEnv *env,
>> jobjectArray mediaOptions)
>>  {
>>      int stringCount = (*env)->GetArrayLength(env, mediaOptions);
>> @@ -98,24 +117,20 @@ libvlc_media_t *new_media(JNIEnv *env, jobject thiz,
>> jstring fileLocation, bool
>>
>>  libvlc_instance_t *getLibVlcInstance(JNIEnv *env, jobject thiz)
>>  {
>> -    return (libvlc_instance_t*)(intptr_t)getLong(env, thiz,
>> "mLibVlcInstance");
>> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>> +    return p_sys ? p_sys->p_libvlc : NULL;
>>  }
>>
>> -libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)
>> +android_surf_value_t *getAndroidSurfaceInstance(JNIEnv *env, jobject
>> thiz)
>>  {
>> -    return (libvlc_media_player_t*)(intptr_t)getLong(env, thiz,
>> "mInternalMediaPlayerInstance");
>> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>> +    return p_sys ? p_sys->p_surf : NULL;
>>  }
>>
>> -
>> -static void releaseMediaPlayer(JNIEnv *env, jobject thiz)
>> +libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)
>>  {
>> -    libvlc_media_player_t* p_mp = getMediaPlayer(env, thiz);
>> -    if (p_mp)
>> -    {
>> -        libvlc_media_player_stop(p_mp);
>> -        libvlc_media_player_release(p_mp);
>> -        setLong(env, thiz, "mInternalMediaPlayerInstance", 0);
>> -    }
>> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>> +    return p_sys ? p_sys->p_mp : NULL;
>>  }
>>
>>  /* Pointer to the Java virtual machine
>> @@ -124,17 +139,12 @@ static void releaseMediaPlayer(JNIEnv *env, jobject
>> thiz)
>>   */
>>  static JavaVM *myVm;
>>
>> -static jobject eventHandlerInstance = NULL;
>> -
>>  static void vlc_event_callback(const libvlc_event_t *ev, void *data)
>>  {
>>      JNIEnv *env;
>>
>>      bool isAttached = false;
>>
>> -    if (eventHandlerInstance == NULL)
>> -        return;
>> -
>>      if (jni_get_env(&env) < 0) {
>>          if (jni_attach_thread(&env, THREAD_NAME) < 0)
>>              return;
>> @@ -193,20 +203,31 @@ static void vlc_event_callback(const libvlc_event_t
>> *ev, void *data)
>>          free(mrl);
>>      }
>>
>> +    /* The LibVLC object */
>> +    jobject vlcObject = (jobject) data;
>> +
>> +    /* Get the event handler object */
>> +    jclass cls = (*env)->GetObjectClass(env, vlcObject);
>> +    jmethodID methodId = (*env)->GetMethodID(env, cls,
>> "getEventHandler", "()Lorg/videolan/libvlc/EventHandler;");
>> +    jobject eventHandlerInstance = (*env)->CallObjectMethod(env,
>> vlcObject, methodId);
>> +
>> +    (*env)->DeleteLocalRef(env, cls);
>> +
>>      /* Get the object class */
>> -    jclass cls = (*env)->GetObjectClass(env, eventHandlerInstance);
>> +    cls = (*env)->GetObjectClass(env, eventHandlerInstance);
>>      if (!cls) {
>>          LOGE("EventHandler: failed to get class reference");
>>          goto end;
>>      }
>>
>>      /* Find the callback ID */
>> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",
>> "(ILandroid/os/Bundle;)V");
>> -    if (methodID) {
>> -        (*env)->CallVoidMethod(env, eventHandlerInstance, methodID,
>> ev->type, bundle);
>> +    methodId = (*env)->GetMethodID(env, cls, "callback",
>> "(ILandroid/os/Bundle;)V");
>> +    if (methodId) {
>> +        (*env)->CallVoidMethod(env, eventHandlerInstance, methodId,
>> ev->type, bundle);
>>      } else {
>>          LOGE("EventHandler: failed to get the callback method");
>>      }
>> +    (*env)->DeleteLocalRef(env, cls);
>>
>>  end:
>>      (*env)->DeleteLocalRef(env, bundle);
>> @@ -219,16 +240,12 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)
>>      // Keep a reference on the Java VM.
>>      myVm = vm;
>>
>> -    pthread_mutex_init(&vout_android_lock, NULL);
>> -    pthread_cond_init(&vout_android_surf_attached, NULL);
>> -
>>      LOGD("JNI interface loaded.");
>>      return VLC_JNI_VERSION;
>>  }
>>
>>  void JNI_OnUnload(JavaVM* vm, void* reserved) {
>> -    pthread_mutex_destroy(&vout_android_lock);
>> -    pthread_cond_destroy(&vout_android_surf_attached);
>> +    LOGD("JNI interface un-loaded.");
>>  }
>>
>>  int jni_attach_thread(JNIEnv **env, const char *thread_name)
>> @@ -354,8 +371,6 @@ void
>> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
>>      };
>>      libvlc_instance_t *instance = libvlc_new(sizeof(argv) /
>> sizeof(*argv), argv);
>>
>> -    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) instance);
>> -
>>      (*env)->ReleaseStringUTFChars(env, chroma, chromastr);
>>      (*env)->ReleaseStringUTFChars(env, subsencoding, subsencodingstr);
>>
>> @@ -365,45 +380,45 @@ void
>> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
>>          (*env)->ThrowNew(env, exc, "Unable to instantiate LibVLC");
>>      }
>>
>> +    /* Set values to libvlc sys instance */
>> +    libvlc_instance_sys_t  *p_sys = (libvlc_instance_sys_t *) calloc(1,
>> sizeof(libvlc_instance_sys_t));
>> +    p_sys->p_libvlc = instance;
>> +    p_sys->p_surf = (android_surf_value_t *) calloc(1,
>> sizeof(android_surf_value_t));
>> +    p_sys->p_this = (*env)->NewGlobalRef(env, thiz);
>> +
>> +    pthread_mutex_init(&p_sys->p_surf->vout_android_lock, NULL);
>> +    pthread_cond_init(&p_sys->p_surf->vout_android_surf_attached, NULL);
>> +
>> +    setLibVlcSysInstance(env, thiz, p_sys);
>> +
>>      LOGI("LibVLC initialized: %p", instance);
>>
>>      libvlc_log_set(instance, debug_log, &verbosity);
>> -
>> -    init_native_crash_handler(env, thiz);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject
>> thiz)
>>  {
>> -    destroy_native_crash_handler(env);
>> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>> +    if (p_sys == NULL)
>> +        return; // Already destroyed
>>
>>      releaseMediaPlayer(env, thiz);
>> -    jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
>> -    if (!libVlcInstance)
>> -        return; // Already destroyed
>>
>> -    libvlc_instance_t *instance = (libvlc_instance_t*)(intptr_t)
>> libVlcInstance;
>> +    libvlc_instance_t *instance = p_sys->p_libvlc;
>> +    LOGI("LibVLC destroyed: %p", instance);
>> +
>>      libvlc_log_unset(instance);
>>      libvlc_release(instance);
>>
>> -    setLong(env, thiz, "mLibVlcInstance", 0);
>> -}
>> +    (*env)->DeleteGlobalRef(env, p_sys->p_this);
>>
>> -void Java_org_videolan_libvlc_LibVLC_detachEventHandler(JNIEnv *env,
>> jobject thiz)
>> -{
>> -    if (eventHandlerInstance != NULL) {
>> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
>> -        eventHandlerInstance = NULL;
>> -    }
>> -}
>> +    pthread_mutex_destroy(&p_sys->p_surf->vout_android_lock);
>> +    pthread_cond_destroy(&p_sys->p_surf->vout_android_surf_attached);
>>
>> -void Java_org_videolan_libvlc_LibVLC_setEventHandler(JNIEnv *env,
>> jobject thiz, jobject eventHandler)
>> -{
>> -    if (eventHandlerInstance != NULL) {
>> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
>> -        eventHandlerInstance = NULL;
>> -    }
>> +    free(p_sys->p_surf);
>> +    free(p_sys);
>>
>> -    eventHandlerInstance = getEventHandlerReference(env, thiz,
>> eventHandler);
>> +    setLibVlcSysInstance(env, thiz, NULL);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,
>> @@ -412,25 +427,24 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
>> *env, jobject thiz,
>>      /* Release previous media player, if any */
>>      releaseMediaPlayer(env, thiz);
>>
>> -    libvlc_instance_t *p_instance = getLibVlcInstance(env, thiz);
>> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>>
>>      /* Create a media player playing environment */
>> -    libvlc_media_player_t *mp = libvlc_media_player_new(p_instance);
>> -    libvlc_media_player_set_video_title_display(mp,
>> libvlc_position_disable, 0);
>> -    jobject myJavaLibVLC = (*env)->NewGlobalRef(env, thiz);
>> +    p_sys->p_mp = libvlc_media_player_new(p_sys->p_libvlc);
>> +
>> +    libvlc_media_player_set_video_title_display(p_sys->p_mp,
>> libvlc_position_disable, 0);
>>
>>      //if AOUT_AUDIOTRACK_JAVA, we use amem
>>      jclass cls = (*env)->GetObjectClass(env, thiz);
>>      jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout", "()I");
>>      if ( (*env)->CallIntMethod(env, thiz, methodId) ==
>> AOUT_AUDIOTRACK_JAVA )
>>      {
>> -        libvlc_audio_set_callbacks(mp, aout_play, aout_pause, NULL,
>> NULL, NULL,
>> -                                   (void*) myJavaLibVLC);
>> -        libvlc_audio_set_format_callbacks(mp, aout_open, aout_close);
>> +        libvlc_audio_set_callbacks(p_sys->p_mp, aout_play, aout_pause,
>> NULL, NULL, NULL, p_sys->p_this);
>> +        libvlc_audio_set_format_callbacks(p_sys->p_mp, aout_open,
>> aout_close);
>>      }
>>
>>      /* Connect the event manager */
>> -    libvlc_event_manager_t *ev = libvlc_media_player_event_manager(mp);
>> +    libvlc_event_manager_t *ev =
>> libvlc_media_player_event_manager(p_sys->p_mp);
>>      static const libvlc_event_type_t mp_events[] = {
>>          libvlc_MediaPlayerPlaying,
>>          libvlc_MediaPlayerPaused,
>> @@ -442,10 +456,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
>> *env, jobject thiz,
>>          libvlc_MediaPlayerEncounteredError
>>      };
>>      for(int i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); i++)
>> -        libvlc_event_attach(ev, mp_events[i], vlc_event_callback, myVm);
>> -
>> -    /* Keep a pointer to this media player */
>> -    setLong(env, thiz, "mInternalMediaPlayerInstance",
>> (jlong)(intptr_t)mp);
>> +        libvlc_event_attach(ev, mp_events[i], vlc_event_callback,
>> p_sys->p_this);
>>
>>      cls = (*env)->GetObjectClass(env, thiz);
>>      jmethodID methodID = (*env)->GetMethodID(env, cls, "applyEqualizer",
>> "()V");
>> @@ -453,13 +464,16 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
>> *env, jobject thiz,
>>
>>      const char* p_mrl = (*env)->GetStringUTFChars(env, mrl, 0);
>>
>> -    libvlc_media_t* p_md = libvlc_media_new_location(p_instance, p_mrl);
>> +    libvlc_media_t* p_md = libvlc_media_new_location(p_sys->p_libvlc,
>> p_mrl);
>>      /* media options */
>>      if (mediaOptions != NULL)
>>          add_media_options(p_md, env, mediaOptions);
>>
>>      (*env)->ReleaseStringUTFChars(env, mrl, p_mrl);
>>
>> +    /* set the Android surface value structure before playing */
>> +    libvlc_media_player_set_androidobject(p_sys->p_mp, p_sys->p_surf);
>> +
>>      /* Connect the media event manager. */
>>      libvlc_event_manager_t *ev_media = libvlc_media_event_manager(p_md);
>>      static const libvlc_event_type_t mp_media_events[] = {
>> @@ -467,10 +481,10 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
>> *env, jobject thiz,
>>          libvlc_MediaMetaChanged,
>>      };
>>      for(int i = 0; i < (sizeof(mp_media_events) /
>> sizeof(*mp_media_events)); i++)
>> -        libvlc_event_attach(ev_media, mp_media_events[i],
>> vlc_event_callback, myVm);
>> +        libvlc_event_attach(ev_media, mp_media_events[i],
>> vlc_event_callback, p_sys->p_this);
>>
>> -    libvlc_media_player_set_media(mp, p_md);
>> -    libvlc_media_player_play(mp);
>> +    libvlc_media_player_set_media(p_sys->p_mp, p_md);
>> +    libvlc_media_player_play(p_sys->p_mp);
>>  }
>>
>>  jfloat Java_org_videolan_libvlc_LibVLC_getRate(JNIEnv *env, jobject
>> thiz) {
>> @@ -655,23 +669,26 @@ void
>> Java_org_videolan_libvlc_LibVLC_playerNavigate(JNIEnv *env, jobject thiz, j
>>          libvlc_media_player_navigate(mp, (unsigned) nav);
>>  }
>>
>> -// TODO: remove static variables
>> -static int i_window_width = 0;
>> -static int i_window_height = 0;
>> -
>>  void Java_org_videolan_libvlc_LibVLC_setWindowSize(JNIEnv *env, jobject
>> thiz, jint width, jint height)
>>  {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    i_window_width = width;
>> -    i_window_height = height;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t *android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    android_surface->i_window_width = width;
>> +    android_surface->i_window_height = height;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>> -int jni_GetWindowSize(int *width, int *height)
>> +int jni_GetWindowSize(android_surf_value_t *android_surface, int *width,
>> int *height)
>>  {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    *width = i_window_width;
>> -    *height = i_window_height;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    *width = android_surface->i_window_width;
>> +    *height = android_surface->i_window_height;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>      return 0;
>>  }
>> diff --git a/libvlc/jni/native_crash_handler.c
>> b/libvlc/jni/native_crash_handler.c
>> index 2cb1590..73b1e1e 100644
>> --- a/libvlc/jni/native_crash_handler.c
>> +++ b/libvlc/jni/native_crash_handler.c
>> @@ -23,7 +23,7 @@
>>  #include "native_crash_handler.h"
>>
>>  static struct sigaction old_actions[NSIG];
>> -static jobject j_libVLC;
>> +static jobject j_NativeCrashHandler = NULL;
>>
>>  #define THREAD_NAME "native_crash_handler"
>>  extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
>> @@ -54,9 +54,9 @@ void sigaction_callback(int signal, siginfo_t *info,
>> void *reserved)
>>      JNIEnv *env;
>>      jni_attach_thread(&env, THREAD_NAME);
>>
>> -    jclass cls = (*env)->GetObjectClass(env, j_libVLC);
>> +    jclass cls = (*env)->GetObjectClass(env, j_NativeCrashHandler);
>>      jmethodID methodId = (*env)->GetMethodID(env, cls, "onNativeCrash",
>> "()V");
>> -    (*env)->CallVoidMethod(env, j_libVLC, methodId);
>> +    (*env)->CallVoidMethod(env, j_NativeCrashHandler, methodId);
>>
>>      (*env)->DeleteLocalRef(env, cls);
>>      jni_detach_thread();
>> @@ -65,10 +65,8 @@ void sigaction_callback(int signal, siginfo_t *info,
>> void *reserved)
>>      old_actions[signal].sa_handler(signal);
>>  }
>>
>> -
>> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)
>> +void Java_org_videolan_libvlc_NativeCrashHandler_nativeInit(JNIEnv *env,
>> jobject thiz)
>>  {
>> -    j_libVLC = (*env)->NewGlobalRef(env, j_libVLC_local);
>>      struct sigaction handler;
>>      memset(&handler, 0, sizeof(struct sigaction));
>>
>> @@ -81,17 +79,6 @@ void init_native_crash_handler(JNIEnv *env, jobject
>> j_libVLC_local)
>>          const int s = monitored_signals[i];
>>          sigaction(s, &handler, &old_actions[s]);
>>      }
>> -}
>> -
>> -
>> -void destroy_native_crash_handler(JNIEnv *env)
>> -{
>> -    // Uninstall the signal handlers and restore their old actions.
>> -    for (unsigned i = 0; i < sizeof(monitored_signals) / sizeof(int);
>> ++i)
>> -    {
>> -        const int s = monitored_signals[i];
>> -        sigaction(s, &old_actions[s], NULL);
>> -    }
>>
>> -    (*env)->DeleteGlobalRef(env, j_libVLC);
>> -}
>> +    j_NativeCrashHandler = (*env)->NewGlobalRef(env, thiz);;
>> +}
>> \ No newline at end of file
>> diff --git a/libvlc/jni/native_crash_handler.h
>> b/libvlc/jni/native_crash_handler.h
>> index a57e61e..d220af5 100644
>> --- a/libvlc/jni/native_crash_handler.h
>> +++ b/libvlc/jni/native_crash_handler.h
>> @@ -23,7 +23,4 @@
>>
>>  #include <jni.h>
>>
>> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);
>> -void destroy_native_crash_handler(JNIEnv *env);
>> -
>> -#endif // LIBVLCJNI_NATIVE_CRASH_HANDLER_H
>> +#endif // LIBVLCJNI_NATIVE_CRASH_HANDLER_H
>> \ No newline at end of file
>> diff --git a/libvlc/jni/utils.h b/libvlc/jni/utils.h
>> index f5b9f8d..e136bcb 100644
>> --- a/libvlc/jni/utils.h
>> +++ b/libvlc/jni/utils.h
>> @@ -43,8 +43,6 @@ void arrayListGetIDs(JNIEnv *env, jclass* p_class,
>> jmethodID* p_add, jmethodID*
>>
>>  void arrayListStringAdd(JNIEnv *env, jclass class, jmethodID methodID,
>> jobject arrayList, const char* str);
>>
>> -jobject getEventHandlerReference(JNIEnv *env, jobject thiz, jobject
>> eventHandler);
>> -
>>  void debug_log(void *data, int level, const libvlc_log_t *ctx, const
>> char *fmt, va_list ap);
>>
>>  #endif // LIBVLCJNI_UTILS_H
>> diff --git a/libvlc/jni/vout.c b/libvlc/jni/vout.c
>> index 6362f0c..aeec651 100644
>> --- a/libvlc/jni/vout.c
>> +++ b/libvlc/jni/vout.c
>> @@ -22,105 +22,105 @@
>>  #include <vlc_common.h>
>>
>>  #include <jni.h>
>> +#include "vout.h"
>> +
>> +#define LOG_TAG "VLC/JNI/vout"
>> +#include "log.h"
>>
>>  #define THREAD_NAME "jni_vout"
>>  extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
>>  extern void jni_detach_thread();
>>  extern int jni_get_env(JNIEnv **env);
>>
>> -pthread_mutex_t vout_android_lock;
>> -pthread_cond_t vout_android_surf_attached;
>> -static void *vout_android_gui = NULL;
>> -static jobject vout_android_java_surf = NULL;
>> -static jobject vout_android_subtitles_surf = NULL;
>> -static bool vout_video_player_activity_created = false;
>> -
>> -void *jni_LockAndGetSubtitlesSurface() {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    while (vout_android_subtitles_surf == NULL)
>> -        pthread_cond_wait(&vout_android_surf_attached,
>> &vout_android_lock);
>> -    return vout_android_subtitles_surf;
>> +void *jni_LockAndGetSubtitlesSurface(android_surf_value_t
>> *android_surface) {
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    while (android_surface->vout_android_subtitles_surf == NULL)
>> +        pthread_cond_wait(&android_surface->vout_android_surf_attached,
>> &android_surface->vout_android_lock);
>> +    return android_surface->vout_android_subtitles_surf;
>>  }
>>
>> -jobject jni_LockAndGetAndroidJavaSurface() {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    while (vout_android_java_surf == NULL)
>> -        pthread_cond_wait(&vout_android_surf_attached,
>> &vout_android_lock);
>> -    return vout_android_java_surf;
>> +jobject jni_LockAndGetAndroidJavaSurface(android_surf_value_t
>> *android_surface) {
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    while (android_surface->vout_android_java_surf == NULL)
>> +        pthread_cond_wait(&android_surface->vout_android_surf_attached,
>> &android_surface->vout_android_lock);
>> +    return android_surface->vout_android_java_surf;
>>  }
>>
>> -void jni_UnlockAndroidSurface() {
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +void jni_UnlockAndroidSurface(android_surf_value_t *android_surface) {
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>> -bool jni_LockAndGetIsSurfaceAttached() {
>> -    pthread_mutex_unlock(&vout_android_lock);
>> -    return vout_android_java_surf != NULL;
>> +bool jni_LockAndGetIsSurfaceAttached(android_surf_value_t
>> *android_surface) {
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>> +    return android_surface->vout_android_java_surf != NULL;
>>  }
>>
>> -void jni_EventHardwareAccelerationError()
>> +void jni_EventHardwareAccelerationError(android_surf_value_t
>> *android_surface)
>>  {
>>      JNIEnv *env;
>>      bool isAttached = false;
>>
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_gui == NULL) {
>> -        pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_gui == NULL) {
>> +        pthread_mutex_unlock(&android_surface->vout_android_lock);
>>          return;
>>      }
>>
>>      if (jni_get_env(&env) < 0) {
>>          if (jni_attach_thread(&env, THREAD_NAME) < 0) {
>> -            pthread_mutex_unlock(&vout_android_lock);
>> +            pthread_mutex_unlock(&android_surface->vout_android_lock);
>>              return;
>>          }
>>          isAttached = true;
>>      }
>>
>> -    jclass cls = (*env)->GetObjectClass(env, vout_android_gui);
>> +    jclass cls = (*env)->GetObjectClass(env,
>> android_surface->vout_android_gui);
>>      jmethodID methodId = (*env)->GetMethodID(env, cls,
>> "eventHardwareAccelerationError", "()V");
>> -    (*env)->CallVoidMethod(env, vout_android_gui, methodId);
>> +    (*env)->CallVoidMethod(env, android_surface->vout_android_gui,
>> methodId);
>>
>>      (*env)->DeleteLocalRef(env, cls);
>>      if (isAttached)
>>          jni_detach_thread();
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>> -static void jni_SetSurfaceLayoutEnv(JNIEnv *p_env, int width, int
>> height, int visible_width, int visible_height, int sar_num, int sar_den)
>> +void jni_SetSurfaceLayoutEnv(JNIEnv *p_env, android_surf_value_t
>> *android_surface, int width, int height, int visible_width, int
>> visible_height, int sar_num, int sar_den)
>>  {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_gui == NULL) {
>> -        pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_gui == NULL) {
>> +        pthread_mutex_unlock(&android_surface->vout_android_lock);
>>          return;
>>      }
>>
>> -    jclass cls = (*p_env)->GetObjectClass (p_env, vout_android_gui);
>> +    jclass cls = (*p_env)->GetObjectClass (p_env,
>> android_surface->vout_android_gui);
>>      jmethodID methodId = (*p_env)->GetMethodID (p_env, cls,
>> "setSurfaceLayout", "(IIIIII)V");
>>
>> -    (*p_env)->CallVoidMethod (p_env, vout_android_gui, methodId, width,
>> height, visible_width, visible_height, sar_num, sar_den);
>> +    (*p_env)->CallVoidMethod (p_env, android_surface->vout_android_gui,
>> methodId, width, height, visible_width, visible_height, sar_num, sar_den);
>>
>>      (*p_env)->DeleteLocalRef(p_env, cls);
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>> -void jni_SetSurfaceLayout(int width, int height, int visible_width, int
>> visible_height, int sar_num, int sar_den)
>> +void jni_SetSurfaceLayout(android_surf_value_t *android_surface, int
>> width, int height, int visible_width, int visible_height, int sar_num, int
>> sar_den)
>>  {
>>      JNIEnv *p_env;
>>      bool isAttached = false;
>>
>> +    if (android_surface == NULL)
>> +        return;
>> +
>>      if (jni_get_env(&p_env) < 0) {
>>          if (jni_attach_thread(&p_env, THREAD_NAME) < 0)
>>              return;
>>          isAttached = true;
>>      }
>> -    jni_SetSurfaceLayoutEnv(p_env, width, height, visible_width,
>> visible_height, sar_num, sar_den);
>> +    jni_SetSurfaceLayoutEnv(p_env, android_surface, width, height,
>> visible_width, visible_height, sar_num, sar_den);
>>
>>      if (isAttached)
>>          jni_detach_thread();
>>  }
>>
>> -void *jni_AndroidJavaSurfaceToNativeSurface(jobject *surf)
>> +void *jni_AndroidJavaSurfaceToNativeSurface(jobject surf)
>>  {
>>      JNIEnv *p_env;
>>      jclass clz;
>> @@ -159,28 +159,29 @@ void *jni_AndroidJavaSurfaceToNativeSurface(jobject
>> *surf)
>>      return native_surface;
>>  }
>>
>> -int jni_ConfigureSurface(jobject jsurf, int width, int height, int hal,
>> bool *configured)
>> +int jni_ConfigureSurface(android_surf_value_t *android_surface, int
>> width, int height, int hal, bool *configured)
>>  {
>>      JNIEnv *p_env;
>>      bool isAttached = false;
>>      int ret;
>>
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_gui == NULL) {
>> -        pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_gui == NULL) {
>> +        pthread_mutex_unlock(&android_surface->vout_android_lock);
>>          return -1;
>>      }
>>
>>      if (jni_get_env(&p_env) < 0) {
>>          if (jni_attach_thread(&p_env, THREAD_NAME) < 0) {
>> -            pthread_mutex_unlock(&vout_android_lock);
>> +            pthread_mutex_unlock(&android_surface->vout_android_lock);
>>              return -1;
>>          }
>>          isAttached = true;
>>      }
>> -    jclass clz = (*p_env)->GetObjectClass (p_env, vout_android_gui);
>> +    jclass clz = (*p_env)->GetObjectClass (p_env,
>> android_surface->vout_android_gui);
>>      jmethodID methodId = (*p_env)->GetMethodID (p_env, clz,
>> "configureSurface", "(Landroid/view/Surface;III)I");
>> -    ret = (*p_env)->CallIntMethod (p_env, vout_android_gui, methodId,
>> jsurf, width, height, hal);
>> +    ret = (*p_env)->CallIntMethod (p_env,
>> android_surface->vout_android_gui, methodId,
>> +
>>  android_surface->vout_android_java_surf, width, height, hal);
>>      if (ret >= 0 && configured)
>>          *configured = ret == 1;
>>
>> @@ -188,62 +189,81 @@ int jni_ConfigureSurface(jobject jsurf, int width,
>> int height, int hal, bool *co
>>
>>      if (isAttached)
>>          jni_detach_thread();
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>      return ret == -1 ? -1 : 0;
>>  }
>>
>> -bool jni_IsVideoPlayerActivityCreated() {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    bool result = vout_video_player_activity_created;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +bool jni_IsVideoPlayerActivityCreated(android_surf_value_t
>> *android_surface) {
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    bool result = android_surface->vout_video_player_activity_created;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>      return result;
>>  }
>>
>>  void
>> Java_org_videolan_libvlc_LibVLC_eventVideoPlayerActivityCreated(JNIEnv
>> *env, jobject thiz, jboolean created) {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    vout_video_player_activity_created = created;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t * android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    android_surface->vout_video_player_activity_created = created;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_attachSurface(JNIEnv *env, jobject
>> thiz, jobject surf, jobject gui) {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -
>> -    if (vout_android_gui != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_gui);
>> -    if (vout_android_java_surf != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_java_surf);
>> -    vout_android_gui = (*env)->NewGlobalRef(env, gui);
>> -    vout_android_java_surf = (*env)->NewGlobalRef(env, surf);
>> -    pthread_cond_signal(&vout_android_surf_attached);
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t * android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_gui != NULL)
>> +        (*env)->DeleteGlobalRef(env, android_surface->vout_android_gui);
>> +    if (android_surface->vout_android_java_surf != NULL)
>> +        (*env)->DeleteGlobalRef(env,
>> android_surface->vout_android_java_surf);
>> +    android_surface->vout_android_gui = (*env)->NewGlobalRef(env, gui);
>> +    android_surface->vout_android_java_surf = (*env)->NewGlobalRef(env,
>> surf);
>> +    pthread_cond_signal(&android_surface->vout_android_surf_attached);
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_detachSurface(JNIEnv *env, jobject
>> thiz) {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_gui != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_gui);
>> -    if (vout_android_java_surf != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_java_surf);
>> -    vout_android_gui = NULL;
>> -    vout_android_java_surf = NULL;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t * android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_gui != NULL)
>> +        (*env)->DeleteGlobalRef(env, android_surface->vout_android_gui);
>> +    if (android_surface->vout_android_java_surf != NULL)
>> +        (*env)->DeleteGlobalRef(env,
>> android_surface->vout_android_java_surf);
>> +    android_surface->vout_android_gui = NULL;
>> +    android_surface->vout_android_java_surf = NULL;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_attachSubtitlesSurface(JNIEnv *env,
>> jobject thiz, jobject surf) {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_subtitles_surf != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);
>> -    vout_android_subtitles_surf = (*env)->NewGlobalRef(env, surf);
>> -    pthread_cond_signal(&vout_android_surf_attached);
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t * android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_subtitles_surf != NULL)
>> +        (*env)->DeleteGlobalRef(env,
>> android_surface->vout_android_subtitles_surf);
>> +    android_surface->vout_android_subtitles_surf =
>> (*env)->NewGlobalRef(env, surf);
>> +    pthread_cond_signal(&android_surface->vout_android_surf_attached);
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>>  void Java_org_videolan_libvlc_LibVLC_detachSubtitlesSurface(JNIEnv *env,
>> jobject thiz) {
>> -    pthread_mutex_lock(&vout_android_lock);
>> -    if (vout_android_subtitles_surf != NULL)
>> -        (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);
>> -    vout_android_subtitles_surf = NULL;
>> -    pthread_mutex_unlock(&vout_android_lock);
>> +    android_surf_value_t * android_surface =
>> getAndroidSurfaceInstance(env, thiz);
>> +    if (android_surface == NULL)
>> +        return;
>> +
>> +    pthread_mutex_lock(&android_surface->vout_android_lock);
>> +    if (android_surface->vout_android_subtitles_surf != NULL)
>> +        (*env)->DeleteGlobalRef(env,
>> android_surface->vout_android_subtitles_surf);
>> +    android_surface->vout_android_subtitles_surf = NULL;
>> +    pthread_mutex_unlock(&android_surface->vout_android_lock);
>>  }
>>
>>  static int mouse_x = -1;
>> diff --git a/libvlc/jni/vout.h b/libvlc/jni/vout.h
>> index c3d4fd7..ac13413 100644
>> --- a/libvlc/jni/vout.h
>> +++ b/libvlc/jni/vout.h
>> @@ -21,8 +21,26 @@
>>  #ifndef LIBVLCJNI_VOUT_H
>>  #define LIBVLCJNI_VOUT_H
>>
>> -/* vout lock initialized in vout.c */
>> -pthread_mutex_t vout_android_lock;
>> -pthread_cond_t vout_android_surf_attached;
>> +#include <pthread.h>
>> +
>> +typedef struct android_surf_value_t {
>> +    pthread_mutex_t   vout_android_lock;
>> +    pthread_cond_t    vout_android_surf_attached;
>> +    void             *vout_android_gui;
>> +    jobject           vout_android_java_surf;
>> +    jobject           vout_android_subtitles_surf;
>> +    bool              vout_video_player_activity_created;
>> +    int               i_window_width;
>> +    int               i_window_height;
>> +} android_surf_value_t;
>> +
>> +typedef struct libvlc_instance_sys_t {
>> +    void                    *p_this;
>> +    libvlc_instance_t       *p_libvlc;
>> +    libvlc_media_player_t   *p_mp;
>> +    android_surf_value_t    *p_surf;
>> +} libvlc_instance_sys_t;
>> +
>> +android_surf_value_t *getAndroidSurfaceInstance(JNIEnv *env, jobject
>> thiz);
>>
>>  #endif // LIBVLCJNI_VOUT_H
>> diff --git a/libvlc/src/org/videolan/libvlc/EventHandler.java
>> b/libvlc/src/org/videolan/libvlc/EventHandler.java
>> index 4ec0861..2d13d30 100644
>> --- a/libvlc/src/org/videolan/libvlc/EventHandler.java
>> +++ b/libvlc/src/org/videolan/libvlc/EventHandler.java
>> @@ -97,19 +97,11 @@ public class EventHandler {
>>      public static final int HardwareAccelerationError         = 0x3000;
>>
>>      private ArrayList<Handler> mEventHandler;
>> -    private static EventHandler mInstance;
>>
>>      EventHandler() {
>>          mEventHandler = new ArrayList<Handler>();
>>      }
>>
>> -    public static EventHandler getInstance() {
>> -        if (mInstance == null) {
>> -            mInstance = new EventHandler();
>> -        }
>> -        return mInstance;
>> -    }
>> -
>>      public void addHandler(Handler handler) {
>>          if (!mEventHandler.contains(handler))
>>              mEventHandler.add(handler);
>> diff --git a/libvlc/src/org/videolan/libvlc/LibVLC.java
>> b/libvlc/src/org/videolan/libvlc/LibVLC.java
>> index 822999a..aaf640f 100644
>> --- a/libvlc/src/org/videolan/libvlc/LibVLC.java
>> +++ b/libvlc/src/org/videolan/libvlc/LibVLC.java
>> @@ -1,7 +1,7 @@
>>
>>  /*****************************************************************************
>>   * LibVLC.java
>>
>> *****************************************************************************
>> - * Copyright © 2010-2013 VLC authors and VideoLAN
>> + * Copyright © 2010-2014 VLC authors and VideoLAN
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>> it
>>   * under the terms of the GNU Lesser General Public License as published
>> by
>> @@ -25,7 +25,6 @@ import java.util.ArrayList;
>>  import java.util.Map;
>>
>>  import android.content.Context;
>> -import android.os.Build;
>>  import android.util.Log;
>>  import android.view.Surface;
>>
>> @@ -61,11 +60,12 @@ public class LibVLC {
>>
>>      private static LibVLC sInstance;
>>
>> +    private final EventHandler eventHandler = new EventHandler();
>> +
>>      /** libVLC instance C pointer */
>>      private long mLibVlcInstance = 0; // Read-only, reserved for JNI
>>      /** libvlc_media_player pointer and index */
>>      private int mInternalMediaPlayerIndex = 0; // Read-only, reserved
>> for JNI
>> -    private long mInternalMediaPlayerInstance = 0; // Read-only,
>> reserved for JNI
>>
>>      private MediaList mMediaList; // Pointer to media list being followed
>>      private MediaList mPrimaryList; // Primary/default media list; see
>> getPrimaryMediaList()
>> @@ -99,9 +99,6 @@ public class LibVLC {
>>      /** Path of application-specific cache */
>>      private String mCachePath = "";
>>
>> -    /** Native crash handler */
>> -    private OnNativeCrashListener mOnNativeCrashListener;
>> -
>>      /** Check in libVLC already initialized otherwise crash */
>>      private boolean mIsInitialized = false;
>>      public native void attachSurface(Surface surface, IVideoPlayer
>> player);
>> @@ -113,54 +110,6 @@ public class LibVLC {
>>
>>      public native void eventVideoPlayerActivityCreated(boolean created);
>>
>> -    /* Load library before object instantiation */
>> -    static {
>> -        if (Build.VERSION.SDK_INT >=
>> Build.VERSION_CODES.GINGERBREAD_MR1) {
>> -            try {
>> -                if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR1)
>> -                    System.loadLibrary("anw.10");
>> -                else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR2)
>> -                    System.loadLibrary("anw.13");
>> -                else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR1)
>> -                    System.loadLibrary("anw.14");
>> -                else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.KITKAT_WATCH)
>> -                    System.loadLibrary("anw.18");
>> -                else
>> -                    System.loadLibrary("anw.21");
>> -            } catch (Throwable t) {
>> -                Log.w(TAG, "Unable to load the anw library: " + t);
>> -            }
>> -        }
>> -
>> -        try {
>> -            if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.GINGERBREAD_MR1)
>> -                System.loadLibrary("iomx.10");
>> -            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR2)
>> -                System.loadLibrary("iomx.13");
>> -            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR1)
>> -                System.loadLibrary("iomx.14");
>> -            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR2)
>> -                System.loadLibrary("iomx.18");
>> -            else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
>> -                System.loadLibrary("iomx.19");
>> -        } catch (Throwable t) {
>> -            // No need to warn if it isn't found, when we intentionally
>> don't build these except for debug
>> -            if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
>> -                Log.w(TAG, "Unable to load the iomx library: " + t);
>> -        }
>> -        try {
>> -            System.loadLibrary("vlcjni");
>> -        } catch (UnsatisfiedLinkError ule) {
>> -            Log.e(TAG, "Can't load vlcjni library: " + ule);
>> -            /// FIXME Alert user
>> -            System.exit(1);
>> -        } catch (SecurityException se) {
>> -            Log.e(TAG, "Encountered a security issue when loading vlcjni
>> library: " + se);
>> -            /// FIXME Alert user
>> -            System.exit(1);
>> -        }
>> -    }
>> -
>>      /**
>>       * Singleton constructor of libVLC Without surface and vout to
>> create the
>>       * thumbnail and get information e.g. on the MediaLibraryActivity
>> @@ -192,10 +141,9 @@ public class LibVLC {
>>      }
>>
>>      /**
>> -     * Constructor
>> -     * It is private because this class is a singleton.
>> +     * Constructor.
>>       */
>> -    private LibVLC() {
>> +    public LibVLC() {
>>          mAout = new AudioOutput();
>>      }
>>
>> @@ -261,7 +209,7 @@ public class LibVLC {
>>       */
>>      public native void setSurface(Surface f);
>>
>> -    public static synchronized void restart(Context context) {
>> +    public static synchronized void restartInstance(Context context) {
>>          if (sInstance != null) {
>>              try {
>>                  sInstance.destroy();
>> @@ -272,6 +220,15 @@ public class LibVLC {
>>          }
>>      }
>>
>> +    public void restart(Context context) {
>> +        try {
>> +            this.destroy();
>> +            this.init(context);
>> +        } catch (LibVlcException lve) {
>> +            Log.e(TAG, "Unable to reinit libvlc: " + lve);
>> +        }
>> +    }
>> +
>>      /**
>>       * those get/is* are called from native code to get settings values.
>>       */
>> @@ -493,11 +450,11 @@ public class LibVLC {
>>          applyEqualizer();
>>      }
>>
>> -    private void applyEqualizer()
>> +    protected void applyEqualizer()
>>      {
>> -        setNativeEqualizer(mInternalMediaPlayerInstance, this.equalizer);
>> +        setNativeEqualizer(this.equalizer);
>>      }
>> -    private native int setNativeEqualizer(long mediaPlayer, float[]
>> bands);
>> +    private native int setNativeEqualizer(float[] bands);
>>
>>      public boolean frameSkipEnabled() {
>>          return frameSkip;
>> @@ -533,7 +490,7 @@ public class LibVLC {
>>      public void init(Context context) throws LibVlcException {
>>          Log.v(TAG, "Initializing LibVLC");
>>          mDebugLogBuffer = new StringBuffer();
>> -        if (!mIsInitialized) {
>> +        if (LibVlcUtil.isLibraryLoaded() && !mIsInitialized) {
>>              if(!LibVlcUtil.hasCompatibleCPU(context)) {
>>                  Log.e(TAG, LibVlcUtil.getErrorMsg());
>>                  throw new LibVlcException();
>> @@ -543,7 +500,6 @@ public class LibVLC {
>>              mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath()
>> : null;
>>              nativeInit();
>>              mMediaList = mPrimaryList = new MediaList(this);
>> -            setEventHandler(EventHandler.getInstance());
>>              mIsInitialized = true;
>>          }
>>      }
>> @@ -555,7 +511,6 @@ public class LibVLC {
>>      public void destroy() {
>>          Log.v(TAG, "Destroying LibVLC instance");
>>          nativeDestroy();
>> -        detachEventHandler();
>>          mIsInitialized = false;
>>      }
>>
>> @@ -835,27 +790,14 @@ public class LibVLC {
>>          return mMediaList.expandMedia(mInternalMediaPlayerIndex);
>>      }
>>
>> -    private native void setEventHandler(EventHandler eventHandler);
>> -
>> -    private native void detachEventHandler();
>> -
>>      public native float[] getBands();
>>
>>      public native String[] getPresets();
>>
>>      public native float[] getPreset(int index);
>>
>> -    public static interface OnNativeCrashListener {
>> -        public void onNativeCrash();
>> -    }
>> -
>> -    public void setOnNativeCrashListener(OnNativeCrashListener l) {
>> -        mOnNativeCrashListener = l;
>> -    }
>> -
>> -    private void onNativeCrash() {
>> -        if (mOnNativeCrashListener != null)
>> -            mOnNativeCrashListener.onNativeCrash();
>> +    public EventHandler getEventHandler() {
>> +        return eventHandler;
>>      }
>>
>>      public String getCachePath() {
>> diff --git a/libvlc/src/org/videolan/libvlc/LibVlcUtil.java
>> b/libvlc/src/org/videolan/libvlc/LibVlcUtil.java
>> index 0ddf780..6c7dc97 100644
>> --- a/libvlc/src/org/videolan/libvlc/LibVlcUtil.java
>> +++ b/libvlc/src/org/videolan/libvlc/LibVlcUtil.java
>> @@ -1,7 +1,7 @@
>>
>>  /*****************************************************************************
>>   * LibVlcUtil.java
>>
>> *****************************************************************************
>> - * Copyright © 2011-2013 VLC authors and VideoLAN
>> + * Copyright © 2011-2014 VLC authors and VideoLAN
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>> it
>>   * under the terms of the GNU Lesser General Public License as published
>> by
>> @@ -39,6 +39,60 @@ import android.util.Log;
>>  public class LibVlcUtil {
>>      public final static String TAG = "VLC/LibVLC/Util";
>>
>> +    public static boolean libraryLoaded = false;
>> +
>> +    /* Load library before object instantiation */
>> +    static {
>> +        if (Build.VERSION.SDK_INT >=
>> Build.VERSION_CODES.GINGERBREAD_MR1) {
>> +            try {
>> +                if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR1)
>> +                    System.loadLibrary("anw.10");
>> +                else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR2)
>> +                    System.loadLibrary("anw.13");
>> +                else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR1)
>> +                    System.loadLibrary("anw.14");
>> +                else
>> +                    System.loadLibrary("anw.18");
>> +            } catch (Throwable t) {
>> +                Log.w(TAG, "Unable to load the anw library: " + t);
>> +            }
>> +        }
>> +
>> +        try {
>> +            if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.GINGERBREAD_MR1)
>> +                System.loadLibrary("iomx.10");
>> +            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.HONEYCOMB_MR2)
>> +                System.loadLibrary("iomx.13");
>> +            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR1)
>> +                System.loadLibrary("iomx.14");
>> +            else if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.JELLY_BEAN_MR2)
>> +                System.loadLibrary("iomx.18");
>> +            else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT)
>> +                System.loadLibrary("iomx.19");
>> +        } catch (Throwable t) {
>> +            // No need to warn if it isn't found, when we intentionally
>> don't build these except for debug
>> +            if (Build.VERSION.SDK_INT <=
>> Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
>> +                Log.w(TAG, "Unable to load the iomx library: " + t);
>> +        }
>> +        try {
>> +            System.loadLibrary("vlcjni");
>> +        } catch (UnsatisfiedLinkError ule) {
>> +            Log.e(TAG, "Can't load vlcjni library: " + ule);
>> +            /// FIXME Alert user
>> +            System.exit(1);
>> +        } catch (SecurityException se) {
>> +            Log.e(TAG, "Encountered a security issue when loading vlcjni
>> library: " + se);
>> +            /// FIXME Alert user
>> +            System.exit(1);
>> +        }
>> +
>> +        libraryLoaded = true;
>> +    }
>> +
>> +    public static boolean isLibraryLoaded() {
>> +        return libraryLoaded;
>> +    }
>> +
>>      public static boolean isFroyoOrLater()
>>      {
>>          return android.os.Build.VERSION.SDK_INT >=
>> android.os.Build.VERSION_CODES.FROYO;
>> diff --git a/libvlc/src/org/videolan/libvlc/NativeCrashHandler.java
>> b/libvlc/src/org/videolan/libvlc/NativeCrashHandler.java
>> new file mode 100644
>> index 0000000..ec10698
>> --- /dev/null
>> +++ b/libvlc/src/org/videolan/libvlc/NativeCrashHandler.java
>> @@ -0,0 +1,64 @@
>>
>> +/*****************************************************************************
>> + * NativeCrashHandler.java
>> +
>> *****************************************************************************
>> + * Copyright © 2014 VLC authors and VideoLAN
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License as published by
>> + * the Free Software Foundation; either version 2 of the License, or
>> + * (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
>> 02110-1301, USA.
>> +
>> *****************************************************************************/
>> +
>> +package org.videolan.libvlc;
>> +
>> +import android.os.Build;
>> +import android.util.Log;
>> +
>> +public class NativeCrashHandler {
>> +    public final static String TAG = "VLC/NativeCrashHandler";
>> +
>> +    /** Native crash handler */
>> +    private OnNativeCrashListener mOnNativeCrashListener;
>> +
>> +    private static NativeCrashHandler sInstance;
>> +
>> +    private NativeCrashHandler() {
>> +    }
>> +
>> +    public static interface OnNativeCrashListener {
>> +        public void onNativeCrash();
>> +    }
>> +
>> +    public static NativeCrashHandler getInstance() {
>> +        synchronized (NativeCrashHandler.class) {
>> +            if (sInstance == null) {
>> +                /* First call */
>> +                sInstance = new NativeCrashHandler();
>> +                if (LibVlcUtil.isLibraryLoaded())
>> +                    sInstance.nativeInit();
>> +            }
>> +        }
>> +
>> +        return sInstance;
>> +    }
>> +
>> +    public void setOnNativeCrashListener(OnNativeCrashListener l) {
>> +        mOnNativeCrashListener = l;
>> +    }
>> +
>> +    public void onNativeCrash() {
>> +        if (mOnNativeCrashListener != null)
>> +            mOnNativeCrashListener.onNativeCrash();
>> +    }
>> +
>> +    private native void nativeInit();
>> +}
>> \ No newline at end of file
>> diff --git a/vlc-android/src/org/videolan/vlc/VLCApplication.java
>> b/vlc-android/src/org/videolan/vlc/VLCApplication.java
>> index e915a46..ba34827 100644
>> --- a/vlc-android/src/org/videolan/vlc/VLCApplication.java
>> +++ b/vlc-android/src/org/videolan/vlc/VLCApplication.java
>> @@ -1,7 +1,7 @@
>>
>>  /*****************************************************************************
>>   * VLCApplication.java
>>
>> *****************************************************************************
>> - * Copyright © 2010-2013 VLC authors and VideoLAN
>> + * Copyright © 2010-2014 VLC authors and VideoLAN
>>   *
>>   * This program is free software; you can redistribute it and/or modify
>>   * it under the terms of the GNU General Public License as published by
>> @@ -21,11 +21,14 @@ package org.videolan.vlc;
>>
>>  import java.util.Locale;
>>
>> +import org.videolan.libvlc.NativeCrashHandler;
>>  import org.videolan.vlc.gui.audio.AudioUtil;
>> +import org.videolan.vlc.gui.NativeCrashActivity;
>>  import org.videolan.vlc.util.BitmapCache;
>>
>>  import android.app.Application;
>>  import android.content.Context;
>> +import android.content.Intent;
>>  import android.content.SharedPreferences;
>>  import android.content.res.Configuration;
>>  import android.content.res.Resources;
>> @@ -81,6 +84,16 @@ public class VLCApplication extends Application {
>>          MediaDatabase.getInstance();
>>          // Prepare cache folder constants
>>          AudioUtil.prepareCacheFolder(this);
>> +
>> +        NativeCrashHandler.getInstance().setOnNativeCrashListener(new
>> NativeCrashHandler.OnNativeCrashListener() {
>> +            @Override
>> +            public void onNativeCrash() {
>> +                Intent i = new Intent(instance,
>> NativeCrashActivity.class);
>> +                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
>> +                i.putExtra("PID", android.os.Process.myPid());
>> +                instance.startActivity(i);
>> +            }
>> +        });
>>      }
>>
>>      /**
>> diff --git a/vlc-android/src/org/videolan/vlc/audio/AudioService.java
>> b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
>> index c33abc8..d039fba 100644
>> --- a/vlc-android/src/org/videolan/vlc/audio/AudioService.java
>> +++ b/vlc-android/src/org/videolan/vlc/audio/AudioService.java
>> @@ -116,7 +116,6 @@ public class AudioService extends Service {
>>
>>      private LibVLC mLibVLC;
>>      private HashMap<IAudioServiceCallback, Integer> mCallback;
>> -    private EventHandler mEventHandler;
>>      private OnAudioFocusChangeListener audioFocusListener;
>>      private boolean mDetectHeadset = true;
>>      private PowerManager.WakeLock mWakeLock;
>> @@ -165,7 +164,6 @@ public class AudioService extends Service {
>>          mPrevIndex = -1;
>>          mNextIndex = -1;
>>          mPrevious = new Stack<Integer>();
>> -        mEventHandler = EventHandler.getInstance();
>>          mRemoteControlClientReceiverComponent = new
>> ComponentName(getPackageName(),
>>                  RemoteControlClientReceiver.class.getName());
>>
>> @@ -346,7 +344,7 @@ public class AudioService extends Service {
>>              }
>>
>>              /*
>> -             * Incoming Call : Pause if VLC is playing audio or video.
>> +             * Incoming Call : Pause if VLC is playing audio or video.
>>               */
>>              if
>> (action.equalsIgnoreCase(VLCApplication.INCOMING_CALL_INTENT)) {
>>                  mWasPlayingAudio = mLibVLC.isPlaying() &&
>> mLibVLC.getVideoTracksCount() < 1;
>> @@ -625,7 +623,7 @@ public class AudioService extends Service {
>>          String MRL = mLibVLC.getMediaList().getMRL(mCurrentIndex);
>>          int index = mCurrentIndex;
>>          mCurrentIndex = -1;
>> -        mEventHandler.removeHandler(mVlcEventHandler);
>> +        mLibVLC.getEventHandler().removeHandler(mVlcEventHandler);
>>          // Preserve playback when switching to video
>>          hideNotification(false);
>>
>> @@ -833,7 +831,7 @@ public class AudioService extends Service {
>>
>>      private void stop() {
>>          mLibVLC.stop();
>> -        mEventHandler.removeHandler(mVlcEventHandler);
>> +        mLibVLC.getEventHandler().removeHandler(mVlcEventHandler);
>>
>>  mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);
>>
>>  setRemoteControlClientPlaybackState(EventHandler.MediaPlayerStopped);
>>          mCurrentIndex = -1;
>> @@ -1158,7 +1156,7 @@ public class AudioService extends Service {
>>                  throws RemoteException {
>>
>>              Log.v(TAG, "Loading position " +
>> ((Integer)position).toString() + " in " + mediaPathList.toString());
>> -            mEventHandler.addHandler(mVlcEventHandler);
>> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);
>>
>>
>>  mLibVLC.getMediaList().getEventHandler().removeHandler(mListEventHandler);
>>              mLibVLC.setMediaList();
>> @@ -1226,7 +1224,7 @@ public class AudioService extends Service {
>>                  mCurrentIndex = 0;
>>              }
>>
>> -            mEventHandler.addHandler(mVlcEventHandler);
>> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);
>>              mLibVLC.playIndex(mCurrentIndex);
>>              mHandler.sendEmptyMessage(SHOW_PROGRESS);
>>              setUpRemoteControlClient();
>> @@ -1250,7 +1248,7 @@ public class AudioService extends Service {
>>
>>              if(URI == null || !mLibVLC.isPlaying())
>>                  return;
>> -            mEventHandler.addHandler(mVlcEventHandler);
>> +            mLibVLC.getEventHandler().addHandler(mVlcEventHandler);
>>              mCurrentIndex = index;
>>
>>              // Notify everyone
>> diff --git
>> a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> index fc7d695..6a2cfed 100644
>> --- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> +++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> @@ -299,7 +299,7 @@ public class PreferencesActivity extends
>> PreferenceActivity implements OnSharedP
>>                  || key.equalsIgnoreCase("network_caching")
>>                  || key.equalsIgnoreCase("dev_hardware_decoder")) {
>>              VLCInstance.updateLibVlcSettings(sharedPreferences);
>> -            LibVLC.restart(this);
>> +            LibVLC.restartInstance(this);
>>          }
>>      }
>>
>> diff --git
>> a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
>> b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
>> index 4cf4793..195de50 100644
>> --- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
>> +++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
>> @@ -439,8 +439,7 @@ public class VideoPlayerActivity extends
>> ActionBarActivity implements IVideoPlay
>>          // SurfaceView is now available for MediaCodec direct rendering.
>>          mLibVLC.eventVideoPlayerActivityCreated(true);
>>
>> -        EventHandler em = EventHandler.getInstance();
>> -        em.addHandler(eventHandler);
>> +        mLibVLC.getEventHandler().addHandler(eventHandler);
>>
>>          this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
>>
>> @@ -590,8 +589,7 @@ public class VideoPlayerActivity extends
>> ActionBarActivity implements IVideoPlay
>>          super.onDestroy();
>>          unregisterReceiver(mReceiver);
>>
>> -        EventHandler em = EventHandler.getInstance();
>> -        em.removeHandler(eventHandler);
>> +        mLibVLC.getEventHandler().removeHandler(eventHandler);
>>
>>          // MediaCodec opaque direct rendering should not be used anymore
>> since there is no surface to attach.
>>          mLibVLC.eventVideoPlayerActivityCreated(false);
>> @@ -1228,8 +1226,7 @@ public class VideoPlayerActivity extends
>> ActionBarActivity implements IVideoPlay
>>      }
>>
>>      public void eventHardwareAccelerationError() {
>> -        EventHandler em = EventHandler.getInstance();
>> -        em.callback(EventHandler.HardwareAccelerationError, new
>> Bundle());
>> +
>> mLibVLC.getEventHandler().callback(EventHandler.HardwareAccelerationError,
>> new Bundle());
>>      }
>>
>>      private void handleHardwareAccelerationError() {
>> diff --git a/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
>> b/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
>> index d0212c6..9b65285 100644
>> --- a/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
>> +++ b/vlc-android/src/org/videolan/vlc/util/VLCInstance.java
>> @@ -24,7 +24,6 @@ import org.videolan.libvlc.LibVLC;
>>  import org.videolan.libvlc.LibVlcException;
>>  import org.videolan.vlc.VLCApplication;
>>  import org.videolan.vlc.VLCCrashHandler;
>> -import org.videolan.vlc.gui.NativeCrashActivity;
>>
>>  import android.content.Context;
>>  import android.content.Intent;
>> @@ -45,15 +44,6 @@ public class VLCInstance {
>>              SharedPreferences pref =
>> PreferenceManager.getDefaultSharedPreferences(context);
>>              VLCInstance.updateLibVlcSettings(pref);
>>              instance.init(context);
>> -            instance.setOnNativeCrashListener(new
>> LibVLC.OnNativeCrashListener() {
>> -                @Override
>> -                public void onNativeCrash() {
>> -                    Intent i = new Intent(context,
>> NativeCrashActivity.class);
>> -                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
>> -                    i.putExtra("PID", android.os.Process.myPid());
>> -                    context.startActivity(i);
>> -                }
>> -            });
>>          }
>>          return instance;
>>      }
>> @@ -81,10 +71,10 @@ public class VLCInstance {
>>          }
>>          int vout;
>>          try {
>> -               vout = Integer.parseInt(pref.getString("vout", "-1"));
>> +            vout = Integer.parseInt(pref.getString("vout", "-1"));
>>          }
>>          catch (NumberFormatException nfe) {
>> -               vout = -1;
>> +            vout = -1;
>>          }
>>          int deblocking;
>>          try {
>> --
>> 1.9.3 (Apple Git-50)
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/android/attachments/20150115/ead0fdbc/attachment-0001.html>


More information about the Android mailing list