Bug 1756260 - part9 : only execute engine's methods after it got intialized correctly and not in a shutdown state. r=jolin

If we call them too early, the IPC connection might not be created yet.

Differential Revision: https://phabricator.services.mozilla.com/D144629
This commit is contained in:
alwu 2022-05-11 17:46:15 +00:00
Родитель ba6f805451
Коммит 37cbb23832
2 изменённых файлов: 41 добавлений и 6 удалений

Просмотреть файл

@ -114,11 +114,13 @@ ExternalEngineStateMachine::ExternalEngineStateMachine(
mEngine.reset(new MFMediaEngineWrapper(this));
#endif
if (mEngine) {
mEngine->Init(!mMinimizePreroll)
auto* state = mState.AsInitEngine();
state->mInitPromise = mEngine->Init(!mMinimizePreroll);
state->mInitPromise
->Then(OwnerThread(), __func__, this,
&ExternalEngineStateMachine::OnEngineInitSuccess,
&ExternalEngineStateMachine::OnEngineInitFailure)
->Track(mState.AsInitEngine()->mEngineInitRequest);
->Track(state->mEngineInitRequest);
} else {
ShutdownInternal();
}
@ -132,8 +134,10 @@ void ExternalEngineStateMachine::OnEngineInitSuccess() {
LOG("Initialized the external playback engine %" PRIu64
", start reading metadata",
mEngine->Id());
mState.AsInitEngine()->mEngineInitRequest.Complete();
auto* state = mState.AsInitEngine();
state->mEngineInitRequest.Complete();
mReader->UpdateMediaEngineId(mEngine->Id());
state->mInitPromise = nullptr;
ChangeStateTo(State::ReadingMetadata);
ReadMetadata();
}
@ -142,7 +146,9 @@ void ExternalEngineStateMachine::OnEngineInitFailure() {
AssertOnTaskQueue();
MOZ_ASSERT(mState.IsInitEngine());
LOGE("Failed to initialize the external playback engine");
mState.AsInitEngine()->mEngineInitRequest.Complete();
auto* state = mState.AsInitEngine();
state->mEngineInitRequest.Complete();
state->mInitPromise = nullptr;
// TODO : Should fallback to the normal playback with media engine.
DecodeError(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__));
ShutdownInternal();
@ -441,18 +447,40 @@ void ExternalEngineStateMachine::BufferedRangeUpdated() {
}
}
#define PERFORM_WHEN_ALLOW(Func) \
do { \
/* Initialzation is not done yet, posepone the operation */ \
if (mState.IsInitEngine() && mState.AsInitEngine()->mInitPromise) { \
LOG("%s is called before init", __func__); \
mState.AsInitEngine()->mInitPromise->Then( \
OwnerThread(), __func__, \
[self = RefPtr{this}]( \
const GenericNonExclusivePromise::ResolveOrRejectValue& aVal) { \
if (aVal.IsResolve()) { \
self->Func(); \
} \
}); \
return; \
} else if (mState.IsShutdownEngine()) { \
return; \
} \
} while (false)
void ExternalEngineStateMachine::VolumeChanged() {
AssertOnTaskQueue();
PERFORM_WHEN_ALLOW(VolumeChanged);
mEngine->SetVolume(mVolume);
}
void ExternalEngineStateMachine::PreservesPitchChanged() {
AssertOnTaskQueue();
PERFORM_WHEN_ALLOW(PreservesPitchChanged);
mEngine->SetPreservesPitch(mPreservesPitch);
}
void ExternalEngineStateMachine::PlayStateChanged() {
AssertOnTaskQueue();
PERFORM_WHEN_ALLOW(PlayStateChanged);
if (mPlayState == MediaDecoder::PLAY_STATE_PLAYING) {
mEngine->Play();
} else if (mPlayState == MediaDecoder::PLAY_STATE_PAUSED) {
@ -462,9 +490,12 @@ void ExternalEngineStateMachine::PlayStateChanged() {
void ExternalEngineStateMachine::LoopingChanged() {
AssertOnTaskQueue();
PERFORM_WHEN_ALLOW(LoopingChanged);
mEngine->SetLooping(mLooping);
}
#undef PERFORM_WHEN_ALLOW
void ExternalEngineStateMachine::EndOfStream(MediaData::Type aType) {
AssertOnTaskQueue();
MOZ_ASSERT(mState.IsRunningEngine() || mState.IsSeekingData());

Просмотреть файл

@ -104,6 +104,7 @@ class ExternalEngineStateMachine final
InitEngine() = default;
~InitEngine() { mEngineInitRequest.DisconnectIfExists(); }
MozPromiseRequestHolder<GenericNonExclusivePromise> mEngineInitRequest;
RefPtr<GenericNonExclusivePromise> mInitPromise;
};
struct ReadingMetadata {
ReadingMetadata() = default;
@ -253,17 +254,20 @@ class ExternalPlaybackEngine {
// Init the engine and specify the preload request.
virtual RefPtr<GenericNonExclusivePromise> Init(bool aShouldPreload) = 0;
virtual void Shutdown() = 0;
virtual uint64_t Id() const = 0;
// Following methods should only be called after successfully initialize the
// external engine.
virtual void Play() = 0;
virtual void Pause() = 0;
virtual void Seek(const media::TimeUnit& aTargetTime) = 0;
virtual void Shutdown() = 0;
virtual void SetPlaybackRate(double aPlaybackRate) = 0;
virtual void SetVolume(double aVolume) = 0;
virtual void SetLooping(bool aLooping) = 0;
virtual void SetPreservesPitch(bool aPreservesPitch) = 0;
virtual media::TimeUnit GetCurrentPosition() = 0;
virtual void NotifyEndOfStream(TrackInfo::TrackType aType) = 0;
virtual uint64_t Id() const = 0;
virtual void SetMediaInfo(const MediaInfo& aInfo) = 0;
ExternalEngineStateMachine* const MOZ_NON_OWNING_REF mOwner;