зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382151 - Pause Exoplayer when mediaelement is paused. r=kikuo
MozReview-Commit-ID: 5MDBBP5vfpa --HG-- extra : rebase_source : 9981585791cd359296ac7fef0fe0d7e900af6c61
This commit is contained in:
Родитель
4e4645bdba
Коммит
4843d195fb
|
@ -93,4 +93,26 @@ HLSDecoder::Load(MediaResource*)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HLSDecoder::Play()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
HLS_DEBUG("HLSDecoder", "MediaElement called Play");
|
||||
auto resourceWrapper =
|
||||
static_cast<HLSResource*>(GetResource())->GetResourceWrapper();
|
||||
resourceWrapper->Play();
|
||||
return MediaDecoder::Play();
|
||||
}
|
||||
|
||||
void
|
||||
HLSDecoder::Pause()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
HLS_DEBUG("HLSDecoder", "MediaElement called Pause");
|
||||
auto resourceWrapper =
|
||||
static_cast<HLSResource*>(GetResource())->GetResourceWrapper();
|
||||
resourceWrapper->Pause();
|
||||
return MediaDecoder::Pause();
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -37,6 +37,10 @@ public:
|
|||
bool aIsPrivateBrowsing,
|
||||
nsIStreamListener**) override;
|
||||
nsresult Load(MediaResource*) override;
|
||||
|
||||
nsresult Play() override;
|
||||
|
||||
void Pause() override;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -88,5 +88,9 @@ public interface BaseHlsPlayer {
|
|||
|
||||
public void resume();
|
||||
|
||||
public void play();
|
||||
|
||||
public void pause();
|
||||
|
||||
public void release();
|
||||
}
|
|
@ -79,6 +79,22 @@ public class GeckoHLSResourceWrapper {
|
|||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
public void play() {
|
||||
if (DEBUG) Log.d(LOGTAG, "GeckoHLSResourceWrapper mediaelement played");
|
||||
if (mPlayer != null) {
|
||||
mPlayer.play();
|
||||
}
|
||||
}
|
||||
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
public void pause() {
|
||||
if (DEBUG) Log.d(LOGTAG, "GeckoHLSResourceWrapper mediaelement paused");
|
||||
if (mPlayer != null) {
|
||||
mPlayer.pause();
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertTrue(boolean condition) {
|
||||
if (DEBUG && !condition) {
|
||||
throw new AssertionError("Expected condition to be true");
|
||||
|
|
|
@ -60,7 +60,8 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
* mPlayerId is a token used for Gecko media pipeline to obtain corresponding player.
|
||||
*/
|
||||
private final int mPlayerId;
|
||||
private volatile boolean mSuspended = false;
|
||||
private boolean mExoplayerSuspended = false;
|
||||
private boolean mMediaElementSuspended = false;
|
||||
private DataSource.Factory mMediaDataSourceFactory;
|
||||
|
||||
private Handler mMainHandler;
|
||||
|
@ -312,6 +313,9 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
public synchronized void onLoadingChanged(boolean isLoading) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "loading [" + isLoading + "]"); }
|
||||
if (!isLoading) {
|
||||
if (mMediaElementSuspended) {
|
||||
suspendExoplayer();
|
||||
}
|
||||
// To update buffered position.
|
||||
mComponentEventDispatcher.onDataArrived(C.TRACK_TYPE_DEFAULT);
|
||||
}
|
||||
|
@ -321,8 +325,8 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
@Override
|
||||
public synchronized void onPlayerStateChanged(boolean playWhenReady, int state) {
|
||||
if (DEBUG) { Log.d(LOGTAG, "state [" + playWhenReady + ", " + getStateString(state) + "]"); }
|
||||
if (state == ExoPlayer.STATE_READY && !mSuspended) {
|
||||
mPlayer.setPlayWhenReady(true);
|
||||
if (state == ExoPlayer.STATE_READY && !mExoplayerSuspended && !mMediaElementSuspended) {
|
||||
resumeExoplayer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -679,6 +683,12 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
// Called on HLSDemuxer's TaskQueue
|
||||
@Override
|
||||
public synchronized boolean seek(long positionUs) {
|
||||
// Need to temporarily resume Exoplayer to download the chunks for getting the demuxed
|
||||
// keyframe sample when HTMLMediaElement is paused. Suspend Exoplayer when collecting enough
|
||||
// samples in onLoadingChanged.
|
||||
if (mExoplayerSuspended) {
|
||||
resumeExoplayer();
|
||||
}
|
||||
// positionUs : microseconds.
|
||||
// NOTE : 1) It's not possible to seek media by tracktype via ExoPlayer Interface.
|
||||
// 2) positionUs is samples PTS from MFR, we need to re-adjust it
|
||||
|
@ -712,7 +722,7 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
|
||||
// Called on HLSDemuxer's TaskQueue
|
||||
@Override
|
||||
public long getNextKeyFrameTime() {
|
||||
public synchronized long getNextKeyFrameTime() {
|
||||
long nextKeyFrameTime = mVRenderer != null
|
||||
? mVRenderer.getNextKeyFrameTime()
|
||||
: Long.MAX_VALUE;
|
||||
|
@ -722,29 +732,68 @@ public class GeckoHlsPlayer implements BaseHlsPlayer, ExoPlayer.EventListener {
|
|||
// Called on Gecko's main thread.
|
||||
@Override
|
||||
public synchronized void suspend() {
|
||||
if (mSuspended) {
|
||||
if (mExoplayerSuspended) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) { Log.d(LOGTAG, "suspend player id : " + mPlayerId); }
|
||||
mSuspended = true;
|
||||
if (mPlayer != null) {
|
||||
mPlayer.setPlayWhenReady(false);
|
||||
if (mMediaElementSuspended) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "suspend player id : " + mPlayerId);
|
||||
}
|
||||
suspendExoplayer();
|
||||
}
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread.
|
||||
@Override
|
||||
public synchronized void resume() {
|
||||
if (!mSuspended) {
|
||||
if (!mExoplayerSuspended) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) { Log.d(LOGTAG, "resume player id : " + mPlayerId); }
|
||||
mSuspended = false;
|
||||
if (mPlayer != null) {
|
||||
mPlayer.setPlayWhenReady(true);
|
||||
if (!mMediaElementSuspended) {
|
||||
if (DEBUG) {
|
||||
Log.d(LOGTAG, "resume player id : " + mPlayerId);
|
||||
}
|
||||
resumeExoplayer();
|
||||
}
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread.
|
||||
@Override
|
||||
public synchronized void play() {
|
||||
if (!mMediaElementSuspended) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) { Log.d(LOGTAG, "mediaElement played."); }
|
||||
mMediaElementSuspended = false;
|
||||
resumeExoplayer();
|
||||
}
|
||||
|
||||
// Called on Gecko's main thread.
|
||||
@Override
|
||||
public synchronized void pause() {
|
||||
if (mMediaElementSuspended) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG) { Log.d(LOGTAG, "mediaElement paused."); }
|
||||
mMediaElementSuspended = true;
|
||||
suspendExoplayer();
|
||||
}
|
||||
|
||||
private synchronized void suspendExoplayer() {
|
||||
if (mPlayer != null) {
|
||||
mExoplayerSuspended = true;
|
||||
if (DEBUG) { Log.d(LOGTAG, "suspend Exoplayer"); }
|
||||
mPlayer.setPlayWhenReady(false);
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void resumeExoplayer() {
|
||||
if (mPlayer != null) {
|
||||
mExoplayerSuspended = false;
|
||||
if (DEBUG) { Log.d(LOGTAG, "resume Exoplayer"); }
|
||||
mPlayer.setPlayWhenReady(true);
|
||||
}
|
||||
}
|
||||
// Called on Gecko's main thread, when HLSDemuxer or HLSResource destructs.
|
||||
@Override
|
||||
public synchronized void release() {
|
||||
|
|
|
@ -2050,6 +2050,22 @@ auto GeckoHLSResourceWrapper::GetPlayerId() const -> int32_t
|
|||
return mozilla::jni::Method<GetPlayerId_t>::Call(GeckoHLSResourceWrapper::mCtx, nullptr);
|
||||
}
|
||||
|
||||
constexpr char GeckoHLSResourceWrapper::Pause_t::name[];
|
||||
constexpr char GeckoHLSResourceWrapper::Pause_t::signature[];
|
||||
|
||||
auto GeckoHLSResourceWrapper::Pause() const -> void
|
||||
{
|
||||
return mozilla::jni::Method<Pause_t>::Call(GeckoHLSResourceWrapper::mCtx, nullptr);
|
||||
}
|
||||
|
||||
constexpr char GeckoHLSResourceWrapper::Play_t::name[];
|
||||
constexpr char GeckoHLSResourceWrapper::Play_t::signature[];
|
||||
|
||||
auto GeckoHLSResourceWrapper::Play() const -> void
|
||||
{
|
||||
return mozilla::jni::Method<Play_t>::Call(GeckoHLSResourceWrapper::mCtx, nullptr);
|
||||
}
|
||||
|
||||
constexpr char GeckoHLSResourceWrapper::Resume_t::name[];
|
||||
constexpr char GeckoHLSResourceWrapper::Resume_t::signature[];
|
||||
|
||||
|
|
|
@ -5879,6 +5879,44 @@ public:
|
|||
|
||||
auto GetPlayerId() const -> int32_t;
|
||||
|
||||
struct Pause_t {
|
||||
typedef GeckoHLSResourceWrapper Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "pause";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = false;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::GECKO;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
auto Pause() const -> void;
|
||||
|
||||
struct Play_t {
|
||||
typedef GeckoHLSResourceWrapper Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<> Args;
|
||||
static constexpr char name[] = "play";
|
||||
static constexpr char signature[] =
|
||||
"()V";
|
||||
static const bool isStatic = false;
|
||||
static const mozilla::jni::ExceptionMode exceptionMode =
|
||||
mozilla::jni::ExceptionMode::ABORT;
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::GECKO;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::CURRENT;
|
||||
};
|
||||
|
||||
auto Play() const -> void;
|
||||
|
||||
struct Resume_t {
|
||||
typedef GeckoHLSResourceWrapper Owner;
|
||||
typedef void ReturnType;
|
||||
|
|
Загрузка…
Ссылка в новой задаче