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:
Teng-Hui Zhu
2012-05-11 10:02:12 -07:00
committed by Android Git Automerger
4 changed files with 74 additions and 55 deletions

View File

@@ -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;
}
};

View File

@@ -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]);

View File

@@ -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;
}
}

View File

@@ -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);