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

Paulo Vitor Magacho da Silva pvmagacho at gmail.com
Tue Dec 2 13:06:17 CET 2014


Hi, 

Thanks. I've sent already the patch today to the vlc list.

Can you check that ?

Thanks,
Paulo 

-----Mensagem Original-----
De: "Thomas Guillem" <thomas at gllm.fr>
Enviada em: ‎02/‎12/‎2014 09:28
Para: "android at videolan.org" <android at videolan.org>
Assunto: Re: [Android] [PATCH] Add support for multiple video instances.

Good solution for NativeCrashHandler, it's far better now.

I'm OK with this patch, I'll merge it when patches on vlc are applied.
Can you propose the final patch on vlc-devel too ?

On Tue, Dec 2, 2014, at 11:28, Paulo Vitor Magacho da Silva wrote:
> ---
>  libvlc/jni/libvlcjni-equalizer.c                   |   4 +-
>  libvlc/jni/libvlcjni-util.c                        |  17 --
>  libvlc/jni/libvlcjni.c                             | 179
>  +++++++++++---------
>  libvlc/jni/native_crash_handler.c                  |  25 +--
>  libvlc/jni/native_crash_handler.h                  |   5 +-
>  libvlc/jni/utils.h                                 |   2 -
>  libvlc/jni/vout.c                                  | 186
>  ++++++++++++---------
>  libvlc/jni/vout.h                                  |  24 ++-
>  libvlc/src/org/videolan/libvlc/EventHandler.java   |   8 -
>  libvlc/src/org/videolan/libvlc/LibVLC.java         |  98 +++--------
>  libvlc/src/org/videolan/libvlc/LibVlcUtil.java     |  56 ++++++-
>  .../org/videolan/libvlc/NativeCrashHandler.java    |  64 +++++++
>  .../src/org/videolan/vlc/VLCApplication.java       |  15 +-
>  .../src/org/videolan/vlc/audio/AudioService.java   |  14 +-
>  .../org/videolan/vlc/gui/PreferencesActivity.java  |   2 +-
>  .../vlc/gui/video/VideoPlayerActivity.java         |   9 +-
>  .../src/org/videolan/vlc/util/VLCInstance.java     |  14 +-
>  17 files changed, 399 insertions(+), 323 deletions(-)
>  create mode 100644
>  libvlc/src/org/videolan/libvlc/NativeCrashHandler.java
> 
> diff --git a/libvlc/jni/libvlcjni-equalizer.c
> b/libvlc/jni/libvlcjni-equalizer.c
> index 2dad0e4..d11f24d 100644
> --- a/libvlc/jni/libvlcjni-equalizer.c
> +++ b/libvlc/jni/libvlcjni-equalizer.c
> @@ -89,10 +89,10 @@ jfloatArray
> Java_org_videolan_libvlc_LibVLC_getPreset(JNIEnv *env, jobject thiz,
>   * apply equalizer settings (param bands is float[] (first element is
>   preamp, then bands))
>   */
>  //"--audio-filter=equalizer", "--equalizer-bands=-3.5 -4.5 -1 0 0 5 8 8
>  8 8",
> -jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,
> jobject thiz, jlong media_player, jfloatArray bands)
> +jint Java_org_videolan_libvlc_LibVLC_setNativeEqualizer(JNIEnv *env,
> jobject thiz, jfloatArray bands)
>  {
>      jint res = -1;
> -    libvlc_media_player_t *mp =
> (libvlc_media_player_t*)(intptr_t)media_player;
> +    libvlc_media_player_t *mp = getMediaPlayer(env, thiz);
>      if (!mp)
>          return res;
>  
> diff --git a/libvlc/jni/libvlcjni-util.c b/libvlc/jni/libvlcjni-util.c
> index 205d59d..67c2554 100644
> --- a/libvlc/jni/libvlcjni-util.c
> +++ b/libvlc/jni/libvlcjni-util.c
> @@ -131,23 +131,6 @@ void arrayListStringAdd(JNIEnv *env, jclass class,
> jmethodID methodID, jobject a
>      (*env)->DeleteLocalRef(env, jstr);
>  }
>  
> -jobject getEventHandlerReference(JNIEnv *env, jobject thiz, jobject
> eventHandler)
> -{
> -    jclass cls = (*env)->GetObjectClass(env, eventHandler);
> -    if (!cls) {
> -        LOGE("setEventHandler: failed to get class reference");
> -        return NULL;
> -    }
> -
> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",
> "(ILandroid/os/Bundle;)V");
> -    if (!methodID) {
> -        LOGE("setEventHandler: failed to get the callback method");
> -        return NULL;
> -    }
> -
> -    return (*env)->NewGlobalRef(env, eventHandler);
> -}
> -
>  static void debug_buffer_log(void *data, int level, const char *fmt,
>  va_list ap)
>  {
>      bool isAttached = false;
> diff --git a/libvlc/jni/libvlcjni.c b/libvlc/jni/libvlcjni.c
> index ecfb02e..6f35182 100644
> --- a/libvlc/jni/libvlcjni.c
> +++ b/libvlc/jni/libvlcjni.c
> @@ -38,7 +38,6 @@
>  #include "aout.h"
>  #include "vout.h"
>  #include "utils.h"
> -#include "native_crash_handler.h"
>  
>  #define VOUT_ANDROID_SURFACE 0
>  #define VOUT_OPENGLES2       1
> @@ -60,6 +59,26 @@ int jni_attach_thread(JNIEnv **env, const char
> *thread_name);
>  void jni_detach_thread();
>  int jni_get_env(JNIEnv **env);
>  
> +static void setLibVlcSysInstance(JNIEnv *env, jobject thiz,
> libvlc_instance_sys_t *p_sys)
> +{
> +    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) p_sys);
> +}
> +
> +static libvlc_instance_sys_t *getLibVlcSysInstance(JNIEnv *env, jobject
> thiz)
> +{
> +    return (libvlc_instance_sys_t *)(intptr_t)getLong(env, thiz,
> "mLibVlcInstance");
> +}
> +
> +static void releaseMediaPlayer(JNIEnv *env, jobject thiz)
> +{
> +    libvlc_media_player_t *p_mp = getMediaPlayer(env, thiz);
> +    if (p_mp)
> +    {
> +        libvlc_media_player_stop(p_mp);
> +        libvlc_media_player_release(p_mp);
> +    }
> +}
> +
>  static void add_media_options(libvlc_media_t *p_md, JNIEnv *env,
>  jobjectArray mediaOptions)
>  {
>      int stringCount = (*env)->GetArrayLength(env, mediaOptions);
> @@ -98,24 +117,20 @@ libvlc_media_t *new_media(JNIEnv *env, jobject thiz,
> jstring fileLocation, bool
>  
>  libvlc_instance_t *getLibVlcInstance(JNIEnv *env, jobject thiz)
>  {
> -    return (libvlc_instance_t*)(intptr_t)getLong(env, thiz,
> "mLibVlcInstance");
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
> +    return p_sys ? p_sys->p_libvlc : NULL;
>  }
>  
> -libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)
> +android_surf_value_t *getAndroidSurfaceInstance(JNIEnv *env, jobject
> thiz)
>  {
> -    return (libvlc_media_player_t*)(intptr_t)getLong(env, thiz,
> "mInternalMediaPlayerInstance");
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
> +    return p_sys ? p_sys->p_surf : NULL;
>  }
>  
> -
> -static void releaseMediaPlayer(JNIEnv *env, jobject thiz)
> +libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz)
>  {
> -    libvlc_media_player_t* p_mp = getMediaPlayer(env, thiz);
> -    if (p_mp)
> -    {
> -        libvlc_media_player_stop(p_mp);
> -        libvlc_media_player_release(p_mp);
> -        setLong(env, thiz, "mInternalMediaPlayerInstance", 0);
> -    }
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
> +    return p_sys ? p_sys->p_mp : NULL;
>  }
>  
>  /* Pointer to the Java virtual machine
> @@ -124,17 +139,12 @@ static void releaseMediaPlayer(JNIEnv *env, jobject
> thiz)
>   */
>  static JavaVM *myVm;
>  
> -static jobject eventHandlerInstance = NULL;
> -
>  static void vlc_event_callback(const libvlc_event_t *ev, void *data)
>  {
>      JNIEnv *env;
>  
>      bool isAttached = false;
>  
> -    if (eventHandlerInstance == NULL)
> -        return;
> -
>      if (jni_get_env(&env) < 0) {
>          if (jni_attach_thread(&env, THREAD_NAME) < 0)
>              return;
> @@ -193,20 +203,31 @@ static void vlc_event_callback(const libvlc_event_t
> *ev, void *data)
>          free(mrl);
>      }
>  
> +    /* The LibVLC object */
> +    jobject vlcObject = (jobject) data;
> +
> +    /* Get the event handler object */
> +    jclass cls = (*env)->GetObjectClass(env, vlcObject);
> +    jmethodID methodId = (*env)->GetMethodID(env, cls,
> "getEventHandler", "()Lorg/videolan/libvlc/EventHandler;");
> +    jobject eventHandlerInstance = (*env)->CallObjectMethod(env,
> vlcObject, methodId);
> +
> +    (*env)->DeleteLocalRef(env, cls);
> +
>      /* Get the object class */
> -    jclass cls = (*env)->GetObjectClass(env, eventHandlerInstance);
> +    cls = (*env)->GetObjectClass(env, eventHandlerInstance);
>      if (!cls) {
>          LOGE("EventHandler: failed to get class reference");
>          goto end;
>      }
>  
>      /* Find the callback ID */
> -    jmethodID methodID = (*env)->GetMethodID(env, cls, "callback",
> "(ILandroid/os/Bundle;)V");
> -    if (methodID) {
> -        (*env)->CallVoidMethod(env, eventHandlerInstance, methodID,
> ev->type, bundle);
> +    methodId = (*env)->GetMethodID(env, cls, "callback",
> "(ILandroid/os/Bundle;)V");
> +    if (methodId) {
> +        (*env)->CallVoidMethod(env, eventHandlerInstance, methodId,
> ev->type, bundle);
>      } else {
>          LOGE("EventHandler: failed to get the callback method");
>      }
> +    (*env)->DeleteLocalRef(env, cls);
>  
>  end:
>      (*env)->DeleteLocalRef(env, bundle);
> @@ -219,16 +240,12 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved)
>      // Keep a reference on the Java VM.
>      myVm = vm;
>  
> -    pthread_mutex_init(&vout_android_lock, NULL);
> -    pthread_cond_init(&vout_android_surf_attached, NULL);
> -
>      LOGD("JNI interface loaded.");
>      return VLC_JNI_VERSION;
>  }
>  
>  void JNI_OnUnload(JavaVM* vm, void* reserved) {
> -    pthread_mutex_destroy(&vout_android_lock);
> -    pthread_cond_destroy(&vout_android_surf_attached);
> +    LOGD("JNI interface un-loaded.");
>  }
>  
>  int jni_attach_thread(JNIEnv **env, const char *thread_name)
> @@ -353,8 +370,6 @@ void
> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
>      };
>      libvlc_instance_t *instance = libvlc_new(sizeof(argv) /
>      sizeof(*argv), argv);
>  
> -    setLong(env, thiz, "mLibVlcInstance", (jlong)(intptr_t) instance);
> -
>      (*env)->ReleaseStringUTFChars(env, chroma, chromastr);
>      (*env)->ReleaseStringUTFChars(env, subsencoding, subsencodingstr);
>  
> @@ -364,45 +379,45 @@ void
> Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject thiz)
>          (*env)->ThrowNew(env, exc, "Unable to instantiate LibVLC");
>      }
>  
> +    /* Set values to libvlc sys instance */
> +    libvlc_instance_sys_t  *p_sys = (libvlc_instance_sys_t *) calloc(1,
> sizeof(libvlc_instance_sys_t));
> +    p_sys->p_libvlc = instance;
> +    p_sys->p_surf = (android_surf_value_t *) calloc(1,
> sizeof(android_surf_value_t));
> +    p_sys->p_this = (*env)->NewGlobalRef(env, thiz);
> +
> +    pthread_mutex_init(&p_sys->p_surf->vout_android_lock, NULL);
> +    pthread_cond_init(&p_sys->p_surf->vout_android_surf_attached, NULL);
> +
> +    setLibVlcSysInstance(env, thiz, p_sys);
> +
>      LOGI("LibVLC initialized: %p", instance);
>  
>      libvlc_log_set(instance, debug_log, &verbosity);
> -
> -    init_native_crash_handler(env, thiz);
>  }
>  
>  void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env, jobject
>  thiz)
>  {
> -    destroy_native_crash_handler(env);
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
> +    if (p_sys == NULL)
> +        return; // Already destroyed
>  
>      releaseMediaPlayer(env, thiz);
> -    jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
> -    if (!libVlcInstance)
> -        return; // Already destroyed
>  
> -    libvlc_instance_t *instance = (libvlc_instance_t*)(intptr_t)
> libVlcInstance;
> +    libvlc_instance_t *instance = p_sys->p_libvlc;
> +    LOGI("LibVLC destroyed: %p", instance);
> +
>      libvlc_log_unset(instance);
>      libvlc_release(instance);
>  
> -    setLong(env, thiz, "mLibVlcInstance", 0);
> -}
> +    (*env)->DeleteGlobalRef(env, p_sys->p_this);
>  
> -void Java_org_videolan_libvlc_LibVLC_detachEventHandler(JNIEnv *env,
> jobject thiz)
> -{
> -    if (eventHandlerInstance != NULL) {
> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
> -        eventHandlerInstance = NULL;
> -    }
> -}
> +    pthread_mutex_destroy(&p_sys->p_surf->vout_android_lock);
> +    pthread_cond_destroy(&p_sys->p_surf->vout_android_surf_attached);
>  
> -void Java_org_videolan_libvlc_LibVLC_setEventHandler(JNIEnv *env,
> jobject thiz, jobject eventHandler)
> -{
> -    if (eventHandlerInstance != NULL) {
> -        (*env)->DeleteGlobalRef(env, eventHandlerInstance);
> -        eventHandlerInstance = NULL;
> -    }
> +    free(p_sys->p_surf);
> +    free(p_sys);
>  
> -    eventHandlerInstance = getEventHandlerReference(env, thiz,
> eventHandler);
> +    setLibVlcSysInstance(env, thiz, NULL);
>  }
>  
>  void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv *env, jobject thiz,
> @@ -411,25 +426,24 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
> *env, jobject thiz,
>      /* Release previous media player, if any */
>      releaseMediaPlayer(env, thiz);
>  
> -    libvlc_instance_t *p_instance = getLibVlcInstance(env, thiz);
> +    libvlc_instance_sys_t *p_sys = getLibVlcSysInstance(env, thiz);
>  
>      /* Create a media player playing environment */
> -    libvlc_media_player_t *mp = libvlc_media_player_new(p_instance);
> -    libvlc_media_player_set_video_title_display(mp,
> libvlc_position_disable, 0);
> -    jobject myJavaLibVLC = (*env)->NewGlobalRef(env, thiz);
> +    p_sys->p_mp = libvlc_media_player_new(p_sys->p_libvlc);
> +
> +    libvlc_media_player_set_video_title_display(p_sys->p_mp,
> libvlc_position_disable, 0);
>  
>      //if AOUT_AUDIOTRACK_JAVA, we use amem
>      jclass cls = (*env)->GetObjectClass(env, thiz);
>      jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout",
>      "()I");
>      if ( (*env)->CallIntMethod(env, thiz, methodId) ==
>      AOUT_AUDIOTRACK_JAVA )
>      {
> -        libvlc_audio_set_callbacks(mp, aout_play, aout_pause, NULL,
> NULL, NULL,
> -                                   (void*) myJavaLibVLC);
> -        libvlc_audio_set_format_callbacks(mp, aout_open, aout_close);
> +        libvlc_audio_set_callbacks(p_sys->p_mp, aout_play, aout_pause,
> NULL, NULL, NULL, p_sys->p_this);
> +        libvlc_audio_set_format_callbacks(p_sys->p_mp, aout_open,
> aout_close);
>      }
>  
>      /* Connect the event manager */
> -    libvlc_event_manager_t *ev = libvlc_media_player_event_manager(mp);
> +    libvlc_event_manager_t *ev =
> libvlc_media_player_event_manager(p_sys->p_mp);
>      static const libvlc_event_type_t mp_events[] = {
>          libvlc_MediaPlayerPlaying,
>          libvlc_MediaPlayerPaused,
> @@ -441,10 +455,7 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
> *env, jobject thiz,
>          libvlc_MediaPlayerEncounteredError
>      };
>      for(int i = 0; i < (sizeof(mp_events) / sizeof(*mp_events)); i++)
> -        libvlc_event_attach(ev, mp_events[i], vlc_event_callback, myVm);
> -
> -    /* Keep a pointer to this media player */
> -    setLong(env, thiz, "mInternalMediaPlayerInstance",
> (jlong)(intptr_t)mp);
> +        libvlc_event_attach(ev, mp_events[i], vlc_event_callback,
> p_sys->p_this);
>  
>      cls = (*env)->GetObjectClass(env, thiz);
>      jmethodID methodID = (*env)->GetMethodID(env, cls, "applyEqualizer",
>      "()V");
> @@ -452,13 +463,16 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
> *env, jobject thiz,
>  
>      const char* p_mrl = (*env)->GetStringUTFChars(env, mrl, 0);
>  
> -    libvlc_media_t* p_md = libvlc_media_new_location(p_instance, p_mrl);
> +    libvlc_media_t* p_md = libvlc_media_new_location(p_sys->p_libvlc,
> p_mrl);
>      /* media options */
>      if (mediaOptions != NULL)
>          add_media_options(p_md, env, mediaOptions);
>  
>      (*env)->ReleaseStringUTFChars(env, mrl, p_mrl);
>  
> +    /* set the Android surface value structure before playing */
> +    libvlc_media_player_set_androidobject(p_sys->p_mp, p_sys->p_surf);
> +
>      /* Connect the media event ma

[A mensagem original inteira não está incluída.]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/android/attachments/20141202/f13b8051/attachment-0001.html>


More information about the Android mailing list