[Android] [PATCH 4/5] Support multiple video player instances.
Paulo Vitor Magacho da Silva
pvmagacho at gmail.com
Fri Jul 25 23:13:23 CEST 2014
Hi,
Thanks for the input.
A few answers.
1- Each instance of the java LibVLC class holds a pointer to the libvlc
instance. So there is no issue here. The main issue was the Surface object.
A static global variable was being used initially. This was solved by
creating android_surf_value_t structure that is attached to each LibVLC
class. This works rather well.
2- Event handling: I see your point. Just need to make it non-static and
add it as instance variable inside the LibVLC class. And pass to
vlc_event_callback data the EventHandler instance pointer.
3- The restartInstance was added to avoid breaking the VLC android
application which still uses a singleton. In the future the VLC android
application will need to refactored.
4- "protected void applyEqualizer()" - This is to allow LibVLC subclassing.
5- synchronized was used around nativeInit and nativeDestroy, but I am not
really sure if it's actually needed. Have to test further as well.
Will continue developing and should post a few more updates on this one.
Thanks
2014-07-25 2:17 GMT-03:00 Edward Wang <edward.c.wang at compdigitec.com>:
> On 2014-07-24 22:14, Paulo Vitor Magacho da Silva <pvmagacho at gmail.com>
> wrote:
>
>> ---
>> vlc-android/jni/libvlcjni.c | 39 ++++--
>> vlc-android/jni/utils.h | 12 ++
>> vlc-android/jni/vout.c | 135
>> +++++++++++----------
>> vlc-android/jni/vout.h | 4 -
>> vlc-android/src/org/videolan/libvlc/LibVLC.java | 33 +++--
>> vlc-android/src/org/videolan/libvlc/MediaList.java | 2 +-
>> .../org/videolan/vlc/gui/PreferencesActivity.java | 2 +-
>> 7 files changed, 139 insertions(+), 88 deletions(-)
>>
>
> Most notably, you have to keep track of which objects belong to which
> libVLC, and that could get messy.
>
> I'd like to test this out first, but that will be for tomorrow.
>
> Some comments inline below.
>
>
>
>> diff --git a/vlc-android/jni/libvlcjni.c b/vlc-android/jni/libvlcjni.c
>> index 6a08d85..1f11b20 100644
>> --- a/vlc-android/jni/libvlcjni.c
>> +++ b/vlc-android/jni/libvlcjni.c
>> @@ -200,16 +200,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 JNI_VERSION_1_2;
>> }
>> 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.");
>> }
>> // FIXME: use atomics
>> @@ -217,6 +213,18 @@ static bool verbosity;
>> void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv *env, jobject
>> thiz)
>> {
>> + android_surf_value_t *object = (android_surf_value_t *)
>> malloc(sizeof(android_surf_value_t));
>>
>
> More descriptive variable name than 'object' possible?
>
>
> +
>> + object->vout_android_surf = NULL;
>> + object->vout_android_gui = NULL;
>> + object->vout_android_java_surf = NULL;
>> + object->vout_android_subtitles_surf = NULL;
>> +
>> + pthread_mutex_init(&object->vout_android_lock, NULL);
>> + pthread_cond_init(&object->vout_android_surf_attached, NULL);
>> +
>> + setLong(env, thiz, "mAndroidSurfaceValue", (jlong)(intptr_t)object);
>> +
>> //only use OpenSLES if java side says we can
>> jclass cls = (*env)->GetObjectClass(env, thiz);
>> jmethodID methodId = (*env)->GetMethodID(env, cls, "getAout",
>> "()I");
>> @@ -318,12 +326,23 @@ void Java_org_videolan_libvlc_LibVLC_nativeInit(JNIEnv
>> *env, jobject thiz)
>> libvlc_log_set(instance, debug_log, &verbosity);
>> - init_native_crash_handler(env, thiz);
>> + // init_native_crash_handler(env, thiz);
>>
>
> Why?
>
>
> }
>> void Java_org_videolan_libvlc_LibVLC_nativeDestroy(JNIEnv *env,
>> jobject thiz)
>> {
>> - destroy_native_crash_handler(env);
>> + // clear surface lock and condition
>> + android_surf_value_t *object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + if (object != NULL) {
>> + pthread_mutex_destroy(&object->vout_android_lock);
>> + pthread_cond_destroy(&object->vout_android_surf_attached);
>> +
>> + free(object);
>> + }
>> + setLong(env, thiz, "mAndroidSurfaceValue", 0);
>> +
>> + // destroy_native_crash_handler(env);
>>
> Ditto.
>
>
> releaseMediaPlayer(env, thiz);
>> jlong libVlcInstance = getLong(env, thiz, "mLibVlcInstance");
>> @@ -413,9 +432,13 @@ void Java_org_videolan_libvlc_LibVLC_playMRL(JNIEnv
>> *env, jobject thiz, jlong in
>> (*env)->ReleaseStringUTFChars(env, option, p_st);
>> }
>> }
>> -
>> +
>>
>
> ?
>
> (*env)->ReleaseStringUTFChars(env, mrl, p_mrl);
>> + // set the Android surface value structure
>> + android_surf_value_t *object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> + libvlc_media_player_set_surfacevalue(mp, object);
>> +
>> /* Connect the media event manager. */
>>
>
> What about events? How does each instance deal with its own events?
>
>
> libvlc_event_manager_t *ev_media = libvlc_media_event_manager(p_
>> md);
>> static const libvlc_event_type_t mp_media_events[] = {
>> diff --git a/vlc-android/jni/utils.h b/vlc-android/jni/utils.h
>> index f8502d9..ccf23aa 100644
>> --- a/vlc-android/jni/utils.h
>> +++ b/vlc-android/jni/utils.h
>> @@ -21,6 +21,18 @@
>> #ifndef LIBVLCJNI_UTILS_H
>> #define LIBVLCJNI_UTILS_H
>> +#include <pthread.h>
>> +
>> +typedef struct android_surf_value_t {
>> + pthread_mutex_t vout_android_lock;
>> + pthread_cond_t vout_android_surf_attached;
>> + void *vout_android_surf;
>> + void *vout_android_gui;
>> + jobject vout_android_java_surf;
>> + jobject vout_android_subtitles_surf;
>> + bool vout_video_player_activity_created;
>> +} android_surf_value_t;
>> +
>> libvlc_media_t *new_media(jlong instance, JNIEnv *env, jobject thiz,
>> jstring fileLocation, bool noOmx, bool noVideo);
>> libvlc_media_player_t *getMediaPlayer(JNIEnv *env, jobject thiz);
>> diff --git a/vlc-android/jni/vout.c b/vlc-android/jni/vout.c
>> index f2f4346..74e1f1e 100644
>> --- a/vlc-android/jni/vout.c
>> +++ b/vlc-android/jni/vout.c
>> @@ -23,96 +23,94 @@
>> #include <jni.h>
>> +#include "utils.h"
>> +
>> /** Unique Java VM instance, as defined in libvlcjni.c */
>> extern JavaVM *myVm;
>> -pthread_mutex_t vout_android_lock;
>> -pthread_cond_t vout_android_surf_attached;
>> -static void *vout_android_surf = NULL;
>> -static void *vout_android_gui = NULL;
>> -static jobject vout_android_java_surf = NULL;
>> -static jobject vout_android_subtitles_surf = NULL;
>> -static bool vout_video_player_activity_created = false;
>> -
>> -void *jni_LockAndGetSubtitlesSurface() {
>> - pthread_mutex_lock(&vout_android_lock);
>> - while (vout_android_subtitles_surf == NULL)
>> - pthread_cond_wait(&vout_android_surf_attached,
>> &vout_android_lock);
>> - return vout_android_subtitles_surf;
>> +void *jni_LockAndGetSubtitlesSurface(android_surf_value_t *object) {
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + while (object->vout_android_subtitles_surf == NULL)
>> + pthread_cond_wait(&object->vout_android_surf_attached,
>> &object->vout_android_lock);
>> + return object->vout_android_subtitles_surf;
>> }
>> -void *jni_LockAndGetAndroidSurface() {
>> - pthread_mutex_lock(&vout_android_lock);
>> - while (vout_android_surf == NULL)
>> - pthread_cond_wait(&vout_android_surf_attached,
>> &vout_android_lock);
>> - return vout_android_surf;
>> +void *jni_LockAndGetAndroidSurface(android_surf_value_t *object) {
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + while (object->vout_android_surf == NULL)
>> + pthread_cond_wait(&object->vout_android_surf_attached,
>> &object->vout_android_lock);
>> + return object->vout_android_surf;
>> }
>> -jobject jni_LockAndGetAndroidJavaSurface() {
>> - pthread_mutex_lock(&vout_android_lock);
>> - while (vout_android_java_surf == NULL)
>> - pthread_cond_wait(&vout_android_surf_attached,
>> &vout_android_lock);
>> - return vout_android_java_surf;
>> +jobject jni_LockAndGetAndroidJavaSurface(android_surf_value_t *object) {
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + while (object->vout_android_java_surf == NULL)
>> + pthread_cond_wait(&object->vout_android_surf_attached,
>> &object->vout_android_lock);
>> + return object->vout_android_java_surf;
>> }
>> -void jni_UnlockAndroidSurface() {
>> - pthread_mutex_unlock(&vout_android_lock);
>> +void jni_UnlockAndroidSurface(android_surf_value_t *object) {
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> -void jni_EventHardwareAccelerationError()
>> +void jni_EventHardwareAccelerationError(android_surf_value_t *object)
>> {
>> - if (vout_android_gui == NULL)
>> + if (object->vout_android_gui == NULL)
>> return;
>> JNIEnv *env;
>> (*myVm)->AttachCurrentThread(myVm, &env, NULL);
>> - jclass cls = (*env)->GetObjectClass(env, vout_android_gui);
>> + jclass cls = (*env)->GetObjectClass(env, object->vout_android_gui);
>> jmethodID methodId = (*env)->GetMethodID(env, cls, "
>> eventHardwareAccelerationError", "()V");
>> - (*env)->CallVoidMethod(env, vout_android_gui, methodId);
>> + (*env)->CallVoidMethod(env, object->vout_android_gui, methodId);
>> (*env)->DeleteLocalRef(env, cls);
>> (*myVm)->DetachCurrentThread(myVm);
>> }
>> -void jni_SetAndroidSurfaceSizeEnv(JNIEnv *p_env, int width, int
>> height, int visible_width, int visible_height, int sar_num, int sar_den)
>> +void jni_SetAndroidSurfaceSizeEnv(JNIEnv *p_env, android_surf_value_t
>> *object, int width, int height, int visible_width, int visible_height, int
>> sar_num, int sar_den)
>> {
>> - if (vout_android_gui == NULL)
>> + if (object->vout_android_gui == NULL)
>> return;
>> - jclass cls = (*p_env)->GetObjectClass (p_env, vout_android_gui);
>> + jclass cls = (*p_env)->GetObjectClass (p_env,
>> object->vout_android_gui);
>> jmethodID methodId = (*p_env)->GetMethodID (p_env, cls,
>> "setSurfaceSize", "(IIIIII)V");
>> - (*p_env)->CallVoidMethod (p_env, vout_android_gui, methodId,
>> width, height, visible_width, visible_height, sar_num, sar_den);
>> + (*p_env)->CallVoidMethod (p_env, object->vout_android_gui, methodId,
>> width, height, visible_width, visible_height, sar_num, sar_den);
>> (*p_env)->DeleteLocalRef(p_env, cls);
>> }
>> -void jni_SetAndroidSurfaceSize(int width, int height, int
>> visible_width, int visible_height, int sar_num, int sar_den)
>> +void jni_SetAndroidSurfaceSize(android_surf_value_t *object, int width,
>> int height, int visible_width, int visible_height, int sar_num, int sar_den)
>> {
>> JNIEnv *p_env;
>> (*myVm)->AttachCurrentThread (myVm, &p_env, NULL);
>> - jni_SetAndroidSurfaceSizeEnv(p_env, width, height, visible_width,
>> visible_height, sar_num, sar_den);
>> + jni_SetAndroidSurfaceSizeEnv(p_env, object, width, height,
>> visible_width, visible_height, sar_num, sar_den);
>> (*myVm)->DetachCurrentThread (myVm);
>> }
>> -bool jni_IsVideoPlayerActivityCreated() {
>> - pthread_mutex_lock(&vout_android_lock);
>> - bool result = vout_video_player_activity_created;
>> - pthread_mutex_unlock(&vout_android_lock);
>> +bool jni_IsVideoPlayerActivityCreated(android_surf_value_t *object) {
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + bool result = object->vout_video_player_activity_created;
>> + pthread_mutex_unlock(&object->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 * object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + object->vout_video_player_activity_created = created;
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> void Java_org_videolan_libvlc_LibVLC_attachSurface(JNIEnv *env,
>> jobject thiz, jobject surf, jobject gui) {
>> - pthread_mutex_lock(&vout_android_lock);
>> + android_surf_value_t * object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + pthread_mutex_lock(&object->vout_android_lock);
>> jclass clz;
>> jfieldID fid;
>> @@ -131,39 +129,46 @@ void Java_org_videolan_libvlc_LibVLC_attachSurface(JNIEnv
>> *env, jobject thiz, jo
>> }
>> fid = (*env)->GetFieldID(env, clz, "mNativeSurface", "I");
>> }
>> - vout_android_surf = (void*)(*env)->GetIntField(env, surf, fid);
>> +
>> + object->vout_android_surf = (void*)(*env)->GetIntField(env,
>> surf, fid);
>> (*env)->DeleteLocalRef(env, clz);
>> }
>> - vout_android_gui = (*env)->NewGlobalRef(env, gui);
>> - vout_android_java_surf = (*env)->NewGlobalRef(env, surf);
>> - pthread_cond_signal(&vout_android_surf_attached);
>> - pthread_mutex_unlock(&vout_android_lock);
>> + object->vout_android_gui = (*env)->NewGlobalRef(env, gui);
>> + object->vout_android_java_surf = (*env)->NewGlobalRef(env, surf);
>> + pthread_cond_signal(&object->vout_android_surf_attached);
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> void Java_org_videolan_libvlc_LibVLC_detachSurface(JNIEnv *env,
>> jobject thiz) {
>> - pthread_mutex_lock(&vout_android_lock);
>> - vout_android_surf = NULL;
>> - if (vout_android_gui != NULL)
>> - (*env)->DeleteGlobalRef(env, vout_android_gui);
>> - if (vout_android_java_surf != NULL)
>> - (*env)->DeleteGlobalRef(env, vout_android_java_surf);
>> - vout_android_gui = NULL;
>> - vout_android_java_surf = NULL;
>> - pthread_mutex_unlock(&vout_android_lock);
>> + android_surf_value_t *object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + object->vout_android_surf = NULL;
>> + if (object->vout_android_gui != NULL)
>> + (*env)->DeleteGlobalRef(env, object->vout_android_gui);
>> + if (object->vout_android_java_surf != NULL)
>> + (*env)->DeleteGlobalRef(env, object->vout_android_java_surf);
>> + object->vout_android_gui = NULL;
>> + object->vout_android_java_surf = NULL;
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> void Java_org_videolan_libvlc_LibVLC_attachSubtitlesSurface(JNIEnv
>> *env, jobject thiz, jobject surf) {
>> - pthread_mutex_lock(&vout_android_lock);
>> - vout_android_subtitles_surf = (*env)->NewGlobalRef(env, surf);
>> - pthread_cond_signal(&vout_android_surf_attached);
>> - pthread_mutex_unlock(&vout_android_lock);
>> + android_surf_value_t *object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + object->vout_android_subtitles_surf = (*env)->NewGlobalRef(env,
>> surf);
>> + pthread_cond_signal(&object->vout_android_surf_attached);
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> void Java_org_videolan_libvlc_LibVLC_detachSubtitlesSurface(JNIEnv
>> *env, jobject thiz) {
>> - pthread_mutex_lock(&vout_android_lock);
>> - (*env)->DeleteGlobalRef(env, vout_android_subtitles_surf);
>> - vout_android_subtitles_surf = NULL;
>> - pthread_mutex_unlock(&vout_android_lock);
>> + android_surf_value_t *object = (android_surf_value_t
>> *)(intptr_t)getLong(env, thiz, "mAndroidSurfaceValue");
>> +
>> + pthread_mutex_lock(&object->vout_android_lock);
>> + (*env)->DeleteGlobalRef(env, object->vout_android_subtitles_surf);
>> + object->vout_android_subtitles_surf = NULL;
>> + pthread_mutex_unlock(&object->vout_android_lock);
>> }
>> static int mouse_x = -1;
>> diff --git a/vlc-android/jni/vout.h b/vlc-android/jni/vout.h
>> index c3d4fd7..d14957a 100644
>> --- a/vlc-android/jni/vout.h
>> +++ b/vlc-android/jni/vout.h
>> @@ -21,8 +21,4 @@
>> #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;
>> -
>> #endif // LIBVLCJNI_VOUT_H
>> diff --git a/vlc-android/src/org/videolan/libvlc/LibVLC.java
>> b/vlc-android/src/org/videolan/libvlc/LibVLC.java
>> index 5ac201e..abc50a7 100644
>> --- a/vlc-android/src/org/videolan/libvlc/LibVLC.java
>> +++ b/vlc-android/src/org/videolan/libvlc/LibVLC.java
>> @@ -51,6 +51,9 @@ public class LibVLC {
>> private int mInternalMediaPlayerIndex = 0; // Read-only, reserved
>> for JNI
>> private long mInternalMediaPlayerInstance = 0; // Read-only,
>> reserved for JNI
>> + private long mAndroidSurfaceValue = 0; // Read-only, reserved for
>> JNI
>> + private long mInternalSurface = 0; // Read-only, reserved for JNI
>> +
>> private MediaList mMediaList; // Pointer to media list being
>> followed
>> private MediaList mPrimaryList; // Primary/default media list; see
>> getPrimaryMediaList()
>> @@ -128,7 +131,7 @@ public class LibVLC {
>> public static LibVLC getInstance() throws LibVlcException {
>> synchronized (LibVLC.class) {
>> if (sInstance == null) {
>> - /* First call */
>> + // First call //
>>
>
> Unneeded change.
>
>
> sInstance = new LibVLC();
>> }
>> }
>> @@ -149,10 +152,9 @@ public class LibVLC {
>> }
>> /**
>> - * Constructor
>> - * It is private because this class is a singleton.
>> + * Constructor.
>> */
>> - private LibVLC() {
>> + public LibVLC() {
>> mAout = new AudioOutput();
>> }
>> @@ -218,7 +220,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();
>> @@ -226,6 +228,15 @@ public class LibVLC {
>> } catch (LibVlcException lve) {
>> Log.e(TAG, "Unable to reinit libvlc: " + lve);
>> }
>> + }
>> + }
>> +
>> + public synchronized void restart(Context context) {
>> + try {
>> + this.destroy();
>> + this.init(context);
>> + } catch (LibVlcException lve) {
>> + Log.e(TAG, "Unable to reinit libvlc: " + lve);
>> }
>> }
>> @@ -341,7 +352,7 @@ public class LibVLC {
>> applyEqualizer();
>> }
>> - private void applyEqualizer()
>> + protected void applyEqualizer()
>>
>
> Why?
>
>
> {
>> setNativeEqualizer(mInternalMediaPlayerInstance,
>> this.equalizer);
>> }
>> @@ -381,7 +392,9 @@ public class LibVLC {
>> File cacheDir = context.getCacheDir();
>> mCachePath = (cacheDir != null) ?
>> cacheDir.getAbsolutePath() : null;
>> - nativeInit();
>> + synchronized (LibVLC.class) {
>> + nativeInit();
>> + }
>>
>
> Why?
>
>
> mMediaList = mPrimaryList = new MediaList(this);
>> setEventHandler(EventHandler.getInstance());
>> mIsInitialized = true;
>> @@ -394,7 +407,9 @@ public class LibVLC {
>> */
>> public void destroy() {
>> Log.v(TAG, "Destroying LibVLC instance");
>> - nativeDestroy();
>> + synchronized (LibVLC.class) {
>> + nativeDestroy();
>> + }
>>
>
> Ditto.
>
>
> detachEventHandler();
>> mIsInitialized = false;
>> }
>> @@ -647,7 +662,7 @@ public class LibVLC {
>> public native int getSpuTracksCount();
>> public static native String nativeToURI(String path);
>> -
>> +
>>
>
> ?
>
> public native static void sendMouseEvent( int action, int button,
>> int x, int y);
>> /**
>> diff --git a/vlc-android/src/org/videolan/libvlc/MediaList.java
>> b/vlc-android/src/org/videolan/libvlc/MediaList.java
>> index 85b2d2a..1889481 100644
>> --- a/vlc-android/src/org/videolan/libvlc/MediaList.java
>> +++ b/vlc-android/src/org/videolan/libvlc/MediaList.java
>> @@ -32,7 +32,7 @@ public class MediaList {
>> /* Since the libvlc_media_t is not created until the media plays,
>> we have
>> * to cache them here. */
>> - private static class MediaHolder {
>> + private class MediaHolder {
>>
>
> Why?
>
>
> Media m;
>> boolean noVideo; // default false
>> boolean noHardwareAcceleration; // default false
>> diff --git a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> index 4c9539f..eedadf5 100644
>> --- a/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> +++ b/vlc-android/src/org/videolan/vlc/gui/PreferencesActivity.java
>> @@ -291,7 +291,7 @@ public class PreferencesActivity extends
>> PreferenceActivity implements OnSharedP
>> || key.equalsIgnoreCase("enable_verbose_mode")
>> || key.equalsIgnoreCase("network_caching")) {
>> VLCInstance.updateLibVlcSettings(sharedPreferences);
>> - LibVLC.restart(this);
>> + LibVLC.restartInstance(this);
>> }
>> }
>>
>>
>
> _______________________________________________
> 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/20140725/fcaaf095/attachment-0001.html>
More information about the Android
mailing list