Video not centered in Android SurfaceView with --vout=android-display option
Posted: 10 Mar 2020 00:48
I'm having a strange problem with libvlc version 3.2.5. I'm trying to set the correct aspect ratio by setting the option "--vout=android-display" and then handling the onNewVideoLayout event. Here is how I set the aspect ratio:
The result of this is that for the video is not centered in the SurfaceView. It cuts away some pixels at the left side and on the right side is a small black bar. (On some videos it also cuts away pixels at the top and adds the bar at the bottom) If I remove the -vout=android-display option no pixels are lost, but then the aspect ratio is not correct. Any idea what I'm doing wrong here?
Code: Select all
@Override
public void onNewVideoLayout(IVLCVout vlcVout, int width, int height,
int visibleWidth, int visibleHeight, int sarNum, int sarDen) {
if (PrefStore.getDebugmode(this))
Log.d(BuildConfig.APPLICATION_ID, "onNewVideoLayout");
mVideoWidth = width;
mVideoHeight = height;
mVideoVisibleWidth = visibleWidth;
mVideoVisibleHeight = visibleHeight;
mVideoSarNum = sarNum;
mVideoSarDen = sarDen;
updateVideoSurfaces();
}
private void updateVideoSurfaces() {
CURRENT_SIZE = SURFACE_BEST_FIT;
int sw = getWindow().getDecorView().getWidth();
int sh = getWindow().getDecorView().getHeight();
// sanity check
if (sw * sh == 0) {
Log.e(BuildConfig.APPLICATION_ID, "Invalid surface size");
return;
}
vlcVout.setWindowSize(sw, sh);
ViewGroup.LayoutParams lp = currentVideoSurfaceView.getLayoutParams();
if (mVideoWidth * mVideoHeight == 0) {
/* Case of OpenGL vouts: handles the placement of the video using MediaPlayer API */
lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
currentVideoSurfaceView.setLayoutParams(lp);
changeMediaPlayerLayout(sw, sh);
return;
}
if (lp.width == lp.height && lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
/* We handle the placement of the video using Android View LayoutParams */
vlcPlayer.setAspectRatio(null);
vlcPlayer.setScale(0);
}
double dw = sw, dh = sh;
final boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
if (sw > sh && isPortrait || sw < sh && !isPortrait) {
dw = sh;
dh = sw;
}
// compute the aspect ratio
double ar, vw;
if (mVideoSarDen == mVideoSarNum) {
/* No indication about the density, assuming 1:1 */
vw = mVideoVisibleWidth;
ar = (double)mVideoVisibleWidth / (double)mVideoVisibleHeight;
} else {
/* Use the specified aspect ratio */
vw = mVideoVisibleWidth * (double)mVideoSarNum / mVideoSarDen;
ar = vw / mVideoVisibleHeight;
}
// compute the display aspect ratio
double dar = dw / dh;
if (ar > 1.3 && ar < 1.4)
CURRENT_SIZE = SURFACE_4_3;
else if (ar > 1.7 && ar < 1.8)
CURRENT_SIZE = SURFACE_16_9;
switch (CURRENT_SIZE) {
case SURFACE_BEST_FIT:
if (dar < ar)
dh = dw / ar;
else
dw = dh * ar;
break;
case SURFACE_FIT_SCREEN:
if (dar >= ar)
dh = dw / ar; /* horizontal */
else
dw = dh * ar; /* vertical */
break;
case SURFACE_FILL:
break;
case SURFACE_16_9:
ar = 16.0 / 9.0;
if (dar < ar)
dh = dw / ar;
else
dw = dh * ar;
break;
case SURFACE_4_3:
ar = 4.0 / 3.0;
if (dar < ar)
dh = dw / ar;
else
dw = dh * ar;
break;
case SURFACE_ORIGINAL:
dh = mVideoVisibleHeight;
dw = vw;
break;
}
// set display size
lp.width = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
lp.height = (int) Math.ceil(dh * mVideoHeight / mVideoVisibleHeight);
currentVideoSurfaceView.setLayoutParams(lp);
currentVideoSurfaceView.invalidate();
}