[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