mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1158448 Part 2 - Remove ApplyStateToStateMachine and PLAY_STATE_SEEKING r=jwwang,bwu
This commit is contained in:
parent
bd2cbc7984
commit
071d1f0488
@ -278,7 +278,6 @@ void MediaDecoder::Pause()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
if (mPlayState == PLAY_STATE_LOADING ||
|
||||
mPlayState == PLAY_STATE_SEEKING ||
|
||||
IsEnded()) {
|
||||
mNextState = PLAY_STATE_PAUSED;
|
||||
return;
|
||||
@ -437,6 +436,20 @@ MediaDecoder::OutputStreamData::~OutputStreamData()
|
||||
mListener->Forget();
|
||||
}
|
||||
|
||||
void MediaDecoder::UpdateDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
GetReentrantMonitor().AssertCurrentThreadIn();
|
||||
|
||||
if (mDecodedStream) {
|
||||
bool blockForPlayState = mPlayState != PLAY_STATE_PLAYING || mLogicallySeeking;
|
||||
if (mDecodedStream->mHaveBlockedForPlayState != blockForPlayState) {
|
||||
mDecodedStream->mStream->ChangeExplicitBlockerCount(blockForPlayState ? 1 : -1);
|
||||
mDecodedStream->mHaveBlockedForPlayState = blockForPlayState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MediaDecoder::DestroyDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -610,6 +623,8 @@ MediaDecoder::MediaDecoder() :
|
||||
"MediaDecoder::mPlayState (Canonical)"),
|
||||
mNextState(AbstractThread::MainThread(), PLAY_STATE_PAUSED,
|
||||
"MediaDecoder::mNextState (Canonical)"),
|
||||
mLogicallySeeking(AbstractThread::MainThread(), false,
|
||||
"MediaDecoder::mLogicallySeeking (Canonical)"),
|
||||
mIgnoreProgressData(false),
|
||||
mInfiniteStream(false),
|
||||
mOwner(nullptr),
|
||||
@ -793,7 +808,7 @@ nsresult MediaDecoder::Play()
|
||||
ScheduleStateMachineThread();
|
||||
if (IsEnded()) {
|
||||
return Seek(0, SeekTarget::PrevSyncPoint);
|
||||
} else if (mPlayState == PLAY_STATE_LOADING || mPlayState == PLAY_STATE_SEEKING) {
|
||||
} else if (mPlayState == PLAY_STATE_LOADING) {
|
||||
mNextState = PLAY_STATE_PLAYING;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -806,6 +821,8 @@ nsresult MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
NS_ENSURE_TRUE(!mShuttingDown, NS_ERROR_FAILURE);
|
||||
|
||||
UpdateDormantState(false /* aDormantTimeout */, true /* aActivity */);
|
||||
|
||||
MOZ_ASSERT(aTime >= 0.0, "Cannot seek to a negative value.");
|
||||
@ -814,23 +831,33 @@ nsresult MediaDecoder::Seek(double aTime, SeekTarget::Type aSeekType)
|
||||
nsresult rv = SecondsToUsecs(aTime, timeUsecs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mRequestedSeekTarget = SeekTarget(timeUsecs, aSeekType);
|
||||
mCurrentTime = aTime;
|
||||
mWasEndedWhenEnteredDormant = false;
|
||||
|
||||
// If we are already in the seeking state, the new seek overrides the old one.
|
||||
if (mPlayState != PLAY_STATE_LOADING) {
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
mLogicallySeeking = true;
|
||||
UpdateDecodedStream();
|
||||
SeekTarget target = SeekTarget(timeUsecs, aSeekType);
|
||||
CallSeek(target);
|
||||
|
||||
if (mPlayState == PLAY_STATE_ENDED) {
|
||||
bool paused = false;
|
||||
if (mOwner) {
|
||||
paused = mOwner->GetPaused();
|
||||
}
|
||||
mNextState = paused ? PLAY_STATE_PAUSED : PLAY_STATE_PLAYING;
|
||||
PinForSeek();
|
||||
ChangeState(PLAY_STATE_SEEKING);
|
||||
ChangeState(paused ? PLAY_STATE_PAUSED : PLAY_STATE_PLAYING);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return ScheduleStateMachineThread();
|
||||
void MediaDecoder::CallSeek(const SeekTarget& aTarget)
|
||||
{
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
mSeekRequest.Begin(ProxyMediaCall(mDecoderStateMachine->TaskQueue(),
|
||||
mDecoderStateMachine.get(), __func__,
|
||||
&MediaDecoderStateMachine::Seek, aTarget)
|
||||
->RefableThen(AbstractThread::MainThread(), __func__, this,
|
||||
&MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
|
||||
}
|
||||
|
||||
double MediaDecoder::GetCurrentTime()
|
||||
@ -919,7 +946,6 @@ MediaDecoder::PlayStateStr()
|
||||
case PLAY_STATE_LOADING: return "PLAY_STATE_LOADING";
|
||||
case PLAY_STATE_PAUSED: return "PLAY_STATE_PAUSED";
|
||||
case PLAY_STATE_PLAYING: return "PLAY_STATE_PLAYING";
|
||||
case PLAY_STATE_SEEKING: return "PLAY_STATE_SEEKING";
|
||||
case PLAY_STATE_ENDED: return "PLAY_STATE_ENDED";
|
||||
case PLAY_STATE_SHUTDOWN: return "PLAY_STATE_SHUTDOWN";
|
||||
default: return "INVALID_PLAY_STATE";
|
||||
@ -956,12 +982,7 @@ void MediaDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
// state if we're still set to the original
|
||||
// loading state.
|
||||
if (mPlayState == PLAY_STATE_LOADING && !mIsDormant) {
|
||||
if (mRequestedSeekTarget.IsValid()) {
|
||||
ChangeState(PLAY_STATE_SEEKING);
|
||||
}
|
||||
else {
|
||||
ChangeState(mNextState);
|
||||
}
|
||||
ChangeState(mNextState);
|
||||
}
|
||||
|
||||
// Run NotifySuspendedStatusChanged now to give us a chance to notice
|
||||
@ -1025,8 +1046,7 @@ bool MediaDecoder::IsSameOriginMedia()
|
||||
bool MediaDecoder::IsSeeking() const
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
return !mIsDormant && (mPlayState == PLAY_STATE_SEEKING ||
|
||||
(mPlayState == PLAY_STATE_LOADING && mRequestedSeekTarget.IsValid()));
|
||||
return mLogicallySeeking;
|
||||
}
|
||||
|
||||
bool MediaDecoder::IsEndedOrShutdown() const
|
||||
@ -1046,7 +1066,7 @@ void MediaDecoder::PlaybackEnded()
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mShuttingDown ||
|
||||
mPlayState == PLAY_STATE_SEEKING ||
|
||||
mLogicallySeeking ||
|
||||
mPlayState == PLAY_STATE_LOADING) {
|
||||
return;
|
||||
}
|
||||
@ -1225,30 +1245,24 @@ void MediaDecoder::OnSeekResolved(SeekResolveValue aVal)
|
||||
return;
|
||||
|
||||
bool fireEnded = false;
|
||||
bool seekWasAborted = false;
|
||||
{
|
||||
ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
|
||||
|
||||
// An additional seek was requested while the current seek was
|
||||
// in operation.
|
||||
if (mRequestedSeekTarget.IsValid()) {
|
||||
ChangeState(PLAY_STATE_SEEKING);
|
||||
seekWasAborted = true;
|
||||
} else {
|
||||
UnpinForSeek();
|
||||
fireEnded = aVal.mAtEnd;
|
||||
if (aVal.mAtEnd) {
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
} else if (aVal.mEventVisibility != MediaDecoderEventVisibility::Suppressed) {
|
||||
ChangeState(aVal.mAtEnd ? PLAY_STATE_ENDED : mNextState);
|
||||
}
|
||||
UnpinForSeek();
|
||||
fireEnded = aVal.mAtEnd;
|
||||
if (aVal.mAtEnd) {
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
}
|
||||
mLogicallySeeking = false;
|
||||
UpdateDecodedStream();
|
||||
}
|
||||
|
||||
PlaybackPositionChanged(aVal.mEventVisibility);
|
||||
|
||||
if (mOwner) {
|
||||
if (!seekWasAborted && (aVal.mEventVisibility != MediaDecoderEventVisibility::Suppressed)) {
|
||||
if (aVal.mEventVisibility != MediaDecoderEventVisibility::Suppressed) {
|
||||
mOwner->SeekCompleted();
|
||||
if (fireEnded) {
|
||||
mOwner->PlaybackEnded();
|
||||
@ -1284,35 +1298,18 @@ void MediaDecoder::ChangeState(PlayState aState)
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDecodedStream) {
|
||||
bool blockForPlayState = aState != PLAY_STATE_PLAYING;
|
||||
if (mDecodedStream->mHaveBlockedForPlayState != blockForPlayState) {
|
||||
mDecodedStream->mStream->ChangeExplicitBlockerCount(blockForPlayState ? 1 : -1);
|
||||
mDecodedStream->mHaveBlockedForPlayState = blockForPlayState;
|
||||
}
|
||||
}
|
||||
|
||||
DECODER_LOG("ChangeState %s => %s",
|
||||
gPlayStateStr[mPlayState], gPlayStateStr[aState]);
|
||||
mPlayState = aState;
|
||||
|
||||
UpdateDecodedStream();
|
||||
|
||||
if (mPlayState == PLAY_STATE_PLAYING) {
|
||||
ConstructMediaTracks();
|
||||
} else if (IsEnded()) {
|
||||
RemoveMediaTracks();
|
||||
}
|
||||
|
||||
// XXXbholley - We should refactor things and move this to the code that
|
||||
// actually initiates the seek.
|
||||
if (mPlayState == PLAY_STATE_SEEKING) {
|
||||
mSeekRequest.Begin(ProxyMediaCall(mDecoderStateMachine->TaskQueue(),
|
||||
mDecoderStateMachine.get(), __func__,
|
||||
&MediaDecoderStateMachine::Seek, mRequestedSeekTarget)
|
||||
->RefableThen(AbstractThread::MainThread(), __func__, this,
|
||||
&MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
|
||||
mRequestedSeekTarget.Reset();
|
||||
}
|
||||
|
||||
ScheduleStateMachineThread();
|
||||
|
||||
CancelDormantTimer();
|
||||
|
@ -295,7 +295,6 @@ public:
|
||||
PLAY_STATE_LOADING,
|
||||
PLAY_STATE_PAUSED,
|
||||
PLAY_STATE_PLAYING,
|
||||
PLAY_STATE_SEEKING,
|
||||
PLAY_STATE_ENDED,
|
||||
PLAY_STATE_SHUTDOWN
|
||||
};
|
||||
@ -513,6 +512,9 @@ public:
|
||||
* Connects mDecodedStream->mStream to aStream->mStream.
|
||||
*/
|
||||
void ConnectDecodedStreamToOutputStream(OutputStreamData* aStream);
|
||||
|
||||
void UpdateDecodedStream();
|
||||
|
||||
/**
|
||||
* Disconnects mDecodedStream->mStream from all outputs and clears
|
||||
* mDecodedStream.
|
||||
@ -755,9 +757,6 @@ public:
|
||||
nsAutoPtr<MediaInfo> aInfo,
|
||||
nsAutoPtr<MetadataTags> aTags) override;
|
||||
|
||||
int64_t GetSeekTime() { return mRequestedSeekTarget.mTime; }
|
||||
void ResetSeekTime() { mRequestedSeekTarget.Reset(); }
|
||||
|
||||
/******
|
||||
* The following methods must only be called on the main
|
||||
* thread.
|
||||
@ -803,7 +802,11 @@ public:
|
||||
// Call on the main thread only.
|
||||
void PlaybackEnded();
|
||||
|
||||
void OnSeekRejected() { mSeekRequest.Complete(); }
|
||||
void OnSeekRejected()
|
||||
{
|
||||
mSeekRequest.Complete();
|
||||
mLogicallySeeking = false;
|
||||
}
|
||||
void OnSeekResolved(SeekResolveValue aVal);
|
||||
|
||||
// Seeking has started. Inform the element on the main
|
||||
@ -1154,19 +1157,16 @@ protected:
|
||||
// Any change to the state must call NotifyAll on the monitor.
|
||||
// This can only be PLAY_STATE_PAUSED or PLAY_STATE_PLAYING.
|
||||
Canonical<PlayState> mNextState;
|
||||
|
||||
// True if the decoder is seeking.
|
||||
Canonical<bool> mLogicallySeeking;
|
||||
public:
|
||||
AbstractCanonical<PlayState>* CanonicalPlayState() { return &mPlayState; }
|
||||
AbstractCanonical<PlayState>* CanonicalNextPlayState() { return &mNextState; }
|
||||
AbstractCanonical<bool>* CanonicalLogicallySeeking() { return &mLogicallySeeking; }
|
||||
protected:
|
||||
|
||||
// Position to seek to when the seek notification is received by the
|
||||
// decode thread.
|
||||
// This can only be changed on the main thread while holding the decoder
|
||||
// monitor. Thus, it can be safely read while holding the decoder monitor
|
||||
// OR on the main thread.
|
||||
// If the SeekTarget's IsValid() accessor returns false, then no seek has
|
||||
// been requested. When a seek is started this is reset to invalid.
|
||||
SeekTarget mRequestedSeekTarget;
|
||||
virtual void CallSeek(const SeekTarget& aTarget);
|
||||
|
||||
MediaPromiseConsumerHolder<SeekPromise> mSeekRequest;
|
||||
|
||||
|
@ -216,6 +216,8 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
"MediaDecoderStateMachine::mPlayState (Mirror)"),
|
||||
mNextPlayState(mTaskQueue, MediaDecoder::PLAY_STATE_PAUSED,
|
||||
"MediaDecoderStateMachine::mNextPlayState (Mirror)"),
|
||||
mLogicallySeeking(mTaskQueue, false,
|
||||
"MediaDecoderStateMachine::mLogicallySeeking (Mirror)"),
|
||||
mNextFrameStatus(mTaskQueue, MediaDecoderOwner::NEXT_FRAME_UNINITIALIZED,
|
||||
"MediaDecoderStateMachine::mNextFrameStatus (Canonical)"),
|
||||
mFragmentEndTime(-1),
|
||||
@ -308,6 +310,7 @@ MediaDecoderStateMachine::InitializationTask()
|
||||
// Connect mirrors.
|
||||
mPlayState.Connect(mDecoder->CanonicalPlayState());
|
||||
mNextPlayState.Connect(mDecoder->CanonicalNextPlayState());
|
||||
mLogicallySeeking.Connect(mDecoder->CanonicalLogicallySeeking());
|
||||
mVolume.Connect(mDecoder->CanonicalVolume());
|
||||
mLogicalPlaybackRate.Connect(mDecoder->CanonicalPlaybackRate());
|
||||
mPreservesPitch.Connect(mDecoder->CanonicalPreservesPitch());
|
||||
@ -319,6 +322,7 @@ MediaDecoderStateMachine::InitializationTask()
|
||||
mWatchManager.Watch(mLogicalPlaybackRate, &MediaDecoderStateMachine::LogicalPlaybackRateChanged);
|
||||
mWatchManager.Watch(mPreservesPitch, &MediaDecoderStateMachine::PreservesPitchChanged);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLogicallySeeking, &MediaDecoderStateMachine::LogicallySeekingChanged);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasFutureAudio() {
|
||||
@ -1676,6 +1680,13 @@ void MediaDecoderStateMachine::PlayStateChanged()
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::LogicallySeekingChanged()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::NotifyDataArrived(const char* aBuffer,
|
||||
uint32_t aLength,
|
||||
int64_t aOffset)
|
||||
@ -2545,6 +2556,7 @@ MediaDecoderStateMachine::FinishShutdown()
|
||||
// Disconnect canonicals and mirrors before shutting down our task queue.
|
||||
mPlayState.DisconnectIfConnected();
|
||||
mNextPlayState.DisconnectIfConnected();
|
||||
mLogicallySeeking.DisconnectIfConnected();
|
||||
mVolume.DisconnectIfConnected();
|
||||
mLogicalPlaybackRate.DisconnectIfConnected();
|
||||
mPreservesPitch.DisconnectIfConnected();
|
||||
@ -2665,6 +2677,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
|
||||
AdvanceFrame();
|
||||
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
mLogicallySeeking ||
|
||||
IsStateMachineScheduled() ||
|
||||
mPlaybackRate == 0.0, "Must have timer scheduled");
|
||||
return NS_OK;
|
||||
@ -2733,6 +2746,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
{
|
||||
AdvanceFrame();
|
||||
NS_ASSERTION(mPlayState != MediaDecoder::PLAY_STATE_PLAYING ||
|
||||
mLogicallySeeking ||
|
||||
mPlaybackRate == 0 || IsStateMachineScheduled(),
|
||||
"Must have timer scheduled");
|
||||
return NS_OK;
|
||||
@ -2934,7 +2948,7 @@ void MediaDecoderStateMachine::AdvanceFrame()
|
||||
NS_ASSERTION(!HasAudio() || mAudioStartTime != -1,
|
||||
"Should know audio start time if we have audio.");
|
||||
|
||||
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING) {
|
||||
if (mPlayState != MediaDecoder::PLAY_STATE_PLAYING || mLogicallySeeking) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -580,6 +580,9 @@ protected:
|
||||
// Notification method invoked when mPlayState changes.
|
||||
void PlayStateChanged();
|
||||
|
||||
// Notification method invoked when mLogicallySeeking changes.
|
||||
void LogicallySeekingChanged();
|
||||
|
||||
// Sets internal state which causes playback of media to pause.
|
||||
// The decoder monitor must be held.
|
||||
void StopPlayback();
|
||||
@ -891,6 +894,7 @@ public:
|
||||
// The current play state and next play state, mirrored from the main thread.
|
||||
Mirror<MediaDecoder::PlayState> mPlayState;
|
||||
Mirror<MediaDecoder::PlayState> mNextPlayState;
|
||||
Mirror<bool> mLogicallySeeking;
|
||||
|
||||
// Returns true if we're logically playing, that is, if the Play() has
|
||||
// been called and Pause() has not or we have not yet reached the end
|
||||
|
@ -688,7 +688,7 @@ nsresult AudioOffloadPlayer::StopTimeUpdate()
|
||||
MediaDecoderOwner::NextFrameStatus AudioOffloadPlayer::GetNextFrameStatus()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mPlayState == MediaDecoder::PLAY_STATE_SEEKING) {
|
||||
if (mSeekTarget.IsValid()) {
|
||||
return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING;
|
||||
} else if (mPlayState == MediaDecoder::PLAY_STATE_ENDED) {
|
||||
return MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
|
||||
|
@ -84,17 +84,27 @@ MediaOmxCommonDecoder::FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
|
||||
mAudioOffloadPlayer->SetSource(mReader->GetAudioOffloadTrack());
|
||||
status_t err = mAudioOffloadPlayer->Start(false);
|
||||
if (err == OK) {
|
||||
PauseStateMachine();
|
||||
// Call ChangeState() to run AudioOffloadPlayer since offload state enabled
|
||||
ChangeState(mPlayState);
|
||||
if (err != OK) {
|
||||
mAudioOffloadPlayer = nullptr;
|
||||
mFallbackToStateMachine = true;
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("In %s Unable to start offload audio %d."
|
||||
"Switching to normal mode", __PRETTY_FUNCTION__, err));
|
||||
return;
|
||||
}
|
||||
|
||||
mAudioOffloadPlayer = nullptr;
|
||||
mFallbackToStateMachine = true;
|
||||
DECODER_LOG(PR_LOG_DEBUG, ("In %s Unable to start offload audio %d."
|
||||
"Switching to normal mode", __PRETTY_FUNCTION__, err));
|
||||
PauseStateMachine();
|
||||
if (mLogicallySeeking) {
|
||||
int64_t timeUsecs = 0;
|
||||
SecondsToUsecs(mCurrentTime, timeUsecs);
|
||||
SeekTarget target = SeekTarget(timeUsecs,
|
||||
SeekTarget::Accurate,
|
||||
MediaDecoderEventVisibility::Observable);
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
mSeekRequest.Begin(mAudioOffloadPlayer->Seek(target)
|
||||
->RefableThen(AbstractThread::MainThread(), __func__, static_cast<MediaDecoder*>(this),
|
||||
&MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
|
||||
}
|
||||
// Call ChangeState() to run AudioOffloadPlayer since offload state enabled
|
||||
ChangeState(mPlayState);
|
||||
}
|
||||
|
||||
void
|
||||
@ -140,17 +150,16 @@ MediaOmxCommonDecoder::ResumeStateMachine()
|
||||
mAudioOffloadPlayer = nullptr;
|
||||
int64_t timeUsecs = 0;
|
||||
SecondsToUsecs(mCurrentTime, timeUsecs);
|
||||
mRequestedSeekTarget = SeekTarget(timeUsecs,
|
||||
SeekTarget::Accurate,
|
||||
MediaDecoderEventVisibility::Suppressed);
|
||||
SeekTarget target = SeekTarget(timeUsecs,
|
||||
SeekTarget::Accurate,
|
||||
MediaDecoderEventVisibility::Suppressed);
|
||||
// Call Seek of MediaDecoderStateMachine to suppress seek events.
|
||||
RefPtr<nsRunnable> event =
|
||||
NS_NewRunnableMethodWithArg<SeekTarget>(
|
||||
GetStateMachine(),
|
||||
&MediaDecoderStateMachine::Seek,
|
||||
mRequestedSeekTarget);
|
||||
target);
|
||||
GetStateMachine()->TaskQueue()->Dispatch(event);
|
||||
mRequestedSeekTarget.Reset();
|
||||
|
||||
mNextState = mPlayState;
|
||||
ChangeState(PLAY_STATE_LOADING);
|
||||
@ -226,31 +235,20 @@ MediaOmxCommonDecoder::ChangeState(PlayState aState)
|
||||
ResumeStateMachine();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mPlayState) {
|
||||
case PLAY_STATE_SEEKING:
|
||||
mSeekRequest.Begin(mAudioOffloadPlayer->Seek(mRequestedSeekTarget)
|
||||
->RefableThen(AbstractThread::MainThread(), __func__, static_cast<MediaDecoder*>(this),
|
||||
&MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
|
||||
mRequestedSeekTarget.Reset();
|
||||
break;
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaOmxCommonDecoder::ApplyStateToStateMachine(PlayState aState)
|
||||
MediaOmxCommonDecoder::CallSeek(const SeekTarget& aTarget)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// During offload playback, state machine should be in dormant state.
|
||||
// ApplyStateToStateMachine() can change state machine state to
|
||||
// something else or reset the seek time. So don't call this when audio is
|
||||
// offloaded
|
||||
if (!mAudioOffloadPlayer) {
|
||||
MediaDecoder::ApplyStateToStateMachine(aState);
|
||||
MediaDecoder::CallSeek(aTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
mSeekRequest.DisconnectIfExists();
|
||||
mSeekRequest.Begin(mAudioOffloadPlayer->Seek(aTarget)
|
||||
->RefableThen(AbstractThread::MainThread(), __func__, static_cast<MediaDecoder*>(this),
|
||||
&MediaDecoder::OnSeekResolved, &MediaDecoder::OnSeekRejected));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -24,23 +24,23 @@ public:
|
||||
MediaOmxCommonDecoder();
|
||||
|
||||
virtual void FirstFrameLoaded(nsAutoPtr<MediaInfo> aInfo,
|
||||
MediaDecoderEventVisibility aEventVisibility);
|
||||
virtual void ChangeState(PlayState aState);
|
||||
virtual void ApplyStateToStateMachine(PlayState aState);
|
||||
virtual void SetVolume(double aVolume);
|
||||
MediaDecoderEventVisibility aEventVisibility) override;
|
||||
virtual void ChangeState(PlayState aState) override;
|
||||
virtual void CallSeek(const SeekTarget& aTarget) override;
|
||||
virtual void SetVolume(double aVolume) override;
|
||||
virtual void PlaybackPositionChanged(MediaDecoderEventVisibility aEventVisibility =
|
||||
MediaDecoderEventVisibility::Observable);
|
||||
MediaDecoderEventVisibility::Observable) override;
|
||||
virtual MediaDecoderOwner::NextFrameStatus NextFrameStatus() override;
|
||||
virtual void SetElementVisibility(bool aIsVisible);
|
||||
virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio);
|
||||
virtual bool CheckDecoderCanOffloadAudio();
|
||||
virtual void SetElementVisibility(bool aIsVisible) override;
|
||||
virtual void SetPlatformCanOffloadAudio(bool aCanOffloadAudio) override;
|
||||
virtual bool CheckDecoderCanOffloadAudio() override;
|
||||
virtual void AddOutputStream(ProcessedMediaStream* aStream,
|
||||
bool aFinishWhenEnded);
|
||||
virtual void SetPlaybackRate(double aPlaybackRate);
|
||||
bool aFinishWhenEnded) override;
|
||||
virtual void SetPlaybackRate(double aPlaybackRate) override;
|
||||
|
||||
void AudioOffloadTearDown();
|
||||
|
||||
virtual MediaDecoderStateMachine* CreateStateMachine();
|
||||
virtual MediaDecoderStateMachine* CreateStateMachine() override;
|
||||
|
||||
virtual MediaOmxCommonReader* CreateReader() = 0;
|
||||
virtual MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) = 0;
|
||||
|
@ -32,15 +32,15 @@ RtspMediaCodecDecoder::CreateStateMachineFromReader(MediaOmxCommonReader* aReade
|
||||
}
|
||||
|
||||
void
|
||||
RtspMediaCodecDecoder::ApplyStateToStateMachine(PlayState aState)
|
||||
RtspMediaCodecDecoder::ChangeState(PlayState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MediaDecoder::ApplyStateToStateMachine(aState);
|
||||
MediaDecoder::ChangeState(aState);
|
||||
|
||||
// Notify RTSP controller if the play state is ended.
|
||||
// This is necessary for RTSP controller to transit its own state.
|
||||
if (aState == PLAY_STATE_ENDED) {
|
||||
if (mPlayState == PLAY_STATE_ENDED) {
|
||||
nsRefPtr<RtspMediaResource> resource = mResource->GetRtspPointer();
|
||||
if (resource) {
|
||||
nsIStreamingProtocolController* controller =
|
||||
|
@ -20,7 +20,7 @@ public:
|
||||
|
||||
virtual MediaDecoderStateMachine* CreateStateMachineFromReader(MediaOmxCommonReader* aReader) override;
|
||||
|
||||
virtual void ApplyStateToStateMachine(PlayState aState) override;
|
||||
virtual void ChangeState(PlayState aState) override;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -16,22 +16,24 @@ MediaDecoder* RtspOmxDecoder::Clone()
|
||||
return new RtspOmxDecoder();
|
||||
}
|
||||
|
||||
MediaDecoderStateMachine* RtspOmxDecoder::CreateStateMachine()
|
||||
MediaDecoderStateMachine*
|
||||
RtspOmxDecoder::CreateStateMachine()
|
||||
{
|
||||
return new MediaDecoderStateMachine(this,
|
||||
new RtspOmxReader(this),
|
||||
mResource->IsRealTime());
|
||||
}
|
||||
|
||||
void RtspOmxDecoder::ApplyStateToStateMachine(PlayState aState)
|
||||
void
|
||||
RtspOmxDecoder::ChangeState(PlayState aState)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MediaDecoder::ApplyStateToStateMachine(aState);
|
||||
MediaDecoder::ChangeState(aState);
|
||||
|
||||
// Notify RTSP controller if the play state is ended.
|
||||
// This is necessary for RTSP controller to transit its own state.
|
||||
if (aState == PLAY_STATE_ENDED) {
|
||||
if (mPlayState == PLAY_STATE_ENDED) {
|
||||
nsRefPtr<RtspMediaResource> resource = mResource->GetRtspPointer();
|
||||
if (resource) {
|
||||
nsIStreamingProtocolController* controller =
|
||||
|
@ -32,8 +32,7 @@ public:
|
||||
|
||||
virtual MediaDecoder* Clone() override final;
|
||||
virtual MediaDecoderStateMachine* CreateStateMachine() override final;
|
||||
virtual void ApplyStateToStateMachine(PlayState aState)
|
||||
override final;
|
||||
virtual void ChangeState(PlayState aState) override final;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
Loading…
Reference in New Issue
Block a user