From 771993d760dd5c9cbc776d3698711316d5396b48 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Tue, 8 Dec 2020 06:42:51 +0000 Subject: [PATCH] Bug 1672087 - P2. Recreate remote decoder when parent dies. r=mattwoodrow,bryce The RDD process startup being asynchronous make the operation trivial. Unlike with the GPU process, we can immediately tell the MediaFormatDecoder that a new decoder is needed when the RDD died. Recovery will immediately occur with little visible interruption. Differential Revision: https://phabricator.services.mozilla.com/D98571 --- dom/media/ipc/RemoteAudioDecoder.cpp | 5 +++-- dom/media/ipc/RemoteDecoderChild.cpp | 20 +++++++++++++------- dom/media/ipc/RemoteDecoderChild.h | 4 ++-- dom/media/ipc/RemoteVideoDecoder.cpp | 4 +--- dom/media/ipc/RemoteVideoDecoder.h | 3 --- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/dom/media/ipc/RemoteAudioDecoder.cpp b/dom/media/ipc/RemoteAudioDecoder.cpp index 3db946f929eb..48250dc0c4bb 100644 --- a/dom/media/ipc/RemoteAudioDecoder.cpp +++ b/dom/media/ipc/RemoteAudioDecoder.cpp @@ -13,7 +13,8 @@ namespace mozilla { -RemoteAudioDecoderChild::RemoteAudioDecoderChild() : RemoteDecoderChild() {} +RemoteAudioDecoderChild::RemoteAudioDecoderChild() + : RemoteDecoderChild(RemoteDecodeIn::RddProcess) {} MediaResult RemoteAudioDecoderChild::ProcessOutput( DecodedOutputIPDL&& aDecodedData) { @@ -38,7 +39,7 @@ MediaResult RemoteAudioDecoderChild::InitIPDL( const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions) { RefPtr manager = - RemoteDecoderManagerChild::GetSingleton(RemoteDecodeIn::RddProcess); + RemoteDecoderManagerChild::GetSingleton(mLocation); // The manager isn't available because RemoteDecoderManagerChild has been // initialized with null end points and we don't want to decode video on RDD diff --git a/dom/media/ipc/RemoteDecoderChild.cpp b/dom/media/ipc/RemoteDecoderChild.cpp index 578de13fe04f..1cc957e98242 100644 --- a/dom/media/ipc/RemoteDecoderChild.cpp +++ b/dom/media/ipc/RemoteDecoderChild.cpp @@ -9,10 +9,10 @@ namespace mozilla { -RemoteDecoderChild::RemoteDecoderChild(bool aRecreatedOnCrash) +RemoteDecoderChild::RemoteDecoderChild(RemoteDecodeIn aLocation) : ShmemRecycleAllocator(this), - mThread(GetCurrentSerialEventTarget()), - mRecreatedOnCrash(aRecreatedOnCrash) { + mLocation(aLocation), + mThread(GetCurrentSerialEventTarget()) { MOZ_DIAGNOSTIC_ASSERT( RemoteDecoderManagerChild::GetManagerThread() && RemoteDecoderManagerChild::GetManagerThread()->IsOnCurrentThread(), @@ -30,9 +30,12 @@ void RemoteDecoderChild::HandleRejectionError( // longer be used. // The GPU/RDD process crashed. - if (mRecreatedOnCrash) { - // Defer reporting an error until we've recreated the manager so that - // it'll be safe for MediaFormatReader to recreate decoders + if (mLocation == RemoteDecodeIn::GpuProcess) { + // The GPU process will get automatically restarted by the parent process. + // Once it has been restarted the ContentChild will receive the message and + // will call GetManager()->InitForGPUProcess. + // We defer reporting an error until we've recreated the RemoteDecoder + // manager so that it'll be safe for MediaFormatReader to recreate decoders RefPtr self = this; GetManager()->RunWhenGPUProcessRecreated(NS_NewRunnableFunction( "RemoteDecoderChild::HandleRejectionError", @@ -42,7 +45,10 @@ void RemoteDecoderChild::HandleRejectionError( })); return; } - aCallback(MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__)); + // The RDD process is restarted on demand and asynchronously, we can + // immediately inform the caller that a new decoder is needed. The RDD will + // then be restarted during the new decoder creation. + aCallback(MediaResult(NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER, __func__)); } // ActorDestroy is called if the channel goes down while waiting for a response. diff --git a/dom/media/ipc/RemoteDecoderChild.h b/dom/media/ipc/RemoteDecoderChild.h index 7c89c5b2bbe9..7d9602497af7 100644 --- a/dom/media/ipc/RemoteDecoderChild.h +++ b/dom/media/ipc/RemoteDecoderChild.h @@ -24,7 +24,7 @@ class RemoteDecoderChild : public ShmemRecycleAllocator, public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderChild); - explicit RemoteDecoderChild(bool aRecreatedOnCrash = false); + explicit RemoteDecoderChild(RemoteDecodeIn aLocation); void ActorDestroy(ActorDestroyReason aWhy) override; @@ -56,6 +56,7 @@ class RemoteDecoderChild : public ShmemRecycleAllocator, RefPtr mIPDLSelfRef; MediaDataDecoder::DecodedData mDecodedData; + const RemoteDecodeIn mLocation; private: const nsCOMPtr mThread; @@ -74,7 +75,6 @@ class RemoteDecoderChild : public ShmemRecycleAllocator, nsCString mHardwareAcceleratedReason; nsCString mDescription; bool mIsHardwareAccelerated = false; - const bool mRecreatedOnCrash; MediaDataDecoder::ConversionRequired mConversion = MediaDataDecoder::ConversionRequired::kNeedNone; }; diff --git a/dom/media/ipc/RemoteVideoDecoder.cpp b/dom/media/ipc/RemoteVideoDecoder.cpp index fb8ec2e30d64..ad65cd8d25fe 100644 --- a/dom/media/ipc/RemoteVideoDecoder.cpp +++ b/dom/media/ipc/RemoteVideoDecoder.cpp @@ -55,9 +55,7 @@ KnowsCompositorVideo::TryCreateForIdentifier( } RemoteVideoDecoderChild::RemoteVideoDecoderChild(RemoteDecodeIn aLocation) - : RemoteDecoderChild(aLocation == RemoteDecodeIn::GpuProcess), - mBufferRecycleBin(new BufferRecycleBin), - mLocation(aLocation) {} + : RemoteDecoderChild(aLocation), mBufferRecycleBin(new BufferRecycleBin) {} MediaResult RemoteVideoDecoderChild::ProcessOutput( DecodedOutputIPDL&& aDecodedData) { diff --git a/dom/media/ipc/RemoteVideoDecoder.h b/dom/media/ipc/RemoteVideoDecoder.h index 8e1133342c5f..52bcdca9beb5 100644 --- a/dom/media/ipc/RemoteVideoDecoder.h +++ b/dom/media/ipc/RemoteVideoDecoder.h @@ -47,9 +47,6 @@ class RemoteVideoDecoderChild : public RemoteDecoderChild { private: RefPtr mBufferRecycleBin; - - // The location of the RemoteVideoDecoderParent - Gpu or Rdd process. - const RemoteDecodeIn mLocation; }; class RemoteVideoDecoderParent final : public RemoteDecoderParent {