зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1379856 - Provide a HandlerThread for GeckoHlsPlayer instead of using Gecko's MainThread. r=jolin
Gecko's mainthread message queue is getting more tasks along with each creation of GeckoHlsPlayer. We should avoid adding extra work load to gecko's main thread. MozReview-Commit-ID: 2c5fnmG2hfS --HG-- extra : rebase_source : 892290a6e4d2c9b120b6dec9d0aae51d0dc0c05d
This commit is contained in:
Родитель
9a920e6268
Коммит
cd0796d840
|
@ -7,6 +7,7 @@ package org.mozilla.gecko.media;
|
|||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.android.exoplayer2.C;
|
||||
|
@ -63,6 +64,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
private DataSource.Factory mMediaDataSourceFactory;
|
||||
|
||||
private Handler mMainHandler;
|
||||
private HandlerThread mThread;
|
||||
private ExoPlayer mPlayer;
|
||||
private GeckoHlsRendererBase[] mRenderers;
|
||||
private DefaultTrackSelector mTrackSelector;
|
||||
|
@ -70,7 +72,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
private ComponentListener mComponentListener;
|
||||
private ComponentEventDispatcher mComponentEventDispatcher;
|
||||
|
||||
private boolean mIsTimelineStatic = false;
|
||||
private volatile boolean mIsTimelineStatic = false;
|
||||
private long mDurationUs;
|
||||
|
||||
private GeckoHlsVideoRenderer mVRenderer = null;
|
||||
|
@ -156,6 +158,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
|
||||
public final class ComponentEventDispatcher {
|
||||
// Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer/ExoPlayer
|
||||
public void onDataArrived(final int trackType) {
|
||||
assertTrue(mMainHandler != null);
|
||||
assertTrue(mComponentListener != null);
|
||||
|
@ -172,6 +175,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer
|
||||
public void onVideoInputFormatChanged(final Format format) {
|
||||
assertTrue(mMainHandler != null);
|
||||
assertTrue(mComponentListener != null);
|
||||
|
@ -188,6 +192,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer
|
||||
public void onAudioInputFormatChanged(final Format format) {
|
||||
assertTrue(mMainHandler != null);
|
||||
assertTrue(mComponentListener != null);
|
||||
|
@ -208,6 +213,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
public final class ComponentListener {
|
||||
|
||||
// General purpose implementation
|
||||
// Called on GeckoHlsPlayerThread
|
||||
public void onDataArrived(int trackType) {
|
||||
synchronized (GeckoHlsPlayer.this) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "[CB][onDataArrived] id " + mPlayerId); }
|
||||
|
@ -228,6 +234,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread
|
||||
public void onVideoInputFormatChanged(Format format) {
|
||||
synchronized (GeckoHlsPlayer.this) {
|
||||
if (DEBUG) {
|
||||
|
@ -250,6 +257,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread
|
||||
public void onAudioInputFormatChanged(Format format) {
|
||||
synchronized (GeckoHlsPlayer.this) {
|
||||
if (DEBUG) {
|
||||
|
@ -305,23 +313,27 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
// Should be only called by GeckoPlayerFactory and GeckoHLSResourceWrapper.
|
||||
// The mPlayerId is used to make sure that the same GeckoHlsPlayer is used by
|
||||
// corresponding HLSResource and HLSDemuxer for each media playback.
|
||||
// Called on Gecko's main thread
|
||||
@Override
|
||||
public int getId() {
|
||||
return mPlayerId;
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread
|
||||
@Override
|
||||
public void addResourceWrapperCallbackListener(BaseHlsPlayer.ResourceCallbacks callback) {
|
||||
if (DEBUG) { Log.d(LOGTAG, " addResourceWrapperCallbackListener ..."); }
|
||||
mResourceCallbacks = callback;
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread
|
||||
@Override
|
||||
public void addDemuxerWrapperCallbackListener(BaseHlsPlayer.DemuxerCallbacks callback) {
|
||||
if (DEBUG) { Log.d(LOGTAG, " addDemuxerWrapperCallbackListener ..."); }
|
||||
mDemuxerCallbacks = callback;
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public synchronized void onLoadingChanged(boolean isLoading) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "loading [" + isLoading + "]"); }
|
||||
|
@ -331,6 +343,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public synchronized void onPlayerStateChanged(boolean playWhenReady, int state) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "state [" + playWhenReady + ", " + getStateString(state) + "]"); }
|
||||
|
@ -339,11 +352,13 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public void onPositionDiscontinuity() {
|
||||
if (DEBUG) { Log.d(LOGTAG, "positionDiscontinuity"); }
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
|
||||
if (DEBUG) {
|
||||
|
@ -352,6 +367,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public synchronized void onPlayerError(ExoPlaybackException e) {
|
||||
if (DEBUG) { Log.e(LOGTAG, "playerFailed" , e); }
|
||||
|
@ -364,6 +380,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public synchronized void onTracksChanged(TrackGroupArray ignored, TrackSelectionArray trackSelections) {
|
||||
if (DEBUG) {
|
||||
|
@ -442,6 +459,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
mTracksInfo = new HlsMediaTracksInfo(numVideoTracks, numAudioTracks);
|
||||
}
|
||||
|
||||
// Called on GeckoHlsPlayerThread from ExoPlayer
|
||||
@Override
|
||||
public synchronized void onTimelineChanged(Timeline timeline, Object manifest) {
|
||||
// For now, we use the interface ExoPlayer.getDuration() for gecko,
|
||||
|
@ -534,21 +552,11 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return enabled ? "[X]" : "[ ]";
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// API for GeckoHLSResourceWrapper
|
||||
// =======================================================================
|
||||
@Override
|
||||
public synchronized void init(String url) {
|
||||
if (DEBUG) { Log.d(LOGTAG, " init"); }
|
||||
assertTrue(mResourceCallbacks != null);
|
||||
if (mIsPlayerInitDone) {
|
||||
return;
|
||||
}
|
||||
// Called on GeckoHlsPlayerThread
|
||||
private synchronized void createExoPlayer(final String url) {
|
||||
Context ctx = GeckoAppShell.getApplicationContext();
|
||||
mComponentListener = new ComponentListener();
|
||||
mComponentEventDispatcher = new ComponentEventDispatcher();
|
||||
mMainHandler = new Handler();
|
||||
|
||||
mDurationUs = 0;
|
||||
|
||||
// Prepare trackSelector
|
||||
|
@ -578,15 +586,37 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
mPlayer.prepare(mMediaSource);
|
||||
mIsPlayerInitDone = true;
|
||||
}
|
||||
// =======================================================================
|
||||
// API for GeckoHLSResourceWrapper
|
||||
// =======================================================================
|
||||
// Called on Gecko Main Thread
|
||||
@Override
|
||||
public synchronized void init(final String url) {
|
||||
if (DEBUG) { Log.d(LOGTAG, " init"); }
|
||||
assertTrue(mResourceCallbacks != null);
|
||||
assertTrue(!mIsPlayerInitDone);
|
||||
|
||||
mThread = new HandlerThread("GeckoHlsPlayerThread");
|
||||
mThread.start();
|
||||
mMainHandler = new Handler(mThread.getLooper());
|
||||
|
||||
mMainHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
createExoPlayer(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Called on MDSM's TaskQueue
|
||||
@Override
|
||||
public boolean isLiveStream() {
|
||||
return !mIsTimelineStatic;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// API for GeckoHLSDemuxerWrapper
|
||||
// =======================================================================
|
||||
// Called on HLSDemuxer's TaskQueue
|
||||
@Override
|
||||
public ConcurrentLinkedQueue<GeckoHLSSample> getSamples(TrackType trackType,
|
||||
int number) {
|
||||
|
@ -601,6 +631,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
}
|
||||
}
|
||||
|
||||
// Called on MFR's TaskQueue
|
||||
@Override
|
||||
public synchronized long getBufferedPosition() {
|
||||
// Value returned by getBufferedPosition() is in milliseconds.
|
||||
|
@ -609,6 +640,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return bufferedPos;
|
||||
}
|
||||
|
||||
// Called on MFR's TaskQueue
|
||||
@Override
|
||||
public synchronized int getNumberOfTracks(TrackType trackType) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "getNumberOfTracks : type " + trackType); }
|
||||
|
@ -622,6 +654,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Called on MFR's TaskQueue
|
||||
@Override
|
||||
public GeckoVideoInfo getVideoInfo(int index) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "getVideoInfo"); }
|
||||
|
@ -642,6 +675,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return vInfo;
|
||||
}
|
||||
|
||||
// Called on MFR's TaskQueue
|
||||
@Override
|
||||
public GeckoAudioInfo getAudioInfo(int index) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "getAudioInfo"); }
|
||||
|
@ -670,6 +704,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return aInfo;
|
||||
}
|
||||
|
||||
// Called on HLSDemuxer's TaskQueue
|
||||
@Override
|
||||
public synchronized boolean seek(long positionUs) {
|
||||
// positionUs : microseconds.
|
||||
|
@ -703,6 +738,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Called on HLSDemuxer's TaskQueue
|
||||
@Override
|
||||
public long getNextKeyFrameTime() {
|
||||
long nextKeyFrameTime = mVRenderer != null
|
||||
|
@ -711,6 +747,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
return nextKeyFrameTime;
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread, when HLSDemuxer or HLSResource destructs.
|
||||
@Override
|
||||
public synchronized void release() {
|
||||
if (DEBUG) { Log.d(LOGTAG, "releasing ... id : " + mPlayerId); }
|
||||
|
@ -722,6 +759,10 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
mARenderer = null;
|
||||
mPlayer = null;
|
||||
}
|
||||
if (mThread != null) {
|
||||
mThread.quit();
|
||||
mThread = null;
|
||||
}
|
||||
mDemuxerCallbacks = null;
|
||||
mResourceCallbacks = null;
|
||||
mIsPlayerInitDone = false;
|
||||
|
|
Загрузка…
Ссылка в новой задаче