diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:50 +0000 |
commit | def92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch) | |
tree | 2ef34b9ad8bb9a9220e05d60352558b15f513894 /dom/media/platforms/wmf | |
parent | Adding debian version 125.0.3-1. (diff) | |
download | firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/platforms/wmf')
-rw-r--r-- | dom/media/platforms/wmf/DXVA2Manager.cpp | 73 | ||||
-rw-r--r-- | dom/media/platforms/wmf/MFCDMSession.cpp | 3 | ||||
-rw-r--r-- | dom/media/platforms/wmf/MFMediaEngineStream.cpp | 9 | ||||
-rw-r--r-- | dom/media/platforms/wmf/WMFDataEncoderUtils.h | 1 | ||||
-rw-r--r-- | dom/media/platforms/wmf/WMFEncoderModule.cpp | 7 | ||||
-rw-r--r-- | dom/media/platforms/wmf/WMFUtils.cpp | 4 |
6 files changed, 78 insertions, 19 deletions
diff --git a/dom/media/platforms/wmf/DXVA2Manager.cpp b/dom/media/platforms/wmf/DXVA2Manager.cpp index 36b424ab8e..9efe9dab55 100644 --- a/dom/media/platforms/wmf/DXVA2Manager.cpp +++ b/dom/media/platforms/wmf/DXVA2Manager.cpp @@ -21,6 +21,8 @@ #include "gfxCrashReporterUtils.h" #include "gfxWindowsPlatform.h" #include "mfapi.h" +#include "mozilla/AppShutdown.h" +#include "mozilla/ClearOnShutdown.h" #include "mozilla/StaticMutex.h" #include "mozilla/StaticPrefs_media.h" #include "mozilla/Telemetry.h" @@ -122,6 +124,38 @@ using layers::ImageContainer; using namespace layers; using namespace gfx; +StaticRefPtr<ID3D11Device> sDevice; +StaticMutex sDeviceMutex; + +// We found an issue where the ID3D11VideoDecoder won't release its underlying +// resources properly if the decoder iscreated from a compositor device by +// ourselves. This problem has been observed with both VP9 and, reportedly, AV1 +// decoders, it does not seem to affect the H264 decoder, but the underlying +// decoder created by MFT seems not having this issue. +// Therefore, when checking whether we can use hardware decoding, we should use +// a non-compositor device to create a decoder in order to prevent resource +// leaking that can significantly degrade the performance. For the actual +// decoding, we will still use the compositor device if it's avaiable in order +// to avoid video copying. +static ID3D11Device* GetDeviceForDecoderCheck() { + StaticMutexAutoLock lock(sDeviceMutex); + if (AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdown)) { + return nullptr; + } + if (!sDevice) { + sDevice = gfx::DeviceManagerDx::Get()->CreateDecoderDevice( + {DeviceManagerDx::DeviceFlag::disableDeviceReuse}); + auto clearOnShutdown = [] { ClearOnShutdown(&sDevice); }; + if (!NS_IsMainThread()) { + Unused << NS_DispatchToMainThread( + NS_NewRunnableFunction(__func__, clearOnShutdown)); + } else { + clearOnShutdown(); + } + } + return sDevice.get(); +} + void GetDXVA2ExtendedFormatFromMFMediaType(IMFMediaType* pType, DXVA2_ExtendedFormat* pFormat) { // Get the interlace mode. @@ -362,10 +396,10 @@ class D3D11DXVA2Manager : public DXVA2Manager { HRESULT CreateOutputSample(RefPtr<IMFSample>& aSample, ID3D11Texture2D* aTexture); + // This is used for check whether hw decoding is possible before using MFT for + // decoding. bool CanCreateDecoder(const D3D11_VIDEO_DECODER_DESC& aDesc) const; - already_AddRefed<ID3D11VideoDecoder> CreateDecoder( - const D3D11_VIDEO_DECODER_DESC& aDesc) const; void RefreshIMFSampleWrappers(); void ReleaseAllIMFSamples(); @@ -618,10 +652,11 @@ D3D11DXVA2Manager::InitInternal(layers::KnowsCompositor* aKnowsCompositor, mDevice = aDevice; if (!mDevice) { - bool useHardwareWebRender = - aKnowsCompositor && aKnowsCompositor->UsingHardwareWebRender(); - mDevice = - gfx::DeviceManagerDx::Get()->CreateDecoderDevice(useHardwareWebRender); + DeviceManagerDx::DeviceFlagSet flags; + if (aKnowsCompositor && aKnowsCompositor->UsingHardwareWebRender()) { + flags += DeviceManagerDx::DeviceFlag::isHardwareWebRenderInUse; + } + mDevice = gfx::DeviceManagerDx::Get()->CreateDecoderDevice(flags); if (!mDevice) { aFailureReason.AssignLiteral("Failed to create D3D11 device for decoder"); return E_FAIL; @@ -1155,20 +1190,26 @@ D3D11DXVA2Manager::ConfigureForSize(IMFMediaType* aInputType, bool D3D11DXVA2Manager::CanCreateDecoder( const D3D11_VIDEO_DECODER_DESC& aDesc) const { - RefPtr<ID3D11VideoDecoder> decoder = CreateDecoder(aDesc); - return decoder.get() != nullptr; -} + RefPtr<ID3D11Device> device = GetDeviceForDecoderCheck(); + if (!device) { + LOG("Can't create decoder due to lacking of ID3D11Device!"); + return false; + } -already_AddRefed<ID3D11VideoDecoder> D3D11DXVA2Manager::CreateDecoder( - const D3D11_VIDEO_DECODER_DESC& aDesc) const { RefPtr<ID3D11VideoDevice> videoDevice; - HRESULT hr = mDevice->QueryInterface( + HRESULT hr = device->QueryInterface( static_cast<ID3D11VideoDevice**>(getter_AddRefs(videoDevice))); - NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); + if (FAILED(hr)) { + LOG("Failed to query ID3D11VideoDevice!"); + return false; + } UINT configCount = 0; hr = videoDevice->GetVideoDecoderConfigCount(&aDesc, &configCount); - NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); + if (FAILED(hr)) { + LOG("Failed to get decoder config count!"); + return false; + } for (UINT i = 0; i < configCount; i++) { D3D11_VIDEO_DECODER_CONFIG config; @@ -1177,10 +1218,10 @@ already_AddRefed<ID3D11VideoDecoder> D3D11DXVA2Manager::CreateDecoder( RefPtr<ID3D11VideoDecoder> decoder; hr = videoDevice->CreateVideoDecoder(&aDesc, &config, decoder.StartAssignment()); - return decoder.forget(); + return decoder != nullptr; } } - return nullptr; + return false; } /* static */ diff --git a/dom/media/platforms/wmf/MFCDMSession.cpp b/dom/media/platforms/wmf/MFCDMSession.cpp index b797898abb..0ae4614f3b 100644 --- a/dom/media/platforms/wmf/MFCDMSession.cpp +++ b/dom/media/platforms/wmf/MFCDMSession.cpp @@ -11,6 +11,7 @@ #include "MFMediaEngineUtils.h" #include "GMPUtils.h" // ToHexString #include "mozilla/EMEUtils.h" +#include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/MediaKeyMessageEventBinding.h" #include "mozilla/dom/MediaKeyStatusMapBinding.h" #include "nsThreadUtils.h" @@ -244,7 +245,7 @@ void MFCDMSession::OnSessionKeysChange() { nsAutoCString keyIdString(ToHexString(keyId)); LOG("Append keyid-sz=%u, keyid=%s, status=%s", keyStatus.cbKeyId, keyIdString.get(), - ToMediaKeyStatusStr(ToMediaKeyStatus(keyStatus.eMediaKeyStatus))); + dom::GetEnumString(ToMediaKeyStatus(keyStatus.eMediaKeyStatus)).get()); keyInfos.AppendElement(MFCDMKeyInformation{ std::move(keyId), ToMediaKeyStatus(keyStatus.eMediaKeyStatus)}); } diff --git a/dom/media/platforms/wmf/MFMediaEngineStream.cpp b/dom/media/platforms/wmf/MFMediaEngineStream.cpp index 70ffa50142..5875b5a17c 100644 --- a/dom/media/platforms/wmf/MFMediaEngineStream.cpp +++ b/dom/media/platforms/wmf/MFMediaEngineStream.cpp @@ -11,6 +11,7 @@ #include "TimeUnits.h" #include "mozilla/ProfilerLabels.h" #include "mozilla/ProfilerMarkerTypes.h" +#include "mozilla/ScopeExit.h" #include "WMF.h" #include "WMFUtils.h" @@ -126,6 +127,13 @@ HRESULT MFMediaEngineStream::RuntimeClassInitialize( mTaskQueue = aParentSource->GetTaskQueue(); MOZ_ASSERT(mTaskQueue); mStreamId = aStreamId; + + auto errorExit = MakeScopeExit([&] { + SLOG("Failed to initialize media stream (id=%" PRIu64 ")", aStreamId); + mIsShutdown = true; + Unused << mMediaEventQueue->Shutdown(); + }); + RETURN_IF_FAILED(wmf::MFCreateEventQueue(&mMediaEventQueue)); ComPtr<IMFMediaType> mediaType; @@ -134,6 +142,7 @@ HRESULT MFMediaEngineStream::RuntimeClassInitialize( RETURN_IF_FAILED(GenerateStreamDescriptor(mediaType)); SLOG("Initialized %s (id=%" PRIu64 ", descriptorId=%lu)", GetDescriptionName().get(), aStreamId, mStreamDescriptorId); + errorExit.release(); return S_OK; } diff --git a/dom/media/platforms/wmf/WMFDataEncoderUtils.h b/dom/media/platforms/wmf/WMFDataEncoderUtils.h index 7472827b49..19f04e768f 100644 --- a/dom/media/platforms/wmf/WMFDataEncoderUtils.h +++ b/dom/media/platforms/wmf/WMFDataEncoderUtils.h @@ -32,7 +32,6 @@ static const GUID CodecToSubtype(CodecType aCodec) { case CodecType::VP9: return MFVideoFormat_VP90; default: - MOZ_ASSERT(false, "Unsupported codec"); return GUID_NULL; } } diff --git a/dom/media/platforms/wmf/WMFEncoderModule.cpp b/dom/media/platforms/wmf/WMFEncoderModule.cpp index f9f35db653..7b5af9bf50 100644 --- a/dom/media/platforms/wmf/WMFEncoderModule.cpp +++ b/dom/media/platforms/wmf/WMFEncoderModule.cpp @@ -12,6 +12,10 @@ namespace mozilla { extern LazyLogModule sPEMLog; bool WMFEncoderModule::SupportsCodec(CodecType aCodecType) const { + if (aCodecType > CodecType::_BeginAudio_ && + aCodecType < CodecType::_EndAudio_) { + return false; + } return CanCreateWMFEncoder(aCodecType); } @@ -19,6 +23,9 @@ bool WMFEncoderModule::Supports(const EncoderConfig& aConfig) const { if (!CanLikelyEncode(aConfig)) { return false; } + if (aConfig.IsAudio()) { + return false; + } return SupportsCodec(aConfig.mCodec); } diff --git a/dom/media/platforms/wmf/WMFUtils.cpp b/dom/media/platforms/wmf/WMFUtils.cpp index dda9df808e..bf5b8fe67d 100644 --- a/dom/media/platforms/wmf/WMFUtils.cpp +++ b/dom/media/platforms/wmf/WMFUtils.cpp @@ -333,7 +333,9 @@ GUID VideoMimeTypeToMediaFoundationSubtype(const nsACString& aMimeType) { if (MP4Decoder::IsHEVC(aMimeType)) { return MFVideoFormat_HEVC; } - NS_WARNING("Unsupport video mimetype"); + NS_WARNING(nsAutoCString(nsDependentCString("Unsupported video mimetype ") + + aMimeType) + .get()); return GUID_NULL; } |