[Android] [PATCH 3/4] android: allow surface vout per instance

Rafaël Carré funman at videolan.org
Mon Mar 5 00:04:58 CET 2012


From: tewilove <tewilove at gmail.com>

---
 modules/video_output/androidsurface.c |   62 ++++++++++++++++++++++----------
 1 files changed, 42 insertions(+), 20 deletions(-)

diff --git a/modules/video_output/androidsurface.c b/modules/video_output/androidsurface.c
index af2cdc1..ba9e3c8 100644
--- a/modules/video_output/androidsurface.c
+++ b/modules/video_output/androidsurface.c
@@ -64,9 +64,9 @@ vlc_module_end()
  * JNI prototypes
  *****************************************************************************/
 
-extern void *jni_LockAndGetAndroidSurface();
-extern void  jni_UnlockAndroidSurface();
-extern void  jni_SetAndroidSurfaceSize(int width, int height);
+typedef void *(*jni_LockAndGetAndroidSurface_t)(vlc_object_t *);
+typedef void (*jni_UnlockAndroidSurface_t)(vlc_object_t *);
+typedef void (*jni_SetAndroidSurfaceSize_t)(vlc_object_t *, int, int);
 
 // _ZN7android7Surface4lockEPNS0_11SurfaceInfoEb
 typedef void (*Surface_lock)(void *, void *, int);
@@ -90,7 +90,11 @@ struct vout_display_sys_t {
     Surface_lock s_lock;
     Surface_lock2 s_lock2;
     Surface_unlockAndPost s_unlockAndPost;
-
+    void *p_jni;
+    jni_LockAndGetAndroidSurface_t jni_LockAndGetAndroidSurface;
+    jni_UnlockAndroidSurface_t jni_UnlockAndroidSurface;
+    jni_SetAndroidSurfaceSize_t jni_SetAndroidSurfaceSize;
+    vlc_object_t *p_vout;
     picture_resource_t resource;
 };
 
@@ -115,7 +119,18 @@ struct picture_sys_t
 static int  AndroidLockSurface(picture_t *);
 static void AndroidUnlockSurface(picture_t *);
 
-static vlc_mutex_t single_instance = VLC_STATIC_MUTEX;
+static inline void *LoadJNI(const char *psz_lib, vout_display_sys_t *sys) {
+    void *p_library = dlopen(psz_lib, RTLD_NOW);
+    if (p_library) {
+        sys->jni_LockAndGetAndroidSurface = (jni_LockAndGetAndroidSurface_t) dlsym(p_library, "JNI_LockAndGetAndroidSurface");
+        sys->jni_UnlockAndroidSurface = (jni_UnlockAndroidSurface_t) dlsym(p_library, "JNI_UnlockAndroidSurface");
+        sys->jni_SetAndroidSurfaceSize = (jni_SetAndroidSurfaceSize_t) dlsym(p_library, "JNI_SetAndroidSurfaceSize");
+        if (sys->jni_LockAndGetAndroidSurface && sys->jni_UnlockAndroidSurface && sys->jni_SetAndroidSurfaceSize)
+            return p_library;
+        dlclose(p_library);
+    }
+    return NULL;
+}
 
 static inline void *LoadSurface(const char *psz_lib, vout_display_sys_t *sys) {
     void *p_library = dlopen(psz_lib, RTLD_NOW);
@@ -132,6 +147,10 @@ static inline void *LoadSurface(const char *psz_lib, vout_display_sys_t *sys) {
     return NULL;
 }
 
+static void *InitJNI(vout_display_sys_t *sys) {
+    return LoadJNI("libvlcjni.so", sys);
+}
+
 static void *InitLibrary(vout_display_sys_t *sys) {
     void *p_library;
     if ((p_library = LoadSurface("libsurfaceflinger_client.so", sys)))
@@ -145,29 +164,33 @@ static int Open(vlc_object_t *p_this) {
     vout_display_t *vd = (vout_display_t *)p_this;
     vout_display_sys_t *sys;
     void *p_library;
-
-    /* */
-    if (vlc_mutex_trylock(&single_instance) != 0) {
-        msg_Err(vd, "Can't start more than one instance at a time");
-        return VLC_EGENERIC;
-    }
+    void *p_jni;
 
     /* Allocate structure */
     sys = (struct vout_display_sys_t*) calloc(1, sizeof(*sys));
     if (!sys) {
-        vlc_mutex_unlock(&single_instance);
         return VLC_ENOMEM;
     }
 
     /* */
+    sys->p_jni = p_jni = InitJNI(sys);
+    if (!p_jni) {
+        free(sys);
+        msg_Err(vd, "Could not initialize libvlcjni.so!");
+        return VLC_EGENERIC;
+    }
+    /* */
     sys->p_library = p_library = InitLibrary(sys);
     if (!p_library) {
         free(sys);
+        dlclose(p_jni);
         msg_Err(vd, "Could not initialize libui.so/libgui.so/libsurfaceflinger_client.so!");
-        vlc_mutex_unlock(&single_instance);
         return VLC_EGENERIC;
     }
 
+    /* */
+    sys->p_vout = vd->p_parent;
+
     /* Setup chroma */
     video_format_t fmt = vd->fmt;
     fmt.i_chroma = VLC_CODEC_RGB32;
@@ -224,7 +247,6 @@ enomem:
     free(rsc->p_sys);
     free(sys);
     dlclose(p_library);
-    vlc_mutex_unlock(&single_instance);
     return VLC_ENOMEM;
 }
 
@@ -234,8 +256,8 @@ static void Close(vlc_object_t *p_this) {
 
     picture_pool_Delete(sys->pool);
     dlclose(sys->p_library);
+    dlclose(sys->p_jni);
     free(sys);
-    vlc_mutex_unlock(&single_instance);
 }
 
 static picture_pool_t *Pool(vout_display_t *vd, unsigned count) {
@@ -254,11 +276,11 @@ static int  AndroidLockSurface(picture_t *picture) {
     sw = picture->p[0].i_visible_pitch / picture->p[0].i_pixel_pitch;
     sh = picture->p[0].i_visible_lines;
 
-    picsys->surf = surf = jni_LockAndGetAndroidSurface();
+    picsys->surf = surf = sys->jni_LockAndGetAndroidSurface(sys->p_vout);
     info = &(picsys->info);
 
     if (unlikely(!surf)) {
-        jni_UnlockAndroidSurface();
+        sys->jni_UnlockAndroidSurface(sys->p_vout);
         return VLC_EGENERIC;
     }
 
@@ -270,9 +292,9 @@ static int  AndroidLockSurface(picture_t *picture) {
     // input size doesn't match the surface size,
     // request a resize
     if (info->w != sw || info->h != sh) {
-        jni_SetAndroidSurfaceSize(sw, sh);
+        sys->jni_SetAndroidSurfaceSize(sys->p_vout, sw, sh);
         sys->s_unlockAndPost(surf);
-        jni_UnlockAndroidSurface();
+        sys->jni_UnlockAndroidSurface(sys->p_vout);
         return VLC_EGENERIC;
     }
 
@@ -289,7 +311,7 @@ static void AndroidUnlockSurface(picture_t *picture) {
 
     if (likely(picsys->surf))
         sys->s_unlockAndPost(picsys->surf);
-    jni_UnlockAndroidSurface();
+    sys->jni_UnlockAndroidSurface(sys->p_vout);
 }
 
 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) {
-- 
1.7.9


More information about the Android mailing list