summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/wmf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
commitdef92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch)
tree2ef34b9ad8bb9a9220e05d60352558b15f513894 /dom/media/platforms/wmf
parentAdding debian version 125.0.3-1. (diff)
downloadfirefox-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.cpp73
-rw-r--r--dom/media/platforms/wmf/MFCDMSession.cpp3
-rw-r--r--dom/media/platforms/wmf/MFMediaEngineStream.cpp9
-rw-r--r--dom/media/platforms/wmf/WMFDataEncoderUtils.h1
-rw-r--r--dom/media/platforms/wmf/WMFEncoderModule.cpp7
-rw-r--r--dom/media/platforms/wmf/WMFUtils.cpp4
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;
}