Loading dom/media/ipc/RemoteMediaDataDecoder.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,12 @@ namespace mozilla { ##__VA_ARGS__) ##__VA_ARGS__) RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild) RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild) : mChild(aChild) { : mChild(aChild), mDescription("RemoteMediaDataDecoder"_ns), mProcessName("unknown"_ns), mCodecName("unknown"_ns), mIsHardwareAccelerated(false), mConversion(ConversionRequired::kNeedNone) { LOG("%p is created", this); LOG("%p is created", this); } } Loading Loading @@ -48,6 +53,7 @@ RefPtr<MediaDataDecoder::InitPromise> RemoteMediaDataDecoder::Init() { ->Then( ->Then( RemoteDecoderManagerChild::GetManagerThread(), __func__, RemoteDecoderManagerChild::GetManagerThread(), __func__, [self, this](TrackType aTrack) { [self, this](TrackType aTrack) { MutexAutoLock lock(mMutex); // If shutdown has started in the meantime shutdown promise may // If shutdown has started in the meantime shutdown promise may // be resloved before this task. In this case mChild will be null // be resloved before this task. In this case mChild will be null // and the init promise has to be canceled. // and the init promise has to be canceled. Loading Loading @@ -127,6 +133,7 @@ RefPtr<ShutdownPromise> RemoteMediaDataDecoder::Shutdown() { bool RemoteMediaDataDecoder::IsHardwareAccelerated( bool RemoteMediaDataDecoder::IsHardwareAccelerated( nsACString& aFailureReason) const { nsACString& aFailureReason) const { MutexAutoLock lock(mMutex); aFailureReason = mHardwareAcceleratedReason; aFailureReason = mHardwareAcceleratedReason; return mIsHardwareAccelerated; return mIsHardwareAccelerated; } } Loading @@ -145,18 +152,24 @@ void RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime) { MediaDataDecoder::ConversionRequired RemoteMediaDataDecoder::NeedsConversion() MediaDataDecoder::ConversionRequired RemoteMediaDataDecoder::NeedsConversion() const { const { MutexAutoLock lock(mMutex); return mConversion; return mConversion; } } nsCString RemoteMediaDataDecoder::GetDescriptionName() const { nsCString RemoteMediaDataDecoder::GetDescriptionName() const { MutexAutoLock lock(mMutex); return mDescription; return mDescription; } } nsCString RemoteMediaDataDecoder::GetProcessName() const { nsCString RemoteMediaDataDecoder::GetProcessName() const { MutexAutoLock lock(mMutex); return mProcessName; return mProcessName; } } nsCString RemoteMediaDataDecoder::GetCodecName() const { return mCodecName; } nsCString RemoteMediaDataDecoder::GetCodecName() const { MutexAutoLock lock(mMutex); return mCodecName; } #undef LOG #undef LOG Loading dom/media/ipc/RemoteMediaDataDecoder.h +9 −7 Original line number Original line Diff line number Diff line Loading @@ -53,14 +53,16 @@ class RemoteMediaDataDecoder final // destructor when we can guarantee no other threads are accessing it). Only // destructor when we can guarantee no other threads are accessing it). Only // read from the manager thread. // read from the manager thread. RefPtr<RemoteDecoderChild> mChild; RefPtr<RemoteDecoderChild> mChild; mutable Mutex mMutex{"RemoteMediaDataDecoder"}; // Only ever written/modified during decoder initialisation. // Only ever written/modified during decoder initialisation. // As such can be accessed from any threads after that. nsCString mDescription MOZ_GUARDED_BY(mMutex); nsCString mDescription = "RemoteMediaDataDecoder"_ns; nsCString mProcessName MOZ_GUARDED_BY(mMutex); nsCString mProcessName = "unknown"_ns; nsCString mCodecName MOZ_GUARDED_BY(mMutex); nsCString mCodecName = "unknown"_ns; bool mIsHardwareAccelerated MOZ_GUARDED_BY(mMutex); bool mIsHardwareAccelerated = false; nsCString mHardwareAcceleratedReason MOZ_GUARDED_BY(mMutex); nsCString mHardwareAcceleratedReason; ConversionRequired mConversion MOZ_GUARDED_BY(mMutex); ConversionRequired mConversion = ConversionRequired::kNeedNone; }; }; } // namespace mozilla } // namespace mozilla Loading dom/media/platforms/wrappers/MediaChangeMonitor.cpp +7 −0 Original line number Original line Diff line number Diff line Loading @@ -668,6 +668,7 @@ RefPtr<ShutdownPromise> MediaChangeMonitor::ShutdownDecoder() { AssertOnThread(); AssertOnThread(); mConversionRequired.reset(); mConversionRequired.reset(); if (mDecoder) { if (mDecoder) { MutexAutoLock lock(mMutex); RefPtr<MediaDataDecoder> decoder = std::move(mDecoder); RefPtr<MediaDataDecoder> decoder = std::move(mDecoder); return decoder->Shutdown(); return decoder->Shutdown(); } } Loading Loading @@ -715,6 +716,7 @@ MediaChangeMonitor::CreateDecoder() { ->Then( ->Then( GetCurrentSerialEventTarget(), __func__, GetCurrentSerialEventTarget(), __func__, [self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) { [self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) { MutexAutoLock lock(mMutex); mDecoder = std::move(aDecoder); mDecoder = std::move(aDecoder); DDLINKCHILD("decoder", mDecoder.get()); DDLINKCHILD("decoder", mDecoder.get()); return CreateDecoderPromise::CreateAndResolve(true, __func__); return CreateDecoderPromise::CreateAndResolve(true, __func__); Loading Loading @@ -963,6 +965,11 @@ void MediaChangeMonitor::FlushThenShutdownDecoder( ->Track(mFlushRequest); ->Track(mFlushRequest); } } MediaDataDecoder* MediaChangeMonitor::GetDecoderOnNonOwnerThread() const { MutexAutoLock lock(mMutex); return mDecoder; } #undef LOG #undef LOG } // namespace mozilla } // namespace mozilla dom/media/platforms/wrappers/MediaChangeMonitor.h +20 −10 Original line number Original line Diff line number Diff line Loading @@ -41,34 +41,34 @@ class MediaChangeMonitor final RefPtr<ShutdownPromise> Shutdown() override; RefPtr<ShutdownPromise> Shutdown() override; bool IsHardwareAccelerated(nsACString& aFailureReason) const override; bool IsHardwareAccelerated(nsACString& aFailureReason) const override; nsCString GetDescriptionName() const override { nsCString GetDescriptionName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetDescriptionName(); return decoder->GetDescriptionName(); } } return "MediaChangeMonitor decoder (pending)"_ns; return "MediaChangeMonitor decoder (pending)"_ns; } } nsCString GetProcessName() const override { nsCString GetProcessName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetProcessName(); return decoder->GetProcessName(); } } return "MediaChangeMonitor"_ns; return "MediaChangeMonitor"_ns; } } nsCString GetCodecName() const override { nsCString GetCodecName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetCodecName(); return decoder->GetCodecName(); } } return "MediaChangeMonitor"_ns; return "MediaChangeMonitor"_ns; } } void SetSeekThreshold(const media::TimeUnit& aTime) override; void SetSeekThreshold(const media::TimeUnit& aTime) override; bool SupportDecoderRecycling() const override { bool SupportDecoderRecycling() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->SupportDecoderRecycling(); return decoder->SupportDecoderRecycling(); } } return false; return false; } } ConversionRequired NeedsConversion() const override { ConversionRequired NeedsConversion() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->NeedsConversion(); return decoder->NeedsConversion(); } } // Default so no conversion is performed. // Default so no conversion is performed. return ConversionRequired::kNeedNone; return ConversionRequired::kNeedNone; Loading Loading @@ -97,6 +97,9 @@ class MediaChangeMonitor final MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread()); MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread()); } } // This is used for getting decoder debug info on other threads. Thread-safe. MediaDataDecoder* GetDecoderOnNonOwnerThread() const; bool CanRecycleDecoder() const; bool CanRecycleDecoder() const; typedef MozPromise<bool, MediaResult, true /* exclusive */> typedef MozPromise<bool, MediaResult, true /* exclusive */> Loading Loading @@ -137,6 +140,13 @@ class MediaChangeMonitor final const CreateDecoderParamsForAsync mParams; const CreateDecoderParamsForAsync mParams; // Keep any seek threshold set for after decoder creation and initialization. // Keep any seek threshold set for after decoder creation and initialization. Maybe<media::TimeUnit> mPendingSeekThreshold; Maybe<media::TimeUnit> mPendingSeekThreshold; // This lock is used for mDecoder specifically, but it doens't need to be used // for every places accessing mDecoder which is mostly on the owner thread. // However, when requesting decoder debug info, it can happen on other // threads, so we need this mutex to avoid the data race of // creating/destroying decoder and accessing decoder's debug info. mutable Mutex MOZ_ANNOTATED mMutex{"MediaChangeMonitor"}; }; }; } // namespace mozilla } // namespace mozilla Loading Loading
dom/media/ipc/RemoteMediaDataDecoder.cpp +15 −2 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,12 @@ namespace mozilla { ##__VA_ARGS__) ##__VA_ARGS__) RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild) RemoteMediaDataDecoder::RemoteMediaDataDecoder(RemoteDecoderChild* aChild) : mChild(aChild) { : mChild(aChild), mDescription("RemoteMediaDataDecoder"_ns), mProcessName("unknown"_ns), mCodecName("unknown"_ns), mIsHardwareAccelerated(false), mConversion(ConversionRequired::kNeedNone) { LOG("%p is created", this); LOG("%p is created", this); } } Loading Loading @@ -48,6 +53,7 @@ RefPtr<MediaDataDecoder::InitPromise> RemoteMediaDataDecoder::Init() { ->Then( ->Then( RemoteDecoderManagerChild::GetManagerThread(), __func__, RemoteDecoderManagerChild::GetManagerThread(), __func__, [self, this](TrackType aTrack) { [self, this](TrackType aTrack) { MutexAutoLock lock(mMutex); // If shutdown has started in the meantime shutdown promise may // If shutdown has started in the meantime shutdown promise may // be resloved before this task. In this case mChild will be null // be resloved before this task. In this case mChild will be null // and the init promise has to be canceled. // and the init promise has to be canceled. Loading Loading @@ -127,6 +133,7 @@ RefPtr<ShutdownPromise> RemoteMediaDataDecoder::Shutdown() { bool RemoteMediaDataDecoder::IsHardwareAccelerated( bool RemoteMediaDataDecoder::IsHardwareAccelerated( nsACString& aFailureReason) const { nsACString& aFailureReason) const { MutexAutoLock lock(mMutex); aFailureReason = mHardwareAcceleratedReason; aFailureReason = mHardwareAcceleratedReason; return mIsHardwareAccelerated; return mIsHardwareAccelerated; } } Loading @@ -145,18 +152,24 @@ void RemoteMediaDataDecoder::SetSeekThreshold(const media::TimeUnit& aTime) { MediaDataDecoder::ConversionRequired RemoteMediaDataDecoder::NeedsConversion() MediaDataDecoder::ConversionRequired RemoteMediaDataDecoder::NeedsConversion() const { const { MutexAutoLock lock(mMutex); return mConversion; return mConversion; } } nsCString RemoteMediaDataDecoder::GetDescriptionName() const { nsCString RemoteMediaDataDecoder::GetDescriptionName() const { MutexAutoLock lock(mMutex); return mDescription; return mDescription; } } nsCString RemoteMediaDataDecoder::GetProcessName() const { nsCString RemoteMediaDataDecoder::GetProcessName() const { MutexAutoLock lock(mMutex); return mProcessName; return mProcessName; } } nsCString RemoteMediaDataDecoder::GetCodecName() const { return mCodecName; } nsCString RemoteMediaDataDecoder::GetCodecName() const { MutexAutoLock lock(mMutex); return mCodecName; } #undef LOG #undef LOG Loading
dom/media/ipc/RemoteMediaDataDecoder.h +9 −7 Original line number Original line Diff line number Diff line Loading @@ -53,14 +53,16 @@ class RemoteMediaDataDecoder final // destructor when we can guarantee no other threads are accessing it). Only // destructor when we can guarantee no other threads are accessing it). Only // read from the manager thread. // read from the manager thread. RefPtr<RemoteDecoderChild> mChild; RefPtr<RemoteDecoderChild> mChild; mutable Mutex mMutex{"RemoteMediaDataDecoder"}; // Only ever written/modified during decoder initialisation. // Only ever written/modified during decoder initialisation. // As such can be accessed from any threads after that. nsCString mDescription MOZ_GUARDED_BY(mMutex); nsCString mDescription = "RemoteMediaDataDecoder"_ns; nsCString mProcessName MOZ_GUARDED_BY(mMutex); nsCString mProcessName = "unknown"_ns; nsCString mCodecName MOZ_GUARDED_BY(mMutex); nsCString mCodecName = "unknown"_ns; bool mIsHardwareAccelerated MOZ_GUARDED_BY(mMutex); bool mIsHardwareAccelerated = false; nsCString mHardwareAcceleratedReason MOZ_GUARDED_BY(mMutex); nsCString mHardwareAcceleratedReason; ConversionRequired mConversion MOZ_GUARDED_BY(mMutex); ConversionRequired mConversion = ConversionRequired::kNeedNone; }; }; } // namespace mozilla } // namespace mozilla Loading
dom/media/platforms/wrappers/MediaChangeMonitor.cpp +7 −0 Original line number Original line Diff line number Diff line Loading @@ -668,6 +668,7 @@ RefPtr<ShutdownPromise> MediaChangeMonitor::ShutdownDecoder() { AssertOnThread(); AssertOnThread(); mConversionRequired.reset(); mConversionRequired.reset(); if (mDecoder) { if (mDecoder) { MutexAutoLock lock(mMutex); RefPtr<MediaDataDecoder> decoder = std::move(mDecoder); RefPtr<MediaDataDecoder> decoder = std::move(mDecoder); return decoder->Shutdown(); return decoder->Shutdown(); } } Loading Loading @@ -715,6 +716,7 @@ MediaChangeMonitor::CreateDecoder() { ->Then( ->Then( GetCurrentSerialEventTarget(), __func__, GetCurrentSerialEventTarget(), __func__, [self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) { [self = RefPtr{this}, this](RefPtr<MediaDataDecoder>&& aDecoder) { MutexAutoLock lock(mMutex); mDecoder = std::move(aDecoder); mDecoder = std::move(aDecoder); DDLINKCHILD("decoder", mDecoder.get()); DDLINKCHILD("decoder", mDecoder.get()); return CreateDecoderPromise::CreateAndResolve(true, __func__); return CreateDecoderPromise::CreateAndResolve(true, __func__); Loading Loading @@ -963,6 +965,11 @@ void MediaChangeMonitor::FlushThenShutdownDecoder( ->Track(mFlushRequest); ->Track(mFlushRequest); } } MediaDataDecoder* MediaChangeMonitor::GetDecoderOnNonOwnerThread() const { MutexAutoLock lock(mMutex); return mDecoder; } #undef LOG #undef LOG } // namespace mozilla } // namespace mozilla
dom/media/platforms/wrappers/MediaChangeMonitor.h +20 −10 Original line number Original line Diff line number Diff line Loading @@ -41,34 +41,34 @@ class MediaChangeMonitor final RefPtr<ShutdownPromise> Shutdown() override; RefPtr<ShutdownPromise> Shutdown() override; bool IsHardwareAccelerated(nsACString& aFailureReason) const override; bool IsHardwareAccelerated(nsACString& aFailureReason) const override; nsCString GetDescriptionName() const override { nsCString GetDescriptionName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetDescriptionName(); return decoder->GetDescriptionName(); } } return "MediaChangeMonitor decoder (pending)"_ns; return "MediaChangeMonitor decoder (pending)"_ns; } } nsCString GetProcessName() const override { nsCString GetProcessName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetProcessName(); return decoder->GetProcessName(); } } return "MediaChangeMonitor"_ns; return "MediaChangeMonitor"_ns; } } nsCString GetCodecName() const override { nsCString GetCodecName() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->GetCodecName(); return decoder->GetCodecName(); } } return "MediaChangeMonitor"_ns; return "MediaChangeMonitor"_ns; } } void SetSeekThreshold(const media::TimeUnit& aTime) override; void SetSeekThreshold(const media::TimeUnit& aTime) override; bool SupportDecoderRecycling() const override { bool SupportDecoderRecycling() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->SupportDecoderRecycling(); return decoder->SupportDecoderRecycling(); } } return false; return false; } } ConversionRequired NeedsConversion() const override { ConversionRequired NeedsConversion() const override { if (mDecoder) { if (RefPtr<MediaDataDecoder> decoder = GetDecoderOnNonOwnerThread()) { return mDecoder->NeedsConversion(); return decoder->NeedsConversion(); } } // Default so no conversion is performed. // Default so no conversion is performed. return ConversionRequired::kNeedNone; return ConversionRequired::kNeedNone; Loading Loading @@ -97,6 +97,9 @@ class MediaChangeMonitor final MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread()); MOZ_ASSERT(!mThread || mThread->IsOnCurrentThread()); } } // This is used for getting decoder debug info on other threads. Thread-safe. MediaDataDecoder* GetDecoderOnNonOwnerThread() const; bool CanRecycleDecoder() const; bool CanRecycleDecoder() const; typedef MozPromise<bool, MediaResult, true /* exclusive */> typedef MozPromise<bool, MediaResult, true /* exclusive */> Loading Loading @@ -137,6 +140,13 @@ class MediaChangeMonitor final const CreateDecoderParamsForAsync mParams; const CreateDecoderParamsForAsync mParams; // Keep any seek threshold set for after decoder creation and initialization. // Keep any seek threshold set for after decoder creation and initialization. Maybe<media::TimeUnit> mPendingSeekThreshold; Maybe<media::TimeUnit> mPendingSeekThreshold; // This lock is used for mDecoder specifically, but it doens't need to be used // for every places accessing mDecoder which is mostly on the owner thread. // However, when requesting decoder debug info, it can happen on other // threads, so we need this mutex to avoid the data race of // creating/destroying decoder and accessing decoder's debug info. mutable Mutex MOZ_ANNOTATED mMutex{"MediaChangeMonitor"}; }; }; } // namespace mozilla } // namespace mozilla Loading