[vlc-devel] [PATCH 11/12] VideoPlayer: Surface size and color is now set from jni

Thomas Guillem thomas at gllm.fr
Fri Nov 14 17:10:26 CET 2014


jni_ConfigureSurface calls VideoPlayerActivity.configureSurface.

configureSurface is only used for gingerbread and before.
After gingerbread, there are fully native way to configure the surface.
---
 libvlc/jni/vout.c                                  |  23 ++++
 libvlc/src/org/videolan/libvlc/IVideoPlayer.java   |  15 +++
 .../vlc/gui/video/VideoPlayerActivity.java         | 122 +++++++++++++--------
 3 files changed, 117 insertions(+), 43 deletions(-)

diff --git a/libvlc/jni/vout.c b/libvlc/jni/vout.c
index 1a8c6a0..6b2c3a7 100644
--- a/libvlc/jni/vout.c
+++ b/libvlc/jni/vout.c
@@ -26,6 +26,7 @@
 #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;
@@ -136,6 +137,28 @@ void *jni_AndroidJavaSurfaceToNativeSurface(jobject *surf)
     return native_surface;
 }
 
+int jni_ConfigureSurface(jobject jsurf, int width, int height, int hal, bool *configured)
+{
+    JNIEnv *p_env;
+    bool isAttached = false;
+    int ret;
+
+    if (jni_get_env(&p_env) < 0) {
+        if (jni_attach_thread(&p_env, THREAD_NAME) < 0)
+            return -1;
+        isAttached = true;
+    }
+    jclass clz = (*p_env)->GetObjectClass (p_env, 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);
+    if (ret >= 0 && configured)
+        *configured = ret == 1;
+
+    if (isAttached)
+        jni_detach_thread();
+    return ret == -1 ? -1 : 0;
+}
+
 bool jni_IsVideoPlayerActivityCreated() {
     pthread_mutex_lock(&vout_android_lock);
     bool result = vout_video_player_activity_created;
diff --git a/libvlc/src/org/videolan/libvlc/IVideoPlayer.java b/libvlc/src/org/videolan/libvlc/IVideoPlayer.java
index 3534426..08ac9ed 100644
--- a/libvlc/src/org/videolan/libvlc/IVideoPlayer.java
+++ b/libvlc/src/org/videolan/libvlc/IVideoPlayer.java
@@ -20,6 +20,8 @@
 
 package org.videolan.libvlc;
 
+import android.view.Surface;
+
 public interface IVideoPlayer {
     /**
      * This method is called by native vout to request a new layout.
@@ -33,6 +35,19 @@ public interface IVideoPlayer {
     void setSurfaceLayout(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den);
 
     /**
+     * This method is only used for Gingerbread and before.
+     * It is called by native vout to request a surface size and hal.
+     * It is synchronous.
+     * @param surface
+     * @param width surface width
+     * @param height surface height
+     * @param hal color format (or PixelFormat)
+     * @return -1 if you should'nt not use this call, 1 if surface size is changed, 0 otherwise
+     */
+    int configureSurface(Surface surface, int width, int height, int hal);
+
+
+    /**
      * Called in case of hardware acceleration error
      */
     public void eventHardwareAccelerationError();
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 e3fbaf8..eb7448e 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -74,7 +74,6 @@ import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.database.Cursor;
 import android.graphics.Color;
-import android.graphics.ImageFormat;
 import android.graphics.PixelFormat;
 import android.media.AudioManager;
 import android.media.AudioManager.OnAudioFocusChangeListener;
@@ -84,6 +83,7 @@ import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Message;
 import android.preference.PreferenceManager;
 import android.provider.MediaStore;
@@ -130,6 +130,8 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
     private SurfaceView mSubtitlesSurfaceView;
     private SurfaceHolder mSurfaceHolder;
     private SurfaceHolder mSubtitlesSurfaceHolder;
+    private Surface mSurface = null;
+    private Surface mSubtitleSurface = null;
     private FrameLayout mSurfaceFrame;
     private MediaRouter mMediaRouter;
     private MediaRouter.SimpleCallback mMediaRouterCallback;
@@ -385,19 +387,11 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
         mSurfaceView = (SurfaceView) findViewById(R.id.player_surface);
         mSurfaceHolder = mSurfaceView.getHolder();
         mSurfaceFrame = (FrameLayout) findViewById(R.id.player_surface_frame);
-        String chroma = mSettings.getString("chroma_format", "");
-        if(LibVlcUtil.isGingerbreadOrLater() && chroma.equals("YV12")) {
-            mSurfaceHolder.setFormat(ImageFormat.YV12);
-        } else if (chroma.equals("RV16")) {
-            mSurfaceHolder.setFormat(PixelFormat.RGB_565);
-        } else {
-            mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
-        }
 
         mSubtitlesSurfaceView = (SurfaceView) findViewById(R.id.subtitles_surface);
         mSubtitlesSurfaceHolder = mSubtitlesSurfaceView.getHolder();
-        mSubtitlesSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
         mSubtitlesSurfaceView.setZOrderMediaOverlay(true);
+        mSubtitlesSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
 
         if (mPresentation == null) {
             mSurfaceHolder.addCallback(mSurfaceCallback);
@@ -868,6 +862,42 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
         mHandler.sendMessage(msg);
     }
 
+    @Override
+    public int configureSurface(final Surface surface, final int width, final int height, final int hal) {
+        if (LibVlcUtil.isHoneycombOrLater() || surface == null)
+            return -1;
+        if (width * height == 0)
+            return 0;
+        Log.d(TAG, "configureSurface: " + width +"x"+height);
+
+        final Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (mSurface == surface && mSurfaceHolder != null) {
+                    mSurfaceHolder.setFormat(hal);
+                    mSurfaceHolder.setFixedSize(width, height);
+                } else if (mSubtitleSurface == surface && mSubtitlesSurfaceHolder != null) {
+                    mSubtitlesSurfaceHolder.setFormat(hal);
+                    mSubtitlesSurfaceHolder.setFixedSize(width, height);
+                }
+
+                synchronized (surface) {
+                    surface.notifyAll();
+                }
+            }
+        });
+
+        try {
+            synchronized (surface) {
+                surface.wait();
+            }
+        } catch (InterruptedException e) {
+            return 0;
+        }
+        return 1;
+    }
+
     /**
      * Lock screen rotation
      */
@@ -1308,28 +1338,18 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
 
         SurfaceView surface;
         SurfaceView subtitlesSurface;
-        SurfaceHolder surfaceHolder;
-        SurfaceHolder subtitlesSurfaceHolder;
         FrameLayout surfaceFrame;
 
         if (mPresentation == null) {
             surface = mSurfaceView;
             subtitlesSurface = mSubtitlesSurfaceView;
-            surfaceHolder = mSurfaceHolder;
-            subtitlesSurfaceHolder = mSubtitlesSurfaceHolder;
             surfaceFrame = mSurfaceFrame;
         } else {
             surface = mPresentation.mSurfaceView;
             subtitlesSurface = mPresentation.mSubtitlesSurfaceView;
-            surfaceHolder = mPresentation.mSurfaceHolder;
-            subtitlesSurfaceHolder = mPresentation.mSubtitlesSurfaceHolder;
             surfaceFrame = mPresentation.mSurfaceFrame;
         }
 
-        // force surface buffer size
-        surfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
-        subtitlesSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
-
         // set display size
         LayoutParams lp = surface.getLayoutParams();
         lp.width  = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
@@ -1825,16 +1845,19 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
     private final SurfaceHolder.Callback mSurfaceCallback = new Callback() {
         @Override
         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            if(format == PixelFormat.RGBX_8888)
-                Log.d(TAG, "Pixel format is RGBX_8888");
-            else if(format == PixelFormat.RGB_565)
-                Log.d(TAG, "Pixel format is RGB_565");
-            else if(format == ImageFormat.YV12)
-                Log.d(TAG, "Pixel format is YV12");
-            else
-                Log.d(TAG, "Pixel format is other/unknown");
-            if(mLibVLC != null)
-                mLibVLC.attachSurface(holder.getSurface(), VideoPlayerActivity.this);
+            if(mLibVLC != null) {
+                final Surface newSurface = holder.getSurface();
+                if (mSurface != newSurface) {
+                    if (mSurface != null) {
+                        synchronized (mSurface) {
+                            mSurface.notifyAll();
+                        }
+                    }
+                    mSurface = newSurface;
+                    Log.d(TAG, "surfaceChanged: " + mSurface);
+                    mLibVLC.attachSurface(mSurface, VideoPlayerActivity.this);
+                }
+            }
         }
 
         @Override
@@ -1843,16 +1866,32 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
 
         @Override
         public void surfaceDestroyed(SurfaceHolder holder) {
-            if(mLibVLC != null)
+            Log.d(TAG, "surfaceDestroyed");
+            if(mLibVLC != null) {
+                synchronized (mSurface) {
+                    mSurface.notifyAll();
+                }
+                mSurface = null;
                 mLibVLC.detachSurface();
+            }
         }
     };
 
     private final SurfaceHolder.Callback mSubtitlesSurfaceCallback = new Callback() {
         @Override
         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-            if(mLibVLC != null)
-                mLibVLC.attachSubtitlesSurface(holder.getSurface());
+            if(mLibVLC != null) {
+                final Surface newSurface = holder.getSurface();
+                if (mSubtitleSurface != newSurface) {
+                    if (mSubtitleSurface != null) {
+                        synchronized (mSubtitleSurface) {
+                            mSubtitleSurface.notifyAll();
+                        }
+                    }
+                    mSubtitleSurface = newSurface;
+                    mLibVLC.attachSubtitlesSurface(mSubtitleSurface);
+                }
+            }
         }
 
         @Override
@@ -1861,8 +1900,13 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
 
         @Override
         public void surfaceDestroyed(SurfaceHolder holder) {
-            if(mLibVLC != null)
+            if(mLibVLC != null) {
+                synchronized (mSubtitleSurface) {
+                    mSubtitleSurface.notifyAll();
+                }
+                mSubtitleSurface = null;
                 mLibVLC.detachSubtitlesSurface();
+            }
         }
     };
 
@@ -2474,14 +2518,6 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
             mSurfaceView = (SurfaceView) findViewById(R.id.remote_player_surface);
             mSurfaceHolder = mSurfaceView.getHolder();
             mSurfaceFrame = (FrameLayout) findViewById(R.id.remote_player_surface_frame);
-            String chroma = mSettings.getString("chroma_format", "");
-            if(LibVlcUtil.isGingerbreadOrLater() && chroma.equals("YV12")) {
-                mSurfaceHolder.setFormat(ImageFormat.YV12);
-            } else if (chroma.equals("RV16")) {
-                mSurfaceHolder.setFormat(PixelFormat.RGB_565);
-            } else {
-                mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
-            }
 
             VideoPlayerActivity activity = (VideoPlayerActivity)getOwnerActivity();
             if (activity == null) {
@@ -2493,8 +2529,8 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
 
             mSubtitlesSurfaceView = (SurfaceView) findViewById(R.id.remote_subtitles_surface);
             mSubtitlesSurfaceHolder = mSubtitlesSurfaceView.getHolder();
-            mSubtitlesSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
             mSubtitlesSurfaceView.setZOrderMediaOverlay(true);
+            mSubtitlesSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
             mSubtitlesSurfaceHolder.addCallback(activity.mSubtitlesSurfaceCallback);
 
             /* Only show the subtitles surface when using "Full Acceleration" mode */
-- 
2.1.1




More information about the vlc-devel mailing list