Commit 636e7237 authored by flx42's avatar flx42 Committed by Jean-Baptiste Kempf
Browse files

Add a SurfaceView for rendering subtitles above the current player surface



This additional surface is needed when using opaque MediaCodec direct
rendering since the main surface is owned by MediaCodec and cannot be
used for blending or with OpenGL ES.

If this HW acceleration mode is disabled, the visibility of this
surface is set to INVISIBLE since overlaying a transparent SurfaceView
on top of another might not be supported on all devices.
Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 51bd3fa5
......@@ -31,6 +31,14 @@ 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;
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_LockAndGetAndroidSurface() {
pthread_mutex_lock(&vout_android_lock);
......@@ -113,3 +121,17 @@ void Java_org_videolan_libvlc_LibVLC_detachSurface(JNIEnv *env, jobject thiz) {
vout_android_java_surf = NULL;
pthread_mutex_unlock(&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);
}
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);
}
......@@ -24,6 +24,11 @@
android:id="@+id/player_surface"
android:layout_width="1dp"
android:layout_height="1dp" />
<SurfaceView
android:id="@+id/subtitles_surface"
android:layout_width="1dp"
android:layout_height="1dp"
android:visibility="invisible" />
</FrameLayout>
</FrameLayout>
......
......@@ -76,6 +76,9 @@ public class LibVLC {
public native void detachSurface();
public native void attachSubtitlesSurface(Surface surface);
public native void detachSubtitlesSurface();
/* Load library before object instantiation */
static {
try {
......
......@@ -107,7 +107,9 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
private final static String PLAY_FROM_VIDEOGRID = "org.videolan.vlc.gui.video.PLAY_FROM_VIDEOGRID";
private SurfaceView mSurface;
private SurfaceView mSubtitlesSurface;
private SurfaceHolder mSurfaceHolder;
private SurfaceHolder mSubtitlesSurfaceHolder;
private FrameLayout mSurfaceFrame;
private LibVLC mLibVLC;
private String mLocation;
......@@ -282,6 +284,12 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
}
mSurfaceHolder.addCallback(mSurfaceCallback);
mSubtitlesSurface = (SurfaceView) findViewById(R.id.subtitles_surface);
mSubtitlesSurfaceHolder = mSubtitlesSurface.getHolder();
mSubtitlesSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
mSubtitlesSurface.setZOrderMediaOverlay(true);
mSubtitlesSurfaceHolder.addCallback(mSubtitlesSurfaceCallback);
mSeekbar = (SeekBar) findViewById(R.id.player_overlay_seekbar);
mSeekbar.setOnSeekBarChangeListener(mSeekListener);
......@@ -313,6 +321,9 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
Log.d(TAG, "LibVLC initialisation failed");
return;
}
/* Only show the subtitles surface when using "Full Acceleration" mode */
if (mLibVLC.getHardwareAcceleration() == 2)
mSubtitlesSurface.setVisibility(View.VISIBLE);
EventHandler em = EventHandler.getInstance();
em.addHandler(eventHandler);
......@@ -874,12 +885,14 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
// force surface buffer size
mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
mSubtitlesSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
// set display size
LayoutParams lp = mSurface.getLayoutParams();
lp.width = (int) Math.ceil(dw * mVideoWidth / mVideoVisibleWidth);
lp.height = (int) Math.ceil(dh * mVideoHeight / mVideoVisibleHeight);
mSurface.setLayoutParams(lp);
mSubtitlesSurface.setLayoutParams(lp);
// set frame size (crop if necessary)
lp = mSurfaceFrame.getLayoutParams();
......@@ -888,6 +901,7 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
mSurfaceFrame.setLayoutParams(lp);
mSurface.invalidate();
mSubtitlesSurface.invalidate();
}
/**
......@@ -1313,6 +1327,22 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
}
};
private final SurfaceHolder.Callback mSubtitlesSurfaceCallback = new Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mLibVLC.attachSubtitlesSurface(holder.getSurface());
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mLibVLC.detachSubtitlesSurface();
}
};
/**
* show overlay the the default timeout
*/
......@@ -1377,11 +1407,12 @@ public class VideoPlayerActivity extends Activity implements IVideoPlayer {
int layout = 0;
if (!Util.hasCombBar() && Util.isJellyBeanOrLater())
layout = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
mSurface.setSystemUiVisibility(
(dim ? (Util.hasCombBar()
? View.SYSTEM_UI_FLAG_LOW_PROFILE
int visibility = (dim ? (Util.hasCombBar()
? View.SYSTEM_UI_FLAG_LOW_PROFILE
: View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
: View.SYSTEM_UI_FLAG_VISIBLE) | layout);
: View.SYSTEM_UI_FLAG_VISIBLE) | layout;
mSurface.setSystemUiVisibility(visibility);
mSubtitlesSurface.setSystemUiVisibility(visibility);
}
private void updateOverlayPausePlay() {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment