зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1596777 - Hook up the SecondaryVideoContainer with state mirroring. r=alwu
This better follows how MediaDecoder and MediaDecoderStateMachine was architected. Differential Revision: https://phabricator.services.mozilla.com/D53710 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
ca7efe86e5
Коммит
9d878d1ca7
|
@ -502,12 +502,10 @@ void HTMLVideoElement::MaybeBeginCloningVisually() {
|
|||
}
|
||||
|
||||
if (mDecoder) {
|
||||
MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
|
||||
VideoFrameContainer* container =
|
||||
mVisualCloneTarget->GetVideoFrameContainer();
|
||||
if (mdsm && container) {
|
||||
mdsm->SetSecondaryVideoContainer(container);
|
||||
mDecoder->SetCloningVisually(true);
|
||||
if (container) {
|
||||
mDecoder->SetSecondaryVideoContainer(container);
|
||||
}
|
||||
} else if (mSrcStream) {
|
||||
VideoFrameContainer* container =
|
||||
|
@ -522,11 +520,7 @@ void HTMLVideoElement::EndCloningVisually() {
|
|||
MOZ_ASSERT(mVisualCloneTarget);
|
||||
|
||||
if (mDecoder) {
|
||||
MediaDecoderStateMachine* mdsm = mDecoder->GetStateMachine();
|
||||
if (mdsm) {
|
||||
mdsm->SetSecondaryVideoContainer(nullptr);
|
||||
mDecoder->SetCloningVisually(false);
|
||||
}
|
||||
mDecoder->SetSecondaryVideoContainer(nullptr);
|
||||
} else if (mSrcStream) {
|
||||
VideoFrameContainer* container =
|
||||
mVisualCloneTarget->GetVideoFrameContainer();
|
||||
|
|
|
@ -301,7 +301,6 @@ MediaDecoder::MediaDecoder(MediaDecoderInit& aInit)
|
|||
mIsElementInTree(false),
|
||||
mForcedHidden(false),
|
||||
mHasSuspendTaint(aInit.mHasSuspendTaint),
|
||||
mIsCloningVisually(false),
|
||||
mPlaybackRate(aInit.mPlaybackRate),
|
||||
mLogicallySeeking(false, "MediaDecoder::mLogicallySeeking"),
|
||||
INIT_MIRROR(mBuffered, TimeIntervals()),
|
||||
|
@ -312,6 +311,7 @@ MediaDecoder::MediaDecoder(MediaDecoderInit& aInit)
|
|||
INIT_CANONICAL(mPreservesPitch, aInit.mPreservesPitch),
|
||||
INIT_CANONICAL(mLooping, aInit.mLooping),
|
||||
INIT_CANONICAL(mSinkDevice, nullptr),
|
||||
INIT_CANONICAL(mSecondaryVideoContainer, nullptr),
|
||||
INIT_CANONICAL(mOutputCaptured, false),
|
||||
INIT_CANONICAL(mOutputTracks, nsTArray<RefPtr<ProcessedMediaTrack>>()),
|
||||
INIT_CANONICAL(mOutputPrincipal, PRINCIPAL_HANDLE_NONE),
|
||||
|
@ -387,11 +387,8 @@ void MediaDecoder::Shutdown() {
|
|||
// Ensure we always unregister asynchronously in order not to disrupt
|
||||
// the hashtable iterating in MediaShutdownManager::Shutdown().
|
||||
RefPtr<MediaDecoder> self = this;
|
||||
nsCOMPtr<nsIRunnable> r =
|
||||
NS_NewRunnableFunction("MediaDecoder::Shutdown", [self]() {
|
||||
self->mVideoFrameContainer = nullptr;
|
||||
self->ShutdownInternal();
|
||||
});
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
"MediaDecoder::Shutdown", [self]() { self->ShutdownInternal(); });
|
||||
mAbstractMainThread->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
|
@ -533,13 +530,14 @@ void MediaDecoder::OnStoreDecoderBenchmark(const VideoInfo& aInfo) {
|
|||
|
||||
void MediaDecoder::ShutdownInternal() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mVideoFrameContainer = nullptr;
|
||||
mSecondaryVideoContainer = nullptr;
|
||||
MediaShutdownManager::Instance().Unregister(this);
|
||||
}
|
||||
|
||||
void MediaDecoder::FinishShutdown() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
SetStateMachine(nullptr);
|
||||
mVideoFrameContainer = nullptr;
|
||||
ShutdownInternal();
|
||||
}
|
||||
|
||||
|
@ -1006,8 +1004,8 @@ void MediaDecoder::UpdateVideoDecodeMode() {
|
|||
return;
|
||||
}
|
||||
|
||||
// If mIsCloningVisually is set, never suspend the video decoder.
|
||||
if (mIsCloningVisually) {
|
||||
// If mSecondaryVideoContainer is set, never suspend the video decoder.
|
||||
if (mSecondaryVideoContainer.Ref()) {
|
||||
LOG("UpdateVideoDecodeMode(), set Normal because the element is cloning "
|
||||
"itself visually to another video container.");
|
||||
mDecoderStateMachine->SetVideoDecodeMode(VideoDecodeMode::Normal);
|
||||
|
@ -1072,11 +1070,15 @@ bool MediaDecoder::HasSuspendTaint() const {
|
|||
return mHasSuspendTaint;
|
||||
}
|
||||
|
||||
void MediaDecoder::SetCloningVisually(bool aIsCloningVisually) {
|
||||
if (mIsCloningVisually != aIsCloningVisually) {
|
||||
mIsCloningVisually = aIsCloningVisually;
|
||||
UpdateVideoDecodeMode();
|
||||
void MediaDecoder::SetSecondaryVideoContainer(
|
||||
RefPtr<VideoFrameContainer> aSecondaryVideoContainer) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
AbstractThread::AutoEnter context(AbstractMainThread());
|
||||
if (mSecondaryVideoContainer.Ref() == aSecondaryVideoContainer) {
|
||||
return;
|
||||
}
|
||||
mSecondaryVideoContainer = std::move(aSecondaryVideoContainer);
|
||||
UpdateVideoDecodeMode();
|
||||
}
|
||||
|
||||
bool MediaDecoder::IsMediaSeekable() {
|
||||
|
|
|
@ -308,10 +308,11 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||
// Returns true if the decoder can't participate in suspend-video-decoder.
|
||||
bool HasSuspendTaint() const;
|
||||
|
||||
void SetCloningVisually(bool aIsCloningVisually);
|
||||
|
||||
void UpdateVideoDecodeMode();
|
||||
|
||||
void SetSecondaryVideoContainer(
|
||||
RefPtr<VideoFrameContainer> aSecondaryVideoContainer);
|
||||
|
||||
void SetIsBackgroundVideoDecodingAllowed(bool aAllowed);
|
||||
|
||||
bool IsVideoDecodingSuspended() const;
|
||||
|
@ -567,10 +568,6 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||
// disabled.
|
||||
bool mHasSuspendTaint;
|
||||
|
||||
// True if the decoder is sending video to a secondary container, and should
|
||||
// not suspend the decoder.
|
||||
bool mIsCloningVisually;
|
||||
|
||||
MediaDecoderOwner::NextFrameStatus mNextFrameStatus =
|
||||
MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
|
||||
|
||||
|
@ -623,6 +620,10 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||
// set.
|
||||
Canonical<RefPtr<AudioDeviceInfo>> mSinkDevice;
|
||||
|
||||
// Set if the decoder is sending video to a secondary container. While set we
|
||||
// should not suspend the decoder.
|
||||
Canonical<RefPtr<VideoFrameContainer>> mSecondaryVideoContainer;
|
||||
|
||||
// Whether this MediaDecoder's output is captured. When captured, all decoded
|
||||
// data must be played out through mOutputTracks.
|
||||
Canonical<bool> mOutputCaptured;
|
||||
|
@ -668,6 +669,10 @@ class MediaDecoder : public DecoderDoctorLifeLogger<MediaDecoder> {
|
|||
AbstractCanonical<RefPtr<AudioDeviceInfo>>* CanonicalSinkDevice() {
|
||||
return &mSinkDevice;
|
||||
}
|
||||
AbstractCanonical<RefPtr<VideoFrameContainer>>*
|
||||
CanonicalSecondaryVideoContainer() {
|
||||
return &mSecondaryVideoContainer;
|
||||
}
|
||||
AbstractCanonical<bool>* CanonicalOutputCaptured() {
|
||||
return &mOutputCaptured;
|
||||
}
|
||||
|
|
|
@ -2592,6 +2592,7 @@ RefPtr<ShutdownPromise> MediaDecoderStateMachine::ShutdownState::Enter() {
|
|||
master->mPreservesPitch.DisconnectIfConnected();
|
||||
master->mLooping.DisconnectIfConnected();
|
||||
master->mSinkDevice.DisconnectIfConnected();
|
||||
master->mSecondaryVideoContainer.DisconnectIfConnected();
|
||||
master->mOutputCaptured.DisconnectIfConnected();
|
||||
master->mOutputTracks.DisconnectIfConnected();
|
||||
master->mOutputPrincipal.DisconnectIfConnected();
|
||||
|
@ -2643,6 +2644,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||
INIT_MIRROR(mPreservesPitch, true),
|
||||
INIT_MIRROR(mLooping, false),
|
||||
INIT_MIRROR(mSinkDevice, nullptr),
|
||||
INIT_MIRROR(mSecondaryVideoContainer, nullptr),
|
||||
INIT_MIRROR(mOutputCaptured, false),
|
||||
INIT_MIRROR(mOutputTracks, nsTArray<RefPtr<ProcessedMediaTrack>>()),
|
||||
INIT_MIRROR(mOutputPrincipal, PRINCIPAL_HANDLE_NONE),
|
||||
|
@ -2679,6 +2681,8 @@ void MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder) {
|
|||
mPreservesPitch.Connect(aDecoder->CanonicalPreservesPitch());
|
||||
mLooping.Connect(aDecoder->CanonicalLooping());
|
||||
mSinkDevice.Connect(aDecoder->CanonicalSinkDevice());
|
||||
mSecondaryVideoContainer.Connect(
|
||||
aDecoder->CanonicalSecondaryVideoContainer());
|
||||
mOutputCaptured.Connect(aDecoder->CanonicalOutputCaptured());
|
||||
mOutputTracks.Connect(aDecoder->CanonicalOutputTracks());
|
||||
mOutputPrincipal.Connect(aDecoder->CanonicalOutputPrincipal());
|
||||
|
@ -2691,6 +2695,8 @@ void MediaDecoderStateMachine::InitializationTask(MediaDecoder* aDecoder) {
|
|||
&MediaDecoderStateMachine::PreservesPitchChanged);
|
||||
mWatchManager.Watch(mPlayState, &MediaDecoderStateMachine::PlayStateChanged);
|
||||
mWatchManager.Watch(mLooping, &MediaDecoderStateMachine::LoopingChanged);
|
||||
mWatchManager.Watch(mSecondaryVideoContainer,
|
||||
&MediaDecoderStateMachine::UpdateSecondaryVideoContainer);
|
||||
mWatchManager.Watch(mOutputCaptured,
|
||||
&MediaDecoderStateMachine::UpdateOutputCaptured);
|
||||
mWatchManager.Watch(mOutputTracks,
|
||||
|
@ -3613,15 +3619,10 @@ RefPtr<GenericPromise> MediaDecoderStateMachine::SetSink(
|
|||
return GenericPromise::CreateAndResolve(wasPlaying, __func__);
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::SetSecondaryVideoContainer(
|
||||
const RefPtr<VideoFrameContainer>& aSecondary) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
RefPtr<MediaDecoderStateMachine> self = this;
|
||||
Unused << InvokeAsync(OwnerThread(), __func__, [self, aSecondary]() {
|
||||
self->mMediaSink->SetSecondaryVideoContainer(aSecondary);
|
||||
return GenericPromise::CreateAndResolve(true, __func__);
|
||||
});
|
||||
void MediaDecoderStateMachine::UpdateSecondaryVideoContainer() {
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mMediaSink);
|
||||
mMediaSink->SetSecondaryVideoContainer(mSecondaryVideoContainer.Ref());
|
||||
}
|
||||
|
||||
TimeUnit MediaDecoderStateMachine::AudioEndTime() const {
|
||||
|
|
|
@ -269,9 +269,6 @@ class MediaDecoderStateMachine
|
|||
|
||||
RefPtr<GenericPromise> InvokeSetSink(RefPtr<AudioDeviceInfo> aSink);
|
||||
|
||||
void SetSecondaryVideoContainer(
|
||||
const RefPtr<VideoFrameContainer>& aSecondary);
|
||||
|
||||
private:
|
||||
class StateObject;
|
||||
class DecodeMetadataState;
|
||||
|
@ -375,6 +372,7 @@ class MediaDecoderStateMachine
|
|||
void SetPlaybackRate(double aPlaybackRate);
|
||||
void PreservesPitchChanged();
|
||||
void LoopingChanged();
|
||||
void UpdateSecondaryVideoContainer();
|
||||
void UpdateOutputCaptured();
|
||||
void OutputTracksChanged();
|
||||
void OutputPrincipalChanged();
|
||||
|
@ -708,6 +706,10 @@ class MediaDecoderStateMachine
|
|||
// set.
|
||||
Mirror<RefPtr<AudioDeviceInfo>> mSinkDevice;
|
||||
|
||||
// Set if the decoder is sending video to a secondary container. While set we
|
||||
// should not suspend the decoder.
|
||||
Mirror<RefPtr<VideoFrameContainer>> mSecondaryVideoContainer;
|
||||
|
||||
// Whether all output should be captured into mOutputTracks. While true, the
|
||||
// media sink will only play if there are output tracks.
|
||||
Mirror<bool> mOutputCaptured;
|
||||
|
|
Загрузка…
Ссылка в новой задаче