[Android] VideoPlayerActivity: handle opengl vout layout

Thomas Guillem git at videolan.org
Mon Nov 28 16:39:16 CET 2016


vlc-android | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Nov 24 16:57:46 2016 +0100| [8680ceebec7660e3fc7546cdca42d74ae8f2f5fc] | committer: Thomas Guillem

VideoPlayerActivity: handle opengl vout layout

> https://code.videolan.org/videolan/vlc-android/commit/8680ceebec7660e3fc7546cdca42d74ae8f2f5fc
---

 vlc-android/res/layout/player.xml                  |   8 +-
 .../src/org/videolan/vlc/PlaybackService.java      |  25 +++++
 .../vlc/gui/video/VideoPlayerActivity.java         | 121 +++++++++++++++++----
 3 files changed, 127 insertions(+), 27 deletions(-)

diff --git a/vlc-android/res/layout/player.xml b/vlc-android/res/layout/player.xml
index 978c5c7..8525061 100644
--- a/vlc-android/res/layout/player.xml
+++ b/vlc-android/res/layout/player.xml
@@ -18,16 +18,16 @@
 
         <FrameLayout
             android:id="@+id/player_surface_frame"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
             android:layout_gravity="center"
             android:foregroundGravity="clip_horizontal|clip_vertical"
             tools:ignore="true">
 
             <SurfaceView
                 android:id="@+id/player_surface"
-                android:layout_width="1dp"
-                android:layout_height="1dp" />
+                android:layout_width="match_parent"
+                android:layout_height="match_parent" />
 
             <SurfaceView
                 android:id="@+id/subtitles_surface"
diff --git a/vlc-android/src/org/videolan/vlc/PlaybackService.java b/vlc-android/src/org/videolan/vlc/PlaybackService.java
index c9fe9bd..784f0e8 100644
--- a/vlc-android/src/org/videolan/vlc/PlaybackService.java
+++ b/vlc-android/src/org/videolan/vlc/PlaybackService.java
@@ -2133,6 +2133,21 @@ public class PlaybackService extends MediaBrowserServiceCompat implements IVLCVo
     }
 
     @MainThread
+    public MediaPlayer.TrackDescription[] getVideoTracks() {
+        return mMediaPlayer.getVideoTracks();
+    }
+
+    @MainThread
+    public Media.VideoTrack getCurrentVideoTrack() {
+        return mMediaPlayer.getCurrentVideoTrack();
+    }
+
+    @MainThread
+    public int getVideoTrack() {
+        return mMediaPlayer.getVideoTrack();
+    }
+
+    @MainThread
     public boolean addSubtitleTrack(String path, boolean select) {
         return mMediaPlayer.addSlave(Media.Slave.Type.Subtitle, path, select);
     }
@@ -2197,6 +2212,16 @@ public class PlaybackService extends MediaBrowserServiceCompat implements IVLCVo
         mMediaPlayer.setEqualizer(equalizer);
     }
 
+    @MainThread
+    public void setVideoScale(float scale) {
+        mMediaPlayer.setScale(scale);
+    }
+
+    @MainThread
+    public void setVideoAspectRatio(String aspect) {
+        mMediaPlayer.setAspectRatio(aspect);
+    }
+
     /**
      * Expand the current media.
      * @return the index of the media was expanded, and -1 if no media was expanded
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 c6b8a90..be6964e 100644
--- a/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
+++ b/vlc-android/src/org/videolan/vlc/gui/video/VideoPlayerActivity.java
@@ -1795,6 +1795,64 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
         exitOK();
     }
 
+    private void changeMediaPlayerLayout(int displayW, int displayH) {
+        /* Change the video placement using MediaPlayer API */
+        switch (mCurrentSize) {
+            case SURFACE_BEST_FIT:
+                mService.setVideoAspectRatio(null);
+                mService.setVideoScale(0);
+                break;
+            case SURFACE_FIT_SCREEN:
+            case SURFACE_FILL: {
+                Media.VideoTrack vtrack = mService.getCurrentVideoTrack();
+                if (vtrack == null)
+                    return;
+                final boolean videoSwapped = vtrack.orientation == Media.VideoTrack.Orientation.LeftBottom
+                        || vtrack.orientation == Media.VideoTrack.Orientation.RightTop;
+                if (mCurrentSize == SURFACE_FIT_SCREEN) {
+                    int videoW = vtrack.width;
+                    int videoH = vtrack.height;
+
+                    if (videoSwapped) {
+                        int swap = videoW;
+                        videoW = videoH;
+                        videoH = swap;
+                    }
+                    if (vtrack.sarNum != vtrack.sarDen)
+                        videoW = videoW * vtrack.sarNum / vtrack.sarDen;
+
+                    float ar = videoW / (float) videoH;
+                    float dar = displayW / (float) displayH;
+
+                    float scale;
+                    if (dar >= ar)
+                        scale = displayW / (float) videoW; /* horizontal */
+                    else
+                        scale = displayH / (float) videoH; /* vertical */
+                    mService.setVideoScale(scale);
+                    mService.setVideoAspectRatio(null);
+                } else {
+                    mService.setVideoScale(0);
+                    mService.setVideoAspectRatio(!videoSwapped ? ""+displayW+":"+displayH
+                                                               : ""+displayH+":"+displayW);
+                }
+                break;
+            }
+            case SURFACE_16_9:
+                mService.setVideoAspectRatio("16:9");
+                mService.setVideoScale(0);
+                break;
+            case SURFACE_4_3:
+                mService.setVideoAspectRatio("4:3");
+                mService.setVideoScale(0);
+                break;
+            case SURFACE_ORIGINAL:
+                mService.setVideoAspectRatio(null);
+                mService.setVideoScale(1);
+                break;
+        }
+    }
+
     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
     private void changeSurfaceLayout() {
         int sw;
@@ -1809,11 +1867,51 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
             sh = mPresentation.getWindow().getDecorView().getHeight();
         }
 
+        // sanity check
+        if (sw * sh == 0) {
+            Log.e(TAG, "Invalid surface size");
+            return;
+        }
+
         if (mService != null) {
             final IVLCVout vlcVout = mService.getVLCVout();
             vlcVout.setWindowSize(sw, sh);
         }
 
+        SurfaceView surface;
+        SurfaceView subtitlesSurface;
+        FrameLayout surfaceFrame;
+        if (mPresentation == null) {
+            surface = mSurfaceView;
+            subtitlesSurface = mSubtitlesSurfaceView;
+            surfaceFrame = mSurfaceFrame;
+        } else {
+            surface = mPresentation.mSurfaceView;
+            subtitlesSurface = mPresentation.mSubtitlesSurfaceView;
+            surfaceFrame = mPresentation.mSurfaceFrame;
+        }
+        LayoutParams lp = surface.getLayoutParams();
+
+        if (mVideoWidth * mVideoHeight == 0) {
+            /* Case of OpenGL vouts: handles the placement of the video using MediaPlayer API */
+            lp.width  = LayoutParams.MATCH_PARENT;
+            lp.height = LayoutParams.MATCH_PARENT;
+            surface.setLayoutParams(lp);
+            lp = surfaceFrame.getLayoutParams();
+            lp.width  = LayoutParams.MATCH_PARENT;
+            lp.height = LayoutParams.MATCH_PARENT;
+            surfaceFrame.setLayoutParams(lp);
+            if (mService != null)
+                changeMediaPlayerLayout(sw, sh);
+            return;
+        }
+
+        if (mService != null && lp.width == lp.height && lp.width == LayoutParams.MATCH_PARENT) {
+            /* We handle the placement of the video using Android View LayoutParams */
+            mService.setVideoAspectRatio(null);
+            mService.setVideoScale(0);
+        }
+
         double dw = sw, dh = sh;
         boolean isPortrait;
 
@@ -1829,12 +1927,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
             dh = sw;
         }
 
-        // sanity check
-        if (dw * dh == 0 || mVideoWidth * mVideoHeight == 0) {
-            Log.e(TAG, "Invalid surface size");
-            return;
-        }
-
         // compute the aspect ratio
         double ar, vw;
         if (mSarDen == mSarNum) {
@@ -1885,21 +1977,7 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
                 break;
         }
 
-        SurfaceView surface;
-        SurfaceView subtitlesSurface;
-        FrameLayout surfaceFrame;
-        if (mPresentation == null) {
-            surface = mSurfaceView;
-            subtitlesSurface = mSubtitlesSurfaceView;
-            surfaceFrame = mSurfaceFrame;
-        } else {
-            surface = mPresentation.mSurfaceView;
-            subtitlesSurface = mPresentation.mSubtitlesSurfaceView;
-            surfaceFrame = mPresentation.mSurfaceFrame;
-        }
-
         // set display size
-        LayoutParams lp = surface.getLayoutParams();
         lp.width  = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
         lp.height = (int) Math.ceil(dh * mVideoHeight / mVideoVisibleHeight);
         surface.setLayoutParams(lp);
@@ -3464,9 +3542,6 @@ public class VideoPlayerActivity extends AppCompatActivity implements IVLCVout.C
 
     @Override
     public void onNewLayout(IVLCVout vlcVout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen) {
-        if (width * height == 0)
-            return;
-
         // store video size
         mVideoWidth = width;
         mVideoHeight = height;



More information about the Android mailing list