Bug 1418766 - Fix Crash in java.lang.OutOfMemoryError by making Exoplayer pause by default.
MozReview-Commit-ID: JGIRcYLXtdv
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
@@ -56,17 +56,25 @@ public class GeckoHlsPlayer implements B
* It will be created and initialized with a URL by HLSResource in
* Gecko media pipleine (in cpp). Once HLSDemuxer is created later, we
* need to bridge this HLSResource to the created demuxer. And they share
* the same GeckoHlsPlayer.
* mPlayerId is a token used for Gecko media pipeline to obtain corresponding player.
*/
private final int mPlayerId;
private boolean mExoplayerSuspended = false;
- private boolean mMediaElementSuspended = false;
+
+ private enum MediaDecoderPlayState{
+ PLAY_STATE_PREPARING,
+ PLAY_STATE_PAUSED,
+ PLAY_STATE_PLAYING
+ }
+ // Default value is PLAY_STATE_PREPARING and it will be set to PLAY_STATE_PLAYING
+ // once HTMLMediaElement calls PlayInternal().
+ private MediaDecoderPlayState mMediaDecoderPlayState = MediaDecoderPlayState.PLAY_STATE_PREPARING;
private DataSource.Factory mMediaDataSourceFactory;
private Handler mMainHandler;
private HandlerThread mThread;
private ExoPlayer mPlayer;
private GeckoHlsRendererBase[] mRenderers;
private DefaultTrackSelector mTrackSelector;
private MediaSource mMediaSource;
@@ -308,29 +316,31 @@ public class GeckoHlsPlayer implements B
mDemuxerCallbacks = callback;
}
// Called on GeckoHlsPlayerThread from ExoPlayer
@Override
public synchronized void onLoadingChanged(boolean isLoading) {
if (DEBUG) { Log.d(LOGTAG, "loading [" + isLoading + "]"); }
if (!isLoading) {
- if (mMediaElementSuspended) {
+ if (mMediaDecoderPlayState != MediaDecoderPlayState.PLAY_STATE_PLAYING) {
suspendExoplayer();
}
// To update buffered position.
mComponentEventDispatcher.onDataArrived(C.TRACK_TYPE_DEFAULT);
}
}
// Called on GeckoHlsPlayerThread from ExoPlayer
@Override
public synchronized void onPlayerStateChanged(boolean playWhenReady, int state) {
if (DEBUG) { Log.d(LOGTAG, "state [" + playWhenReady + ", " + getStateString(state) + "]"); }
- if (state == ExoPlayer.STATE_READY && !mExoplayerSuspended && !mMediaElementSuspended) {
+ if (state == ExoPlayer.STATE_READY &&
+ !mExoplayerSuspended &&
+ mMediaDecoderPlayState == MediaDecoderPlayState.PLAY_STATE_PLAYING) {
resumeExoplayer();
}
}
// Called on GeckoHlsPlayerThread from ExoPlayer
@Override
public void onPositionDiscontinuity() {
if (DEBUG) { Log.d(LOGTAG, "positionDiscontinuity"); }
@@ -556,17 +566,17 @@ public class GeckoHlsPlayer implements B
Uri uri = Uri.parse(url);
mMediaDataSourceFactory = buildDataSourceFactory(ctx, BANDWIDTH_METER);
mMediaSource = new HlsMediaSource(uri, mMediaDataSourceFactory, mMainHandler, null);
if (DEBUG) {
Log.d(LOGTAG, "Uri is " + uri +
", ContentType is " + Util.inferContentType(uri.getLastPathSegment()));
}
-
+ mPlayer.setPlayWhenReady(false);
mPlayer.prepare(mMediaSource);
mIsPlayerInitDone = true;
}
// =======================================================================
// API for GeckoHLSResourceWrapper
// =======================================================================
// Called on Gecko Main Thread
@Override
@@ -735,57 +745,57 @@ public class GeckoHlsPlayer implements B
}
// Called on Gecko's main thread.
@Override
public synchronized void suspend() {
if (mExoplayerSuspended) {
return;
}
- if (mMediaElementSuspended) {
+ if (mMediaDecoderPlayState != MediaDecoderPlayState.PLAY_STATE_PLAYING) {
if (DEBUG) {
Log.d(LOGTAG, "suspend player id : " + mPlayerId);
}
suspendExoplayer();
}
}
// Called on Gecko's main thread.
@Override
public synchronized void resume() {
if (!mExoplayerSuspended) {
return;
}
- if (!mMediaElementSuspended) {
+ if (mMediaDecoderPlayState == MediaDecoderPlayState.PLAY_STATE_PLAYING) {
if (DEBUG) {
Log.d(LOGTAG, "resume player id : " + mPlayerId);
}
resumeExoplayer();
}
}
// Called on Gecko's main thread.
@Override
public synchronized void play() {
- if (!mMediaElementSuspended) {
+ if (mMediaDecoderPlayState == MediaDecoderPlayState.PLAY_STATE_PLAYING) {
return;
}
- if (DEBUG) { Log.d(LOGTAG, "mediaElement played."); }
- mMediaElementSuspended = false;
+ if (DEBUG) { Log.d(LOGTAG, "MediaDecoder played."); }
+ mMediaDecoderPlayState = MediaDecoderPlayState.PLAY_STATE_PLAYING;
resumeExoplayer();
}
// Called on Gecko's main thread.
@Override
public synchronized void pause() {
- if (mMediaElementSuspended) {
+ if (mMediaDecoderPlayState != MediaDecoderPlayState.PLAY_STATE_PLAYING) {
return;
}
- if (DEBUG) { Log.d(LOGTAG, "mediaElement paused."); }
- mMediaElementSuspended = true;
+ if (DEBUG) { Log.d(LOGTAG, "MediaDecoder paused."); }
+ mMediaDecoderPlayState = MediaDecoderPlayState.PLAY_STATE_PAUSED;
suspendExoplayer();
}
private synchronized void suspendExoplayer() {
if (mPlayer != null) {
mExoplayerSuspended = true;
if (DEBUG) { Log.d(LOGTAG, "suspend Exoplayer"); }
mPlayer.setPlayWhenReady(false);