[Android] [PATCH 3/3] Support for multiple player instances.

Paulo Vitor Magacho da Silva pvmagacho at gmail.com
Sun Jul 27 20:05:15 CEST 2014


Update version. Improved support for events.

---
 vlc-android/jni/libvlcjni-util.c                   |  17 ---
 vlc-android/jni/libvlcjni.c                        |  80 +++++++-----
 vlc-android/jni/utils.h                            |   2 -
 vlc-android/jni/vout.c                             | 135 +++++++++++----------
 vlc-android/jni/vout.h                             |  14 ++-
 .../src/org/videolan/libvlc/EventHandler.java      |  27 +++--
 vlc-android/src/org/videolan/libvlc/LibVLC.java    |  29 +++--
 vlc-android/src/org/videolan/libvlc/MediaList.java |   8 +-
 .../org/videolan/vlc/gui/PreferencesActivity.java  |   2 +-
 9 files changed, 172 insertions(+), 142 deletions(-)

diff --git a/vlc-android/jni/libvlcjni-util.c b/vlc-android/jni/libvlcjni-util.c
index 37f4d2d..e4079aa 100644
--- a/vlc-android/jni/libvlcjni-util.c
+++ b/vlc-android/jni/libvlcjni-util.c
@@ -129,23 +129,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/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
index f621d92..251a434 100644
--- a/vlc-android/jni/libvlcjni.c
+++ b/vlc-android/jni/libvlcjni.c
@@ -189,9 +189,10 @@ static void vlc_event_callback(const libvlc_event_t *ev, void *data)
     }
 
     /* Find the callback ID */
-    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(ILandroid/os/Bundle;)V");
+    jobject vlcObject = (jobject) data;
+    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback", "(ILandroid/os/Bundle;Lorg/videolan/libvlc/LibVLC;)V");
     if (methodID) {
-        (*env)->CallVoidMethod(env, eventHandlerInstance, methodID, ev->type, bundle);
+        (*env)->CallVoidMethod(env, eventHandlerInstance, methodID, ev->type, bundle, vlcObject);
     } else {
         LOGE("EventHandler: failed to get the callback method");
     }
@@ -207,23 +208,49 @@ 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);
+    JNIEnv* env;
+    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+        return -1;
+    }
+
+    jclass eventHandlerCls = (*env)->FindClass(env, "org/videolan/libvlc/EventHandler");
+    jmethodID methodId = (*env)->GetStaticMethodID(env, eventHandlerCls, "getInstance", "()Lorg/videolan/libvlc/EventHandler;");
+    jobject eventHandler = (*env)->CallStaticObjectMethod(env, eventHandlerCls, methodId);
+
+    eventHandlerInstance = (*env)->NewGlobalRef(env, eventHandler);
 
     LOGD("JNI interface loaded.");
     return JNI_VERSION_1_2;
 }
 
 void JNI_OnUnload(JavaVM* vm, void* reserved) {
-    pthread_mutex_destroy(&vout_android_lock);
-    pthread_cond_destroy(&vout_android_surf_attached);
+    JNIEnv* env;
+    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) == JNI_OK) {
+        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
+    }
+
+    LOGD("JNI interface un-loaded.");
 }
 
 // FIXME: use atomics
 static bool verbosity;
 
+
 void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
 {
+    // initialize android_surface_value_t structure
+    android_surf_value_t *android_surface = (android_surf_value_t *) malloc(sizeof(android_surf_value_t));
+
+    android_surface->vout_android_surf = NULL;
+    android_surface->vout_android_gui = NULL;
+    android_surface->vout_android_java_surf = NULL;
+    android_surface->vout_android_subtitles_surf = NULL;
+
+    pthread_mutex_init(&android_surface->vout_android_lock, NULL);
+    pthread_cond_init(&android_surface->vout_android_surf_attached, NULL);
+
+    setLong(env, thiz, "mAndroidSurfaceValue", (jlong)(intptr_t)android_surface);
+
     //only use OpenSLES if java side says we can
     jclass cls = (*env)->GetObjectClass(env, thiz);
     jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout", "()I");
@@ -326,12 +353,23 @@ void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
 
     libvlc_log_set(instance, debug_log, &verbosity);
 
-    init_native_crash_handler(env, thiz);
+    // init_native_crash_handler(env, thiz);
 }
 
 void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject thiz)
 {
-    destroy_native_crash_handler(env);
+    // clear surface lock and condition
+    android_surf_value_t *android_surface = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    if (android_surface != NULL) {
+        pthread_mutex_destroy(&android_surface->vout_android_lock);
+        pthread_cond_destroy(&android_surface->vout_android_surf_attached);
+
+        free(android_surface);
+    }
+    setLong(env, thiz, "mAndroidSurfaceValue", 0);
+
+    // destroy_native_crash_handler(env);
 
     releaseMediaPlayer(env, thiz);
     jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
@@ -345,24 +383,6 @@ void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject thiz)
     setLong(env, thiz, "mLibVlcInstance", 0);
 }
 
-void Java_org_videolan_libvlc_LibVLC_detachEventHandler(JNIEnv *env, jobject thiz)
-{
-    if (eventHandlerInstance != NULL) {
-        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
-        eventHandlerInstance = NULL;
-    }
-}
-
-void Java_org_videolan_libvlc_LibVLC_setEventHandler(JNIEnv *env, jobject thiz, jobject eventHandler)
-{
-    if (eventHandlerInstance != NULL) {
-        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
-        eventHandlerInstance = NULL;
-    }
-
-    eventHandlerInstance = getEventHandlerReference(env, thiz, eventHandler);
-}
-
 void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz, jlong instance,
                                              jstring mrl, jobjectArray mediaOptions)
 {
@@ -397,7 +417,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz, jlong in
         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);
+        libvlc_event_attach(ev, mp_events[i], vlc_event_callback, (void*) myJavaLibVLC);
 
     /* Keep a pointer to this media player */
     setLong(env, thiz, "mInternalMediaPlayerInstance", (jlong)(intptr_t)mp);
@@ -424,13 +444,17 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz, jlong in
 
     (*env)->ReleaseStringUTFChars(env, mrl, p_mrl);
 
+    // set the Android surface value structure before playing
+    android_surf_value_t *object = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+    libvlc_media_player_set_surfacevalue(mp, object);
+
     /* 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[] = {
         libvlc_MediaParsedChanged
     };
     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, (void*) myJavaLibVLC);
 
     libvlc_media_player_set_media(mp, p_md);
     libvlc_media_player_play(mp);
diff --git a/vlc-android/jni/utils.h b/vlc-android/jni/utils.h
index f8502d9..36ccec8 100644
--- a/vlc-android/jni/utils.h
+++ b/vlc-android/jni/utils.h
@@ -41,8 +41,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/vlc-android/jni/vout.c b/vlc-android/jni/vout.c
index f2f4346..d2cc183 100644
--- a/vlc-android/jni/vout.c
+++ b/vlc-android/jni/vout.c
@@ -23,96 +23,94 @@
 
 #include <jni.h>
 
+#include "vout.h"
+
 /** Unique Java VM instance, as defined in libvlcjni.c */
 extern JavaVM *myVm;
 
-pthread_mutex_t vout_android_lock;
-pthread_cond_t vout_android_surf_attached;
-static void *vout_android_surf = NULL;
-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;
 }
 
-void *jni_LockAndGetAndroidSurface() {
-    pthread_mutex_lock(&vout_android_lock);
-    while (vout_android_surf == NULL)
-        pthread_cond_wait(&vout_android_surf_attached, &vout_android_lock);
-    return vout_android_surf;
+void *jni_LockAndGetAndroidSurface(android_surf_value_t *android_surface) {
+    pthread_mutex_lock(&android_surface->vout_android_lock);
+    while (android_surface->vout_android_surf == NULL)
+        pthread_cond_wait(&android_surface->vout_android_surf_attached, &android_surface->vout_android_lock);
+    return android_surface->vout_android_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);
 }
 
-void jni_EventHardwareAccelerationError()
+void jni_EventHardwareAccelerationError(android_surf_value_t *android_surface)
 {
-    if (vout_android_gui == NULL)
+    if (android_surface->vout_android_gui == NULL)
         return;
 
     JNIEnv *env;
     (*myVm)->AttachCurrentThread(myVm, &env, NULL);
 
-    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);
     (*myVm)->DetachCurrentThread(myVm);
 }
 
-void jni_SetAndroidSurfaceSizeEnv(JNIEnv *p_env, int width, int height, int visible_width, int visible_height, int sar_num, int sar_den)
+void jni_SetAndroidSurfaceSizeEnv(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)
 {
-    if (vout_android_gui == NULL)
+    if (android_surface->vout_android_gui == NULL)
         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, "setSurfaceSize", "(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);
 }
 
-void jni_SetAndroidSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den)
+void jni_SetAndroidSurfaceSize(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;
 
     (*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
-    jni_SetAndroidSurfaceSizeEnv(p_env, width, height, visible_width, visible_height, sar_num, sar_den);
+    jni_SetAndroidSurfaceSizeEnv(p_env, android_surface, width, height, visible_width, visible_height, sar_num, sar_den);
 
     (*myVm)->DetachCurrentThread (myVm);
 }
 
-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 = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    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);
+    android_surf_value_t * android_surface = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    pthread_mutex_lock(&android_surface->vout_android_lock);
     jclass clz;
     jfieldID fid;
 
@@ -131,39 +129,46 @@ void Java_org_videolan_libvlc_LibVLC_attachSurface(JNIEnv *env, jobject thiz, jo
             }
             fid = (*env)->GetFieldID(env, clz, "mNativeSurface", "I");
         }
-        vout_android_surf = (void*)(*env)->GetIntField(env, surf, fid);
+        android_surface->vout_android_surf = (void*)(*env)->GetIntField(env, surf, fid);
         (*env)->DeleteLocalRef(env, clz);
     }
-    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_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);
-    vout_android_surf = NULL;
-    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 = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    pthread_mutex_lock(&android_surface->vout_android_lock);
+    android_surface->vout_android_surf = NULL;
+    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);
-    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 = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    pthread_mutex_lock(&android_surface->vout_android_lock);
+    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);
-    (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);
-    vout_android_subtitles_surf = NULL;
-    pthread_mutex_unlock(&vout_android_lock);
+    android_surf_value_t * android_surface = (android_surf_value_t *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
+
+    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/vlc-android/jni/vout.h b/vlc-android/jni/vout.h
index c3d4fd7..c439c12 100644
--- a/vlc-android/jni/vout.h
+++ b/vlc-android/jni/vout.h
@@ -21,8 +21,16 @@
 #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_surf;
+    void *vout_android_gui;
+    jobject vout_android_java_surf;
+    jobject vout_android_subtitles_surf;
+    bool vout_video_player_activity_created;
+} android_surf_value_t;
 
 #endif // LIBVLCJNI_VOUT_H
diff --git a/vlc-android/src/org/videolan/libvlc/EventHandler.java b/vlc-android/src/org/videolan/libvlc/EventHandler.java
index 16a0791..a816e06 100644
--- a/vlc-android/src/org/videolan/libvlc/EventHandler.java
+++ b/vlc-android/src/org/videolan/libvlc/EventHandler.java
@@ -21,6 +21,9 @@
 package org.videolan.libvlc;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import android.os.Bundle;
 import android.os.Handler;
@@ -96,11 +99,11 @@ public class EventHandler {
 
     public static final int HardwareAccelerationError         = 0x3000;
 
-    private ArrayList<Handler> mEventHandler;
+    private Map<LibVLC, ArrayList<Handler>> mMapHandler;
     private static EventHandler mInstance;
 
     EventHandler() {
-        mEventHandler = new ArrayList<Handler>();
+        mMapHandler = new HashMap<LibVLC, ArrayList<Handler>>();
     }
 
     public static EventHandler getInstance() {
@@ -110,22 +113,26 @@ public class EventHandler {
         return mInstance;
     }
 
-    public void addHandler(Handler handler) {
-        if (!mEventHandler.contains(handler))
-            mEventHandler.add(handler);
+    public void addHandler(LibVLC vlcObject, Handler handler) {
+        if (!mMapHandler.containsKey(vlcObject)) {
+            mMapHandler.put(vlcObject, new ArrayList<Handler>());
+        }
+        mMapHandler.get(vlcObject).add(handler);
     }
 
-    public void removeHandler(Handler handler) {
-        mEventHandler.remove(handler);
+    public void removeHandler(LibVLC vlcObject, Handler handler) {
+        mMapHandler.get(vlcObject).remove(handler);
     }
 
     /** This method is called by a native thread **/
-    public void callback(int event, Bundle b) {
+    public void callback(int event, Bundle b, LibVLC vlcObject) {
+        List<Handler> eventHandlers = mMapHandler.get(vlcObject);
         b.putInt("event", event);
-        for (int i = 0; i < mEventHandler.size(); i++) {
+        for (int i = 0; i < eventHandlers.size(); i++) {
             Message msg = Message.obtain();
             msg.setData(b);
-            mEventHandler.get(i).sendMessage(msg);
+            msg.obj = vlcObject;
+            eventHandlers.get(i).sendMessage(msg);
         }
     }
 }
diff --git a/vlc-android/src/org/videolan/libvlc/LibVLC.java b/vlc-android/src/org/videolan/libvlc/LibVLC.java
index cf1dbb5..ef2f4fa 100644
--- a/vlc-android/src/org/videolan/libvlc/LibVLC.java
+++ b/vlc-android/src/org/videolan/libvlc/LibVLC.java
@@ -51,6 +51,9 @@ public class LibVLC {
     private int mInternalMediaPlayerIndex = 0; // Read-only, reserved for JNI
     private long mInternalMediaPlayerInstance = 0; // Read-only, reserved for JNI
 
+    // Android surface structure
+    private long mAndroidSurfaceValue = 0; // Read-only, reserved for JNI
+
     private MediaList mMediaList; // Pointer to media list being followed
     private MediaList mPrimaryList; // Primary/default media list; see getPrimaryMediaList()
 
@@ -155,10 +158,9 @@ public class LibVLC {
     }
 
     /**
-     * Constructor
-     * It is private because this class is a singleton.
+     * Constructor.
      */
-    private LibVLC() {
+    public LibVLC() {
         mAout = new AudioOutput();
     }
 
@@ -224,7 +226,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();
@@ -235,6 +237,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.
      */
@@ -350,7 +361,7 @@ public class LibVLC {
         applyEqualizer();
     }
 
-    private void applyEqualizer()
+    protected void applyEqualizer()
     {
         setNativeEqualizer(mInternalMediaPlayerInstance, this.equalizer);
     }
@@ -392,7 +403,6 @@ public class LibVLC {
             mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath() : null;
             nativeInit();
             mMediaList = mPrimaryList = new MediaList(this);
-            setEventHandler(EventHandler.getInstance());
             mIsInitialized = true;
         }
     }
@@ -404,7 +414,6 @@ public class LibVLC {
     public void destroy() {
         Log.v(TAG, "Destroying LibVLC instance");
         nativeDestroy();
-        detachEventHandler();
         mIsInitialized = false;
     }
 
@@ -661,7 +670,7 @@ public class LibVLC {
     public native int getSpuTracksCount();
 
     public static native String nativeToURI(String path);
-    
+
     public native static void sendMouseEvent( int action, int button, int x, int y);
 
     /**
@@ -702,10 +711,6 @@ 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();
diff --git a/vlc-android/src/org/videolan/libvlc/MediaList.java b/vlc-android/src/org/videolan/libvlc/MediaList.java
index 85b2d2a..b555d1a 100644
--- a/vlc-android/src/org/videolan/libvlc/MediaList.java
+++ b/vlc-android/src/org/videolan/libvlc/MediaList.java
@@ -105,12 +105,12 @@ public class MediaList {
         ArrayList<String> children = new ArrayList<String>();
         int ret = expandMedia(mLibVLC, position, children);
         if(ret == 0) {
-            mEventHandler.callback(EventHandler.CustomMediaListExpanding, new Bundle());
+            mEventHandler.callback(EventHandler.CustomMediaListExpanding, new Bundle(), mLibVLC);
             this.remove(position);
             for(String mrl : children) {
                 this.insert(position, mrl);
             }
-            mEventHandler.callback(EventHandler.CustomMediaListExpandingEnd, new Bundle());
+            mEventHandler.callback(EventHandler.CustomMediaListExpandingEnd, new Bundle(), mLibVLC);
         }
         return ret;
     }
@@ -155,7 +155,7 @@ public class MediaList {
         Bundle b = new Bundle();
         b.putInt("index_before", startPosition);
         b.putInt("index_after", endPosition);
-        mEventHandler.callback(EventHandler.CustomMediaListItemMoved, b);
+        mEventHandler.callback(EventHandler.CustomMediaListItemMoved, b, mLibVLC);
     }
 
     public void remove(int position) {
@@ -250,6 +250,6 @@ public class MediaList {
         Bundle b = new Bundle();
         b.putString("item_uri", uri);
         b.putInt("item_index", position);
-        mEventHandler.callback(event, b);
+        mEventHandler.callback(event, b, mLibVLC);
     }
 }
diff --git a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
index 4c9539f..eedadf5 100644
--- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
@@ -291,7 +291,7 @@ public class PreferencesActivity extends PreferenceActivity implements OnSharedP
                 || key.equalsIgnoreCase("enable_verbose_mode")
                 || key.equalsIgnoreCase("network_caching")) {
             VLCInstance.updateLibVlcSettings(sharedPreferences);
-            LibVLC.restart(this);
+            LibVLC.restartInstance(this);
         }
     }
 
-- 
1.8.5.2 (Apple Git-48)



More information about the Android mailing list