[Android] [PATCH] Add support for multiple video instances.
Paulo Vitor Magacho da Silva
pvmagacho at gmail.com
Fri Dec 5 02:14:03 CET 2014
Please ignore this patch.
Thanks
2014-12-04 23:12 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 | 186
> ++++++++++++---------
> libvlc/jni/vout.h | 24 ++-
> libvlc/src/org/videolan/libvlc/EventHandler.java | 8 -
> libvlc/src/org/videolan/libvlc/LibVLC.java | 98 +++--------
> 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, 399 insertions(+), 323 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 ecfb02e..6f35182 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)
> @@ -353,8 +370,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);
>
> @@ -364,45 +379,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,
> @@ -411,25 +426,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,
> @@ -441,10 +455,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");
> @@ -452,13 +463,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[] = {
> @@ -466,10 +480,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)
> {
> @@ -654,23 +668,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 04c933c..7cdc234 100644
> --- a/libvlc/jni/vout.c
> +++ b/libvlc/jni/vout.c
> @@ -22,100 +22,104 @@
> #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(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;
> }
>
> -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;
> +void jni_LockAndroidSurface(android_surf_value_t *android_surface) {
> + pthread_mutex_lock(&android_surface->vout_android_lock);
> }
>
> -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)
> {
> 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;
> @@ -154,28 +158,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;
>
> @@ -183,62 +188,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 fde2704..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,52 +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
> - 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);
> - }
> - }
> -
> /**
> * Singleton constructor of libVLC Without surface and vout to create
> the
> * thumbnail and get information e.g. on the MediaLibraryActivity
> @@ -190,10 +141,9 @@ public class LibVLC {
> }
>
> /**
> - * Constructor
> - * It is private because this class is a singleton.
> + * Constructor.
> */
> - private LibVLC() {
> + public LibVLC() {
> mAout = new AudioOutput();
> }
>
> @@ -259,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();
> @@ -270,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.
> */
> @@ -491,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;
> @@ -531,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();
> @@ -541,7 +500,6 @@ public class LibVLC {
> mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath()
> : null;
> nativeInit();
> mMediaList = mPrimaryList = new MediaList(this);
> - setEventHandler(EventHandler.getInstance());
> mIsInitialized = true;
> }
> }
> @@ -553,7 +511,6 @@ public class LibVLC {
> public void destroy() {
> Log.v(TAG, "Destroying LibVLC instance");
> nativeDestroy();
> - detachEventHandler();
> mIsInitialized = false;
> }
>
> @@ -833,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 9f0109c..b069452 100644
> --- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
> +++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
> @@ -292,7 +292,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/20141204/836a9c1e/attachment-0001.html>
More information about the Android
mailing list