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

Thomas Guillem thomas at gllm.fr
Wed Dec 3 10:59:47 CET 2014


Ah, I thought your previous patch was already doing it good (moving the
load library into LibVlcUtil).

When you call static LibVlcUtil.isLibraryLoaded() ; the code inside the
static { } block that load libraries will be first executed, then the
function will return true if there was no errors.

On Tue, Dec 2, 2014, at 04:46, Paulo Vitor Magacho da Silva wrote:
> To use the NativeCrashHandler inside VLCApplication::onCreate I need
> to statically load the dynamic libraries, which now are loaded in
> LibVLC.java. Should I move this static block to NativeCrashHandler or
> to VLCApplication::onCreate as a normal init method? Thanks
>
> 2014-12-01 7:23 GMT-02:00 Thomas Guillem <thomas at gllm.fr>:
>>
>>
>>
On Sat, Nov 29, 2014, at 06:22, Paulo Vitor Magacho da Silva wrote:
>>
> ---
>>
>libvlc/jni/libvlcjni-equalizer.c | 4 +-
>>
>libvlc/jni/libvlcjni-util.c | 17 --
>>
>libvlc/jni/libvlcjni.c | 187
>>
>++++++++++++---------
>>
>libvlc/jni/native_crash_handler.c | 119 +++++++++++--
>>
>libvlc/jni/native_crash_handler.h | 8 +-
>>
>libvlc/jni/utils.h | 2 -
>>
>libvlc/jni/vout.c | 186
>>
>+++++++++++---------
>>
>libvlc/jni/vout.h | 25 ++-
>>
>libvlc/src/org/videolan/libvlc/EventHandler.java | 8 -
>>
>libvlc/src/org/videolan/libvlc/LibVLC.java | 35 ++--
>>
>.../src/org/videolan/vlc/audio/AudioService.java | 14 +-
>>
>.../org/videolan/vlc/gui/PreferencesActivity.java | 2 +-
>>
>.../vlc/gui/video/VideoPlayerActivity.java | 9 +-
>>
>13 files changed, 381 insertions(+), 235 deletions(-)
>>
>
>>
> 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 b2c0cce..eaca4ca 100644
>>
> --- a/libvlc/jni/libvlcjni.c
>>
> +++ b/libvlc/jni/libvlcjni.c
>>
> @@ -72,6 +72,26 @@ static void add_media_options(libvlc_media_t *p_md,
>>
> JNIEnv *env, jobjectArray me
>>
>}
>>
>}
>>
>
>>
> +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);
>>
> + }
>>
> +}
>>
> +
>>
>libvlc_media_t *new_media(JNIEnv *env, jobject thiz, jstring
>>
>fileLocation, bool noOmx, bool noVideo)
>>
>{
>>
>libvlc_instance_t *libvlc = getLibVlcInstance(env, thiz);
>>
> @@ -98,24 +118,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 +140,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 +204,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 +241,16 @@ 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);
>>
> + init_native_crash_handler();
>>
>
>>
>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);
>>
> + destroy_native_crash_handler();
>>
> +
>>
> + LOGD("JNI interface un-loaded.");
>>
>}
>>
>
>>
>int jni_attach_thread(JNIEnv **env, const char *thread_name)
>>
> @@ -353,8 +375,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 +384,50 @@ 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);
>>
> + add_native_crash_handler(env, p_sys->p_this);
>>
>}
>>
>
>>
>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);
>>
> +
>>
> + remove_native_crash_handler(env, p_sys->p_this);
>>
>
>>
>releaseMediaPlayer(env, thiz);
>>
> - jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
>>
> - if (!libVlcInstance)
>>
> - return; // Already destroyed
>>
>> this "Already destroyed" check should be done just after
>> libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>>
> +
>>
>>
>
>>
>> > - libvlc_instance_t *instance = (libvlc_instance_t*)(intptr_t)
>>
> libVlcInstance;
>>
> - libvlc_log_unset(instance);
>>
> - libvlc_release(instance);
>>
> + if (p_sys->p_this != NULL)
>>
> + (*env)->DeleteGlobalRef(env, p_sys->p_this);
>>
>
>>
> - setLong(env, thiz, "mLibVlcInstance", 0);
>>
> -}
>>
> + 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_detachEventHandler(JNIEnv *env,
>>
> jobject thiz)
>>
> -{
>>
> - if (eventHandlerInstance != NULL) {
>>
> - (*env)->DeleteGlobalRef(env, eventHandlerInstance);
>>
> - eventHandlerInstance = NULL;
>>
> - }
>>
> -}
>>
> + free(p_sys->p_surf);
>>
>
>>
> -void Java_org_videolan_libvlc_LibVLC_setEventHandler(JNIEnv *env,
>>
> jobject thiz, jobject eventHandler)
>>
> -{
>>
> - if (eventHandlerInstance != NULL) {
>>
> - (*env)->DeleteGlobalRef(env, eventHandlerInstance);
>>
> - eventHandlerInstance = NULL;
>>
> - }
>>
> + if (!p_sys->p_libvlc)
>>
> + return; // Already destroyed
>>
>
>>
> - eventHandlerInstance = getEventHandlerReference(env, thiz,
>>
> eventHandler);
>>
> + libvlc_instance_t *instance = p_sys->p_libvlc;
>>
> + LOGI("LibVLC destroyed: %p", instance);
>>
> +
>>
> + libvlc_log_unset(instance);
>>
> + libvlc_release(instance);
>>
> +
>>
> + setLibVlcSysInstance(env, thiz, NULL);
>>
>> you forgot to free p_sys
>>
>>
>}
>>
>
>>
>void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,
>>
> @@ -411,25 +436,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 +465,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 +473,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_surfacevalue(p_sys->p_mp, p_sys->p_surf);
>>
> +
>>
>> again, I would call that function:
>> libvlc_media_player_set_androidobject
>>
>>
>/* 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 +490,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 +678,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..1a41c5b 100644
>>
> --- a/libvlc/jni/native_crash_handler.c
>>
> +++ b/libvlc/jni/native_crash_handler.c
>>
> @@ -19,11 +19,22 @@
>>
>*****************************************************************************/
>>
>
>>
>#include <signal.h>
>>
> +#include <pthread.h>
>>
>
>>
>#include "native_crash_handler.h"
>>
>
>>
> +#define LOG_TAG "VLC/JNI/crash"
>>
> +#include "log.h"
>>
> +
>>
> +struct libvlc_crash_handler_t {
>>
> + void *j_libVLC;
>>
> + libvlc_crash_handler_t *next;
>>
> + libvlc_crash_handler_t *prev;
>>
> +};
>>
> +
>>
>static struct sigaction old_actions[NSIG];
>>
> -static jobject j_libVLC;
>>
> +static libvlc_crash_handler_t *first = NULL;
>>
> +static libvlc_crash_handler_t *last = NULL;
>>
>
>>
>#define THREAD_NAME "native_crash_handler"
>>
>extern int jni_attach_thread(JNIEnv **env, const char *thread_name);
>>
> @@ -44,6 +55,7 @@ static const int monitored_signals[] = {
>>
>SIGPIPE
>>
>};
>>
>
>>
> +pthread_mutex_t native_handler_lock;
>>
>
>>
>/**
>>
>* Callback called when a monitored signal is triggered.
>>
> @@ -54,21 +66,32 @@ 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);
>>
> - jmethodID methodId = (*env)->GetMethodID(env, cls, "onNativeCrash",
>>
> "()V");
>>
> - (*env)->CallVoidMethod(env, j_libVLC, methodId);
>>
> + pthread_mutex_lock(&native_handler_lock);
>>
> +
>>
> + libvlc_crash_handler_t *lp = first;
>>
> + while (lp != NULL)
>>
> + {
>>
> + jclass cls = (*env)->GetObjectClass(env, lp->j_libVLC);
>>
> + jmethodID methodId = (*env)->GetMethodID(env, cls,
>>
> "onNativeCrash", "()V");
>>
> + (*env)->CallVoidMethod(env, lp->j_libVLC, methodId);
>>
> +
>>
> + (*env)->DeleteLocalRef(env, cls);
>>
> +
>>
> + libvlc_crash_handler_t *todelete = lp;
>>
> + lp = lp->next;
>>
> +
>>
> + free(todelete);
>>
> + }
>>
> + pthread_mutex_unlock(&native_handler_lock);
>>
>
>>
> - (*env)->DeleteLocalRef(env, cls);
>>
>jni_detach_thread();
>>
>
>>
>// Call the old signal handler.
>>
>old_actions[signal].sa_handler(signal);
>>
>}
>>
>
>>
> -
>>
> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)
>>
> +void init_native_crash_handler()
>>
>{
>>
> - j_libVLC = (*env)->NewGlobalRef(env, j_libVLC_local);
>>
>struct sigaction handler;
>>
>memset(&handler, 0, sizeof(struct sigaction));
>>
>
>>
> @@ -81,10 +104,13 @@ void init_native_crash_handler(JNIEnv
> *env, jobject
>>
> j_libVLC_local)
>>
>const int s = monitored_signals[i];
>>
>sigaction(s, &handler, &old_actions[s]);
>>
>}
>>
> -}
>>
>
>>
> + pthread_mutex_init(&native_handler_lock, NULL);
>>
> +
>>
> + LOGI("Native crash handler initialized");
>>
> +}
>>
>
>>
> -void destroy_native_crash_handler(JNIEnv *env)
>>
> +void destroy_native_crash_handler()
>>
>{
>>
>// Uninstall the signal handlers and restore their old actions.
>>
>for (unsigned i = 0; i < sizeof(monitored_signals) / sizeof(int);
>>
>++i)
>>
> @@ -93,5 +119,76 @@ void destroy_native_crash_handler(JNIEnv *env)
>>
>sigaction(s, &old_actions[s], NULL);
>>
>}
>>
>
>>
> - (*env)->DeleteGlobalRef(env, j_libVLC);
>>
> + pthread_mutex_destroy(&native_handler_lock);
>>
> +
>>
> + LOGI("Native crash handler destroyed");
>>
> +}
>>
> +
>>
> +void add_native_crash_handler(JNIEnv *env, void *j_libVLC_local)
>>
> +{
>>
> + LOGI("Add crash handler to %p", j_libVLC_local);
>>
> +
>>
> + pthread_mutex_lock(&native_handler_lock);
>>
> +
>>
> + libvlc_crash_handler_t *current = (libvlc_crash_handler_t *)
>>
> malloc(sizeof(libvlc_crash_handler_t));
>>
> + current->j_libVLC = j_libVLC_local;
>>
> + current->prev = last;
>>
> + current->next = NULL;
>>
> +
>>
> + // update values
>>
> + if (first == NULL)
>>
> + first = current;
>>
> + if (last != NULL)
>>
> + last->next = current;
>>
> +
>>
> + last = current;
>>
> +
>>
> + libvlc_crash_handler_t *lp = first;
>>
> + while (lp != NULL)
>>
> + {
>>
> + LOGI("Current handlers: %p", lp);
>>
> + lp = lp->next;
>>
> + }
>>
> +
>>
> + pthread_mutex_unlock(&native_handler_lock);
>>
> +}
>>
> +
>>
> +
>>
> +void remove_native_crash_handler(JNIEnv *env, jobject j_libVLC_local)
>>
> +{
>>
> + LOGI("Remove crash handler to %p", j_libVLC_local);
>>
> +
>>
> + pthread_mutex_lock(&native_handler_lock);
>>
> +
>>
> + libvlc_crash_handler_t *lp = first;
>>
> + while (lp != NULL)
>>
> + {
>>
> + if (j_libVLC_local == lp->j_libVLC)
>>
> + {
>>
> + LOGI("Destroying handler: %p", lp);
>>
> +
>>
> + libvlc_crash_handler_t *todelete = lp;
>>
> + libvlc_crash_handler_t *prev = lp->prev;
>>
> + libvlc_crash_handler_t *next = lp->next;
>>
> + if (lp == first) {
>>
> + first = next;
>>
> + if (first != NULL)
>>
> + first->prev = NULL;
>>
> + } else if (lp == last) {
>>
> + last = prev;
>>
> + last->next = NULL;
>>
> + } else {
>>
> + prev->next = next;
>>
> + next->prev = prev;
>>
> + }
>>
> +
>>
> + free(todelete);
>>
> +
>>
> + break;
>>
> + }
>>
> +
>>
> + lp = lp->next;
>>
> + }
>>
> +
>>
> + pthread_mutex_unlock(&native_handler_lock);
>>
>}
>>
> diff --git a/libvlc/jni/native_crash_handler.h
>>
> b/libvlc/jni/native_crash_handler.h
>>
> index a57e61e..080fc0b 100644
>>
> --- a/libvlc/jni/native_crash_handler.h
>>
> +++ b/libvlc/jni/native_crash_handler.h
>>
> @@ -23,7 +23,11 @@
>>
>
>>
>#include <jni.h>
>>
>
>>
> -void init_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);
>>
> -void destroy_native_crash_handler(JNIEnv *env);
>>
> +typedef struct libvlc_crash_handler_t libvlc_crash_handler_t;
>>
> +
>>
> +void init_native_crash_handler();
>>
> +void destroy_native_crash_handler();
>>
> +void add_native_crash_handler(JNIEnv *env, jobject j_libVLC_local);
>>
> +void remove_native_crash_handler(JNIEnv *env, jobject
> j_libVLC_local);
>>
>>
>> You don't need all that for nativecrash handler. It must be a
>> singleton.
>>
on vlc-android, you can check how it is used:
>>
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);
>>
}
>>
>>
You see, it start a new activity and it just need a context.
>>
>>
So I would add NativeCrashHandler.java in libvlc with a static native
>>
function: Java_org_videolan_libvlc_NativeCrashHandler_setListener.
>>
And I would set the listener in VLCApplication::onCreate by calling
>>
NativeCrashHandler.setListener()
>>
>>
>
>>
>#endif // LIBVLCJNI_NATIVE_CRASH_HANDLER_H
>>
> diff --git a/libvlc/jni/utils.h b/libvlc/jni/utils.h
>>
> index 5da3514..ac23660 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..6681b59 100644
>>
> --- a/libvlc/jni/vout.h
>>
> +++ b/libvlc/jni/vout.h
>>
> @@ -21,8 +21,27 @@
>>
>#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 5d1f830..5273887 100644
>>
> --- a/libvlc/src/org/videolan/libvlc/LibVLC.java
>>
> +++ b/libvlc/src/org/videolan/libvlc/LibVLC.java
>>
> @@ -61,11 +61,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()
>>
> @@ -190,10 +191,9 @@ public class LibVLC {
>>
>}
>>
>
>>
>/**
>>
> - * Constructor
>>
> - * It is private because this class is a singleton.
>>
> + * Constructor.
>>
>*/
>>
> - private LibVLC() {
>>
> + public LibVLC() {
>>
>mAout = new AudioOutput();
>>
>}
>>
>
>>
> @@ -259,7 +259,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 +270,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.
>>
>*/
>>
> @@ -488,11 +497,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;
>>
> @@ -538,7 +547,6 @@ public class LibVLC {
>>
>mCachePath = (cacheDir != null) ? cacheDir.getAbsolutePath()
>>
>: null;
>>
>nativeInit();
>>
>mMediaList = mPrimaryList = new MediaList(this);
>>
> - setEventHandler(EventHandler.getInstance());
>>
>mIsInitialized = true;
>>
>}
>>
>}
>>
> @@ -550,7 +558,6 @@ public class LibVLC {
>>
>public void destroy() {
>>
>Log.v(TAG, "Destroying LibVLC instance");
>>
>nativeDestroy();
>>
> - detachEventHandler();
>>
>mIsInitialized = false;
>>
>}
>>
>
>>
> @@ -830,10 +837,6 @@ public class LibVLC {
>>
>return mMediaList.expandMedia(mInternalMediaPlayerIndex);
>>
>}
>>
>
>>
> - private native void setEventHandler(EventHandler eventHandler);
>>
> -
>>
> - private native void detachEventHandler();
>>
> -
>>
>public native float[] getBands();
>>
>
>>
>public native String[] getPresets();
>>
> @@ -853,6 +856,10 @@ public class LibVLC {
>>
>mOnNativeCrashListener.onNativeCrash();
>>
>}
>>
>
>>
> + public EventHandler getEventHandler() {
>>
> + return eventHandler;
>>
> + }
>>
> +
>>
>public String getCachePath() {
>>
>return mCachePath;
>>
>}
>>
> 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() {
>>
> --
>>
> 1.9.3 (Apple Git-50)
>>
>
>>
>
>> > _______________________________________________
>>
> Android mailing list
>>
> Android at videolan.org
>>
> https://mailman.videolan.org/listinfo/android
>>
>
>>
>>
The rest is good.
>>
_______________________________________________
>>
Android mailing list
>> Android at videolan.org https://mailman.videolan.org/listinfo/android
>
> _________________________________________________
> Android mailing list Android at videolan.org
> https://mailman.videolan.org/listinfo/android

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/android/attachments/20141203/56a48942/attachment-0001.html>


More information about the Android mailing list