[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