forked from mirrors/gecko-dev
Bug 1885959 - part3 : postpone seek while the engine is still in initialization. r=jolin
We will postpone any seek happening before the engine initialization is finished, and will resolve the seek promise based on the latest seek if there are multiple seek being requested. Differential Revision: https://phabricator.services.mozilla.com/D205017
This commit is contained in:
parent
07febbc907
commit
eefde59bed
3 changed files with 65 additions and 1 deletions
|
|
@ -365,6 +365,58 @@ bool ExternalEngineStateMachine::IsFormatSupportedByExternalEngine(
|
|||
#endif
|
||||
}
|
||||
|
||||
RefPtr<MediaDecoder::SeekPromise> ExternalEngineStateMachine::InvokeSeek(
|
||||
const SeekTarget& aTarget) {
|
||||
return InvokeAsync(
|
||||
OwnerThread(), __func__,
|
||||
[self = RefPtr<ExternalEngineStateMachine>(this), this,
|
||||
target = aTarget]() -> RefPtr<MediaDecoder::SeekPromise> {
|
||||
AssertOnTaskQueue();
|
||||
if (!mEngine || !mEngine->IsInited()) {
|
||||
LOG("Can't perform seek (%" PRId64 ") now, add a pending seek task",
|
||||
target.GetTime().ToMicroseconds());
|
||||
// We haven't added any pending seek before
|
||||
if (mPendingSeek.mPromise.IsEmpty()) {
|
||||
mPendingTasks.AppendElement(NS_NewRunnableFunction(
|
||||
"ExternalEngineStateMachine::InvokeSeek",
|
||||
[self = RefPtr{this}, this] {
|
||||
if (!mPendingSeek.Exists()) {
|
||||
return;
|
||||
}
|
||||
Seek(*mPendingSeek.mTarget)
|
||||
->Then(OwnerThread(), __func__,
|
||||
[self = RefPtr{this},
|
||||
this](const MediaDecoder::SeekPromise::
|
||||
ResolveOrRejectValue& aVal) {
|
||||
mPendingSeekRequest.Complete();
|
||||
if (aVal.IsResolve()) {
|
||||
mPendingSeek.Resolve(__func__);
|
||||
} else {
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
}
|
||||
mPendingSeek = SeekJob();
|
||||
})
|
||||
->Track(mPendingSeekRequest);
|
||||
}));
|
||||
} else {
|
||||
// Reject previous pending promise, as we will create a new one
|
||||
LOG("Replace previous pending seek with a new one");
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mPendingSeekRequest.DisconnectIfExists();
|
||||
}
|
||||
mPendingSeek.mTarget = Some(target);
|
||||
return mPendingSeek.mPromise.Ensure(__func__);
|
||||
}
|
||||
if (mPendingSeek.Exists()) {
|
||||
LOG("Discard pending seek because another new seek happens");
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mPendingSeek = SeekJob();
|
||||
mPendingSeekRequest.DisconnectIfExists();
|
||||
}
|
||||
return self->Seek(target);
|
||||
});
|
||||
}
|
||||
|
||||
RefPtr<MediaDecoder::SeekPromise> ExternalEngineStateMachine::Seek(
|
||||
const SeekTarget& aTarget) {
|
||||
AssertOnTaskQueue();
|
||||
|
|
@ -571,6 +623,9 @@ RefPtr<ShutdownPromise> ExternalEngineStateMachine::Shutdown() {
|
|||
mSetCDMProxyPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_ABORT_ERR, __func__);
|
||||
mSetCDMProxyRequest.DisconnectIfExists();
|
||||
|
||||
mPendingSeek.RejectIfExists(__func__);
|
||||
mPendingSeekRequest.DisconnectIfExists();
|
||||
|
||||
mPendingTasks.Clear();
|
||||
|
||||
if (mEngine) {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ class ExternalEngineStateMachine final
|
|||
ExternalEngineStateMachine(MediaDecoder* aDecoder,
|
||||
MediaFormatReader* aReader);
|
||||
|
||||
RefPtr<MediaDecoder::SeekPromise> InvokeSeek(
|
||||
const SeekTarget& aTarget) override;
|
||||
|
||||
RefPtr<GenericPromise> InvokeSetSink(
|
||||
const RefPtr<AudioDeviceInfo>& aSink) override;
|
||||
|
||||
|
|
@ -309,6 +312,11 @@ class ExternalEngineStateMachine final
|
|||
MozPromiseHolder<SetCDMPromise> mSetCDMProxyPromise;
|
||||
MozPromiseRequestHolder<SetCDMPromise> mSetCDMProxyRequest;
|
||||
|
||||
// If seek happens while the engine is still initializing, then we would
|
||||
// postpone the seek until the engine is ready.
|
||||
SeekJob mPendingSeek;
|
||||
MozPromiseRequestHolder<MediaDecoder::SeekPromise> mPendingSeekRequest;
|
||||
|
||||
// It would be zero for audio-only playback.
|
||||
gfx::IntSize mVideoDisplay;
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,8 @@ class MediaDecoderStateMachineBase {
|
|||
RefPtr<ShutdownPromise> BeginShutdown();
|
||||
|
||||
// Seeks to the decoder to aTarget asynchronously.
|
||||
RefPtr<MediaDecoder::SeekPromise> InvokeSeek(const SeekTarget& aTarget);
|
||||
virtual RefPtr<MediaDecoder::SeekPromise> InvokeSeek(
|
||||
const SeekTarget& aTarget);
|
||||
|
||||
virtual size_t SizeOfVideoQueue() const = 0;
|
||||
virtual size_t SizeOfAudioQueue() const = 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue