am 6df5ca08: Merge "Avoid inline->fullscreen reload for html5 video." into jb-dev
* commit '6df5ca08f192e2b831c6cf216f3a2cfe63456ad0': Avoid inline->fullscreen reload for html5 video.
This commit is contained in:
@@ -104,7 +104,9 @@ public class HTML5VideoFullScreen extends HTML5VideoView
|
||||
// After we return from this we can't use the surface any more.
|
||||
// The current Video View will be destroy when we play a new video.
|
||||
pauseAndDispatch(mProxy);
|
||||
// TODO: handle full screen->inline mode transition without a reload.
|
||||
mPlayer.release();
|
||||
mPlayer = null;
|
||||
mSurfaceHolder = null;
|
||||
if (mMediaController != null) {
|
||||
mMediaController.hide();
|
||||
@@ -128,12 +130,12 @@ public class HTML5VideoFullScreen extends HTML5VideoView
|
||||
return mVideoSurfaceView;
|
||||
}
|
||||
|
||||
HTML5VideoFullScreen(Context context, int videoLayerId, int position) {
|
||||
HTML5VideoFullScreen(Context context, int videoLayerId, int position, boolean skipPrepare) {
|
||||
mVideoSurfaceView = new VideoSurfaceView(context);
|
||||
mFullScreenMode = FULLSCREEN_OFF;
|
||||
mVideoWidth = 0;
|
||||
mVideoHeight = 0;
|
||||
init(videoLayerId, position);
|
||||
init(videoLayerId, position, skipPrepare);
|
||||
}
|
||||
|
||||
private void setMediaController(MediaController m) {
|
||||
@@ -156,8 +158,6 @@ public class HTML5VideoFullScreen extends HTML5VideoView
|
||||
}
|
||||
|
||||
private void prepareForFullScreen() {
|
||||
// So in full screen, we reset the MediaPlayer
|
||||
mPlayer.reset();
|
||||
MediaController mc = new FullScreenMediaController(mProxy.getContext(), mLayout);
|
||||
mc.setSystemUiVisibility(mLayout.getSystemUiVisibility());
|
||||
setMediaController(mc);
|
||||
@@ -243,7 +243,7 @@ public class HTML5VideoFullScreen extends HTML5VideoView
|
||||
|
||||
// Don't show the controller after exiting the full screen.
|
||||
mMediaController = null;
|
||||
mCurrentState = STATE_RELEASED;
|
||||
mCurrentState = STATE_RESETTED;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public class HTML5VideoInline extends HTML5VideoView{
|
||||
// associated with the surface texture can be used for showing the screen
|
||||
// shot when paused, so they are not singleton.
|
||||
private static SurfaceTexture mSurfaceTexture = null;
|
||||
private int[] mTextureNames;
|
||||
private static int[] mTextureNames = null;
|
||||
// Every time when the VideoLayer Id change, we need to recreate the
|
||||
// SurfaceTexture in order to delete the old video's decoder memory.
|
||||
private static int mVideoLayerUsingSurfaceTexture = -1;
|
||||
@@ -35,8 +35,7 @@ public class HTML5VideoInline extends HTML5VideoView{
|
||||
}
|
||||
|
||||
HTML5VideoInline(int videoLayerId, int position) {
|
||||
init(videoLayerId, position);
|
||||
mTextureNames = null;
|
||||
init(videoLayerId, position, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,15 +68,14 @@ public class HTML5VideoInline extends HTML5VideoView{
|
||||
|
||||
// Inline Video specific FUNCTIONS:
|
||||
|
||||
@Override
|
||||
public SurfaceTexture getSurfaceTexture(int videoLayerId) {
|
||||
public static SurfaceTexture getSurfaceTexture(int videoLayerId) {
|
||||
// Create the surface texture.
|
||||
if (videoLayerId != mVideoLayerUsingSurfaceTexture
|
||||
|| mSurfaceTexture == null
|
||||
|| mTextureNames == null) {
|
||||
if (mTextureNames != null) {
|
||||
GLES20.glDeleteTextures(1, mTextureNames, 0);
|
||||
}
|
||||
// The GL texture will store in the VideoLayerManager at native side.
|
||||
// They will be clean up when requested.
|
||||
// The reason we recreated GL texture name is for screen shot support.
|
||||
mTextureNames = new int[1];
|
||||
GLES20.glGenTextures(1, mTextureNames, 0);
|
||||
mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
|
||||
|
||||
@@ -31,11 +31,10 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
// NOTE: these values are in sync with VideoLayerAndroid.h in webkit side.
|
||||
// Please keep them in sync when changed.
|
||||
static final int STATE_INITIALIZED = 0;
|
||||
static final int STATE_NOTPREPARED = 1;
|
||||
static final int STATE_PREPARING = 1;
|
||||
static final int STATE_PREPARED = 2;
|
||||
static final int STATE_PLAYING = 3;
|
||||
static final int STATE_RELEASED = 4;
|
||||
protected int mCurrentState;
|
||||
static final int STATE_RESETTED = 4;
|
||||
|
||||
protected HTML5VideoViewProxy mProxy;
|
||||
|
||||
@@ -46,11 +45,11 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
// This is used to find the VideoLayer on the native side.
|
||||
protected int mVideoLayerId;
|
||||
|
||||
// Every video will have one MediaPlayer. Given the fact we only have one
|
||||
// SurfaceTexture, there is only one MediaPlayer in action. Every time we
|
||||
// switch videos, a new instance of MediaPlayer will be created in reset().
|
||||
// Switching between inline and full screen will also create a new instance.
|
||||
protected MediaPlayer mPlayer;
|
||||
// Given the fact we only have one SurfaceTexture, we cannot support multiple
|
||||
// player at the same time. We may recreate a new one and abandon the old
|
||||
// one at transition time.
|
||||
protected static MediaPlayer mPlayer = null;
|
||||
protected static int mCurrentState = -1;
|
||||
|
||||
// We need to save such info.
|
||||
protected Uri mUri;
|
||||
@@ -60,10 +59,12 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
// See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate
|
||||
protected static Timer mTimer;
|
||||
|
||||
protected boolean mPauseDuringPreparing;
|
||||
|
||||
// The spec says the timer should fire every 250 ms or less.
|
||||
private static final int TIMEUPDATE_PERIOD = 250; // ms
|
||||
private boolean mSkipPrepare = false;
|
||||
|
||||
protected boolean mPauseDuringPreparing;
|
||||
// common Video control FUNCTIONS:
|
||||
public void start() {
|
||||
if (mCurrentState == STATE_PREPARED) {
|
||||
@@ -83,7 +84,7 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
public void pause() {
|
||||
if (isPlaying()) {
|
||||
mPlayer.pause();
|
||||
} else if (mCurrentState == STATE_NOTPREPARED) {
|
||||
} else if (mCurrentState == STATE_PREPARING) {
|
||||
mPauseDuringPreparing = true;
|
||||
}
|
||||
// Delete the Timer to stop it since there is no stop call.
|
||||
@@ -124,11 +125,11 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (mCurrentState != STATE_RELEASED) {
|
||||
mPlayer.release();
|
||||
public void reset() {
|
||||
if (mCurrentState != STATE_RESETTED) {
|
||||
mPlayer.reset();
|
||||
}
|
||||
mCurrentState = STATE_RELEASED;
|
||||
mCurrentState = STATE_RESETTED;
|
||||
}
|
||||
|
||||
public void stopPlayback() {
|
||||
@@ -142,9 +143,16 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
}
|
||||
|
||||
// Every time we start a new Video, we create a VideoView and a MediaPlayer
|
||||
public void init(int videoLayerId, int position) {
|
||||
mPlayer = new MediaPlayer();
|
||||
mCurrentState = STATE_INITIALIZED;
|
||||
public void init(int videoLayerId, int position, boolean skipPrepare) {
|
||||
if (mPlayer == null) {
|
||||
mPlayer = new MediaPlayer();
|
||||
mCurrentState = STATE_INITIALIZED;
|
||||
}
|
||||
mSkipPrepare = skipPrepare;
|
||||
// If we want to skip the prepare, then we keep the state.
|
||||
if (!mSkipPrepare) {
|
||||
mCurrentState = STATE_INITIALIZED;
|
||||
}
|
||||
mProxy = null;
|
||||
mVideoLayerId = videoLayerId;
|
||||
mSaveSeekTime = position;
|
||||
@@ -195,17 +203,28 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
}
|
||||
|
||||
public void prepareDataCommon(HTML5VideoViewProxy proxy) {
|
||||
try {
|
||||
mPlayer.setDataSource(proxy.getContext(), mUri, mHeaders);
|
||||
mPlayer.prepareAsync();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
if (!mSkipPrepare) {
|
||||
try {
|
||||
mPlayer.reset();
|
||||
mPlayer.setDataSource(proxy.getContext(), mUri, mHeaders);
|
||||
mPlayer.prepareAsync();
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
mCurrentState = STATE_PREPARING;
|
||||
} else {
|
||||
// If we skip prepare and the onPrepared happened in inline mode, we
|
||||
// don't need to call prepare again, we just need to call onPrepared
|
||||
// to refresh the state here.
|
||||
if (mCurrentState >= STATE_PREPARED) {
|
||||
onPrepared(mPlayer);
|
||||
}
|
||||
mSkipPrepare = false;
|
||||
}
|
||||
mCurrentState = STATE_NOTPREPARED;
|
||||
}
|
||||
|
||||
public void reprepareData(HTML5VideoViewProxy proxy) {
|
||||
@@ -294,10 +313,6 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
public SurfaceTexture getSurfaceTexture(int videoLayerId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void deleteSurfaceTexture() {
|
||||
}
|
||||
|
||||
@@ -332,14 +347,14 @@ public class HTML5VideoView implements MediaPlayer.OnPreparedListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean m_startWhenPrepared = false;
|
||||
private boolean mStartWhenPrepared = false;
|
||||
|
||||
public void setStartWhenPrepared(boolean willPlay) {
|
||||
m_startWhenPrepared = willPlay;
|
||||
mStartWhenPrepared = willPlay;
|
||||
}
|
||||
|
||||
public boolean getStartWhenPrepared() {
|
||||
return m_startWhenPrepared;
|
||||
return mStartWhenPrepared;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -112,13 +112,14 @@ class HTML5VideoViewProxy extends Handler
|
||||
mBaseLayer = layer;
|
||||
|
||||
int currentVideoLayerId = mHTML5VideoView.getVideoLayerId();
|
||||
SurfaceTexture surfTexture = mHTML5VideoView.getSurfaceTexture(currentVideoLayerId);
|
||||
SurfaceTexture surfTexture =
|
||||
HTML5VideoInline.getSurfaceTexture(currentVideoLayerId);
|
||||
int textureName = mHTML5VideoView.getTextureName();
|
||||
|
||||
if (layer != 0 && surfTexture != null && currentVideoLayerId != -1) {
|
||||
int playerState = mHTML5VideoView.getCurrentState();
|
||||
if (mHTML5VideoView.getPlayerBuffering())
|
||||
playerState = HTML5VideoView.STATE_NOTPREPARED;
|
||||
playerState = HTML5VideoView.STATE_PREPARING;
|
||||
boolean foundInTree = nativeSendSurfaceTexture(surfTexture,
|
||||
layer, currentVideoLayerId, textureName,
|
||||
playerState);
|
||||
@@ -145,6 +146,7 @@ class HTML5VideoViewProxy extends Handler
|
||||
HTML5VideoViewProxy proxy, WebViewClassic webView) {
|
||||
// Save the inline video info and inherit it in the full screen
|
||||
int savePosition = 0;
|
||||
boolean canSkipPrepare = false;
|
||||
if (mHTML5VideoView != null) {
|
||||
// We don't allow enter full screen mode while the previous
|
||||
// full screen video hasn't finished yet.
|
||||
@@ -156,15 +158,20 @@ class HTML5VideoViewProxy extends Handler
|
||||
// save the current position.
|
||||
if (layerId == mHTML5VideoView.getVideoLayerId()) {
|
||||
savePosition = mHTML5VideoView.getCurrentPosition();
|
||||
int playerState = mHTML5VideoView.getCurrentState();
|
||||
canSkipPrepare = (playerState == HTML5VideoView.STATE_PREPARING
|
||||
|| playerState == HTML5VideoView.STATE_PREPARED
|
||||
|| playerState == HTML5VideoView.STATE_PLAYING)
|
||||
&& !mHTML5VideoView.isFullScreenMode();
|
||||
}
|
||||
if (!canSkipPrepare) {
|
||||
mHTML5VideoView.reset();
|
||||
}
|
||||
mHTML5VideoView.release();
|
||||
}
|
||||
mHTML5VideoView = new HTML5VideoFullScreen(proxy.getContext(),
|
||||
layerId, savePosition);
|
||||
layerId, savePosition, canSkipPrepare);
|
||||
mCurrentProxy = proxy;
|
||||
|
||||
mHTML5VideoView.setVideoURI(url, mCurrentProxy);
|
||||
|
||||
mHTML5VideoView.enterFullScreenVideoState(layerId, proxy, webView);
|
||||
}
|
||||
|
||||
@@ -217,8 +224,7 @@ class HTML5VideoViewProxy extends Handler
|
||||
if (!backFromFullScreenMode) {
|
||||
mHTML5VideoView.pauseAndDispatch(mCurrentProxy);
|
||||
}
|
||||
// release the media player to avoid finalize error
|
||||
mHTML5VideoView.release();
|
||||
mHTML5VideoView.reset();
|
||||
}
|
||||
mCurrentProxy = proxy;
|
||||
mHTML5VideoView = new HTML5VideoInline(videoLayerId, time);
|
||||
|
||||
Reference in New Issue
Block a user