From 6ad01d940bd614ba70578800579067179bdb5947 Mon Sep 17 00:00:00 2001 From: EAZYBLACK Date: Sun, 13 Sep 2026 10:42:24 +0300 Subject: [PATCH] Add Hardware Accelerated VP9 Support This is Windows 10+ only for now due to a vp9 decoder mft being needed Fix for older windows is being worked on. --- dom/base/nsDOMWindowUtils.cpp | 36 +++++++++++++++++++ dom/interfaces/base/nsIDOMWindowUtils.idl | 7 ++++ dom/media/platforms/wmf/DXVA2Manager.cpp | 18 +++++++--- dom/media/platforms/wmf/WMFDecoderModule.cpp | 6 ++++ dom/media/platforms/wmf/WMFDecoderModule.h | 1 + modules/libpref/init/all.js | 4 --- toolkit/content/aboutSupport.js | 1 + .../chrome/global/aboutSupport.properties | 1 + toolkit/modules/Troubleshoot.jsm | 9 +++++ 9 files changed, 74 insertions(+), 9 deletions(-) diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index be9c16d0ec..07b2beeb76 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -30,6 +30,9 @@ #ifdef MOZ_FMP4 #include "MP4Decoder.h" #endif +#include "WMFDecoderModule.h" +#include "MediaPrefs.h" +#include "mozilla/gfx/gfxVars.h" #include "CubebUtils.h" #include "nsIScrollableFrame.h" @@ -2360,6 +2363,39 @@ nsDOMWindowUtils::GetSupportsHardwareH264Decoding(JS::MutableHandle a return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::GetSupportsHardwareVP9Decoding(JS::MutableHandle aPromise) +{ + nsCOMPtr window = do_QueryReferent(mWindow); + NS_ENSURE_STATE(window); + nsCOMPtr parentObject = + do_QueryInterface(window->GetCurrentInnerWindow()); + NS_ENSURE_STATE(parentObject); + + ErrorResult rv; + RefPtr promise = Promise::Create(parentObject, rv); + if (rv.Failed()) { + return rv.StealNSResult(); + } + +#if defined(XP_WIN) && defined(MOZ_WMF) + if (!MediaPrefs::PDMWMFVP9DecoderEnabled()) { + promise->MaybeResolve(NS_LITERAL_STRING("No; media.wmf.vp9.enabled is false")); + } else if (!gfx::gfxVars::CanUseHardwareVideoDecoding()) { + promise->MaybeResolve(NS_LITERAL_STRING("No; hardware video decoding disabled")); + } else if (WMFDecoderModule::HasVP9()) { + promise->MaybeResolve(NS_LITERAL_STRING("Yes")); + } else { + promise->MaybeResolve(NS_LITERAL_STRING("No; MFT unavailable")); + } +#else + promise->MaybeResolve(NS_LITERAL_STRING("No; not supported on this platform")); +#endif + + aPromise.setObject(*promise->PromiseObj()); + return NS_OK; +} + NS_IMETHODIMP nsDOMWindowUtils::GetCurrentAudioBackend(nsAString& aBackend) { diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index cd695cf186..baf886f347 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -1419,6 +1419,13 @@ interface nsIDOMWindowUtils : nsISupports { * in hardware. */ readonly attribute jsval supportsHardwareH264Decoding; + /** + * Returns a Promise that will be resolved with a string once the capabilities + * of the vp9 decoder have been determined. + * Success does not mean that all vp9 video decoding will be done + * in hardware. + */ + readonly attribute jsval supportsHardwareVP9Decoding; /** * Returns the current audio backend as a free-form string. diff --git a/dom/media/platforms/wmf/DXVA2Manager.cpp b/dom/media/platforms/wmf/DXVA2Manager.cpp index 304b91ed36..f985dfb3ea 100644 --- a/dom/media/platforms/wmf/DXVA2Manager.cpp +++ b/dom/media/platforms/wmf/DXVA2Manager.cpp @@ -185,6 +185,10 @@ static const GUID DXVA2_Intel_ModeH264_E = { 0x604F8E68, 0x4951, 0x4c54, { 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6 } }; +static const GUID DXVA2_ModeVP9_VLD_Profile0 = { + 0x463707f8, 0xa1d0, 0x4585, { 0x87, 0x6d, 0x83, 0xaa, 0x6d, 0x60, 0xb8, 0x9e } +}; + // This tests if a DXVA video decoder can be created for the given media type/resolution. // It uses the same decoder device (DXVA2_ModeH264_E - DXVA2_ModeH264_VLD_NoFGT) as the H264 // decoder MFT provided by windows (CLSID_CMSH264DecoderMFT) uses, so we can use it to determine @@ -388,7 +392,8 @@ D3D9DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor, decoderDevices[i] == DXVA2_Intel_ModeH264_E) { mDecoderGUID = decoderDevices[i]; found = true; - break; + } else if (decoderDevices[i] == DXVA2_ModeVP9_VLD_Profile0) { + found = true; } } CoTaskMemFree(decoderDevices); @@ -690,10 +695,13 @@ D3D11DXVA2Manager::Init(layers::KnowsCompositor* aKnowsCompositor, for (UINT i = 0; i < profileCount; i++) { GUID id; hr = videoDevice->GetVideoDecoderProfile(i, &id); - if (SUCCEEDED(hr) && (id == DXVA2_ModeH264_E || id == DXVA2_Intel_ModeH264_E)) { - mDecoderGUID = id; - found = true; - break; + if (SUCCEEDED(hr)) { + if (id == DXVA2_ModeH264_E || id == DXVA2_Intel_ModeH264_E) { + mDecoderGUID = id; + found = true; + } else if (id == DXVA2_ModeVP9_VLD_Profile0) { + found = true; + } } } if (!found) { diff --git a/dom/media/platforms/wmf/WMFDecoderModule.cpp b/dom/media/platforms/wmf/WMFDecoderModule.cpp index 46e78fb17f..045977d2e6 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.cpp +++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp @@ -191,6 +191,12 @@ WMFDecoderModule::HasH264() return CanCreateWMFDecoder(); } +/* static */ bool +WMFDecoderModule::HasVP9() +{ + return CanCreateWMFDecoder(); +} + /* static */ bool WMFDecoderModule::HasAAC() { diff --git a/dom/media/platforms/wmf/WMFDecoderModule.h b/dom/media/platforms/wmf/WMFDecoderModule.h index 0cb4e86310..92b977031a 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.h +++ b/dom/media/platforms/wmf/WMFDecoderModule.h @@ -43,6 +43,7 @@ public: // require a "Media Feature Pack" to be installed. static bool HasAAC(); static bool HasH264(); + static bool HasVP9(); private: bool mWMFInitialized; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 9fbcbcab9c..3c86d48351 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -404,11 +404,7 @@ pref("media.wmf.enabled", true); pref("media.wmf.decoder.thread-count", -1); pref("media.wmf.low-latency.enabled", false); pref("media.wmf.skip-blacklist", false); -#ifdef NIGHTLY_BUILD pref("media.wmf.vp9.enabled", true); -#else -pref("media.wmf.vp9.enabled", false); -#endif pref("media.windows-media-foundation.allow-d3d11-dxva", true); pref("media.wmf.disable-d3d11-for-dlls", "igd11dxva64.dll: 20.19.15.4463, 20.19.15.4454, 20.19.15.4444, 20.19.15.4416, 20.19.15.4404, 20.19.15.4390, 20.19.15.4380, 20.19.15.4377, 20.19.15.4364, 20.19.15.4360, 20.19.15.4352, 20.19.15.4331, 20.19.15.4326, 20.19.15.4300; igd10iumd32.dll: 20.19.15.4444, 20.19.15.4424, 20.19.15.4409, 20.19.15.4390, 20.19.15.4380, 20.19.15.4360, 10.18.10.4358, 20.19.15.4331, 20.19.15.4312, 20.19.15.4300, 10.18.15.4281, 10.18.15.4279, 10.18.10.4276, 10.18.15.4268, 10.18.15.4256, 10.18.10.4252, 10.18.15.4248, 10.18.14.4112, 10.18.10.3958, 10.18.10.3496, 10.18.10.3431, 10.18.10.3412, 10.18.10.3355, 9.18.10.3234, 9.18.10.3071, 9.18.10.3055, 9.18.10.3006; igd10umd32.dll: 9.17.10.4229, 9.17.10.3040, 9.17.10.2857, 8.15.10.2274, 8.15.10.2272, 8.15.10.2246, 8.15.10.1840, 8.15.10.1808; igd10umd64.dll: 9.17.10.4229, 9.17.10.2857, 10.18.10.3496; isonyvideoprocessor.dll: 4.1.2247.8090, 4.1.2153.6200; tosqep.dll: 1.2.15.526, 1.1.12.201, 1.0.11.318, 1.0.11.215, 1.0.10.1224; tosqep64.dll: 1.1.12.201, 1.0.11.215; nvwgf2um.dll: 22.21.13.8253, 22.21.13.8233, 22.21.13.8205, 22.21.13.8189, 22.21.13.8178, 22.21.13.8165, 21.21.13.7892, 21.21.13.7878, 21.21.13.7866, 21.21.13.7849, 21.21.13.7654, 21.21.13.7653, 21.21.13.7633, 21.21.13.7619, 21.21.13.7563, 21.21.13.7306, 21.21.13.7290, 21.21.13.7270, 21.21.13.7254, 21.21.13.6939, 21.21.13.6926, 21.21.13.6909, 21.21.13.4201, 21.21.13.4200, 10.18.13.6881, 10.18.13.6839, 10.18.13.6510, 10.18.13.6472, 10.18.13.6143, 10.18.13.5946, 10.18.13.5923, 10.18.13.5921, 10.18.13.5891, 10.18.13.5887, 10.18.13.5582, 10.18.13.5445, 10.18.13.5382, 10.18.13.5362, 9.18.13.4788, 9.18.13.4752, 9.18.13.4725, 9.18.13.4709, 9.18.13.4195, 9.18.13.4192, 9.18.13.4144, 9.18.13.4052, 9.18.13.3788, 9.18.13.3523, 9.18.13.3235, 9.18.13.3165, 9.18.13.2723, 9.18.13.2702, 9.18.13.1422, 9.18.13.1407, 9.18.13.1106, 9.18.13.546; atidxx32.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32837, 20.19.0.32832, 8.17.10.682, 8.17.10.671, 8.17.10.661, 8.17.10.648, 8.17.10.644, 8.17.10.625, 8.17.10.605, 8.17.10.581, 8.17.10.569, 8.17.10.560, 8.17.10.545, 8.17.10.539, 8.17.10.531, 8.17.10.525, 8.17.10.520, 8.17.10.519, 8.17.10.514, 8.17.10.511, 8.17.10.494, 8.17.10.489, 8.17.10.483, 8.17.10.453, 8.17.10.451, 8.17.10.441, 8.17.10.436, 8.17.10.432, 8.17.10.425, 8.17.10.418, 8.17.10.414, 8.17.10.401, 8.17.10.395, 8.17.10.385, 8.17.10.378, 8.17.10.362, 8.17.10.355, 8.17.10.342, 8.17.10.331, 8.17.10.318, 8.17.10.310, 8.17.10.286, 8.17.10.269, 8.17.10.261, 8.17.10.247, 8.17.10.240, 8.15.10.212; atidxx64.dll: 21.19.151.3, 21.19.142.257, 21.19.137.514, 21.19.137.1, 21.19.134.1, 21.19.128.7, 21.19.128.4, 20.19.0.32832, 8.17.10.682, 8.17.10.661, 8.17.10.644, 8.17.10.625; nvumdshim.dll: 10.18.13.6822"); pref("media.wmf.disable-d3d9-for-dlls", "igdumd64.dll: 8.15.10.2189, 8.15.10.2119, 8.15.10.2104, 8.15.10.2102, 8.771.1.0; atiumd64.dll: 7.14.10.833, 7.14.10.867, 7.14.10.885, 7.14.10.903, 7.14.10.911, 8.14.10.768, 9.14.10.1001, 9.14.10.1017, 9.14.10.1080, 9.14.10.1128, 9.14.10.1162, 9.14.10.1171, 9.14.10.1183, 9.14.10.1197, 9.14.10.945, 9.14.10.972, 9.14.10.984, 9.14.10.996"); diff --git a/toolkit/content/aboutSupport.js b/toolkit/content/aboutSupport.js index 9684e80ba7..7026b651cc 100644 --- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -336,6 +336,7 @@ var snapshotFormatters = { addRowFromKey("features", "webgl2DriverExtensions"); addRowFromKey("features", "webgl2Extensions"); addRowFromKey("features", "supportsHardwareH264", "hardwareH264"); + addRowFromKey("features", "supportsHardwareVP9", "hardwareVP9"); addRowFromKey("features", "currentAudioBackend", "audioBackend"); addRowFromKey("features", "direct2DEnabled", "#Direct2D"); diff --git a/toolkit/locales/en-US/chrome/global/aboutSupport.properties b/toolkit/locales/en-US/chrome/global/aboutSupport.properties index b452514158..e2836d6afb 100644 --- a/toolkit/locales/en-US/chrome/global/aboutSupport.properties +++ b/toolkit/locales/en-US/chrome/global/aboutSupport.properties @@ -59,6 +59,7 @@ clearTypeParameters = ClearType Parameters compositing = Compositing hardwareH264 = Hardware H264 Decoding +hardwareVP9 = Hardware VP9 Decoding audioBackend = Audio Backend mainThreadNoOMTC = main thread, no OMTC yes = Yes diff --git a/toolkit/modules/Troubleshoot.jsm b/toolkit/modules/Troubleshoot.jsm index c25cbce433..d2f2b09cf2 100644 --- a/toolkit/modules/Troubleshoot.jsm +++ b/toolkit/modules/Troubleshoot.jsm @@ -357,6 +357,15 @@ var dataProviders = { promises.push(promise); } catch (e) {} + data.supportsHardwareVP9 = "Unknown"; + try { + let promise = winUtils.supportsHardwareVP9Decoding; + promise.then(function(v) { + data.supportsHardwareVP9 = v; + }); + promises.push(promise); + } catch (e) {} + data.currentAudioBackend = winUtils.currentAudioBackend; if (!data.numAcceleratedWindows && gfxInfo) {