Bug 1397141 - part2 : move resolution constraints to WMFVideoMFTManager
WMFDecoderModule should only focus on whether the mime type is supported or not.
Let WMFVideoMFTManager do the checking.
MozReview-Commit-ID: K6jPfrntu7s
--- a/dom/media/MediaPrefs.h
+++ b/dom/media/MediaPrefs.h
@@ -134,17 +134,16 @@ private:
DECL_MEDIA_PREF("media.ffvpx.enabled", PDMFFVPXEnabled, bool, true);
#endif
#ifdef XP_WIN
DECL_MEDIA_PREF("media.wmf.enabled", PDMWMFEnabled, bool, true);
DECL_MEDIA_PREF("media.wmf.skip-blacklist", PDMWMFSkipBlacklist, bool, false);
DECL_MEDIA_PREF("media.decoder-doctor.wmf-disabled-is-failure", DecoderDoctorWMFDisabledIsFailure, bool, false);
DECL_MEDIA_PREF("media.wmf.vp9.enabled", PDMWMFVP9DecoderEnabled, bool, true);
DECL_MEDIA_PREF("media.wmf.decoder.thread-count", PDMWMFThreadCount, int32_t, -1);
- DECL_MEDIA_PREF("media.wmf.allow-unsupported-resolutions", PDMWMFAllowUnsupportedResolutions, bool, false);
#endif
DECL_MEDIA_PREF("media.decoder.fuzzing.enabled", PDMFuzzingEnabled, bool, false);
DECL_MEDIA_PREF("media.decoder.fuzzing.video-output-minimum-interval-ms", PDMFuzzingInterval, uint32_t, 0);
DECL_MEDIA_PREF("media.decoder.fuzzing.dont-delay-inputexhausted", PDMFuzzingDelayInputExhausted, bool, true);
DECL_MEDIA_PREF("media.decoder.recycle.enabled", MediaDecoderCheckRecycling, bool, false);
DECL_MEDIA_PREF("media.decoder.skip-to-next-key-frame.enabled", MFRSkipToNextKeyFrameEnabled, bool, true);
DECL_MEDIA_PREF("media.gmp.decoder.enabled", PDMGMPEnabled, bool, true);
DECL_MEDIA_PREF("media.gmp.decoder.aac", GMPAACPreferred, uint32_t, 0);
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -168,48 +168,16 @@ CanCreateWMFDecoder()
StaticMutexAutoLock lock(sMutex);
static Maybe<bool> result;
if (result.isNothing()) {
result.emplace(CanCreateMFTDecoder(aGuid));
}
return result.value();
}
-static bool
-IsWin7H264Decoder4KCapable()
-{
- WCHAR systemPath[MAX_PATH + 1];
- if (!ConstructSystem32Path(L"msmpeg2vdec.dll", systemPath, MAX_PATH + 1)) {
- // Cannot build path -> Assume it's the old DLL or it's missing.
- return false;
- }
-
- DWORD zero;
- DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
- if (infoSize == 0) {
- // Can't get file info -> Assume it's the old DLL or it's missing.
- return false;
- }
- auto infoData = MakeUnique<unsigned char[]>(infoSize);
- VS_FIXEDFILEINFO *vInfo;
- UINT vInfoLen;
- if (GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) &&
- VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen))
- {
- uint64_t version =
- uint64_t(vInfo->dwFileVersionMS) << 32 | uint64_t(vInfo->dwFileVersionLS);
- // 12.0.9200.16426 & later allow for >1920x1088 resolutions.
- const uint64_t minimum =
- (uint64_t(12) << 48) | (uint64_t(9200) << 16) | uint64_t(16426);
- return version >= minimum;
- }
- // Can't get file version -> Assume it's the old DLL.
- return false;
-}
-
/* static */ bool
WMFDecoderModule::HasH264()
{
return CanCreateWMFDecoder<CLSID_CMSH264DecoderMFT>();
}
/* static */ bool
WMFDecoderModule::HasAAC()
@@ -234,34 +202,16 @@ WMFDecoderModule::Supports(const TrackIn
DecoderDoctorDiagnostics* aDiagnostics) const
{
if ((aTrackInfo.mMimeType.EqualsLiteral("audio/mp4a-latm") ||
aTrackInfo.mMimeType.EqualsLiteral("audio/mp4")) &&
WMFDecoderModule::HasAAC()) {
return true;
}
if (MP4Decoder::IsH264(aTrackInfo.mMimeType) && WMFDecoderModule::HasH264()) {
- if (!MediaPrefs::PDMWMFAllowUnsupportedResolutions()) {
- const VideoInfo* videoInfo = aTrackInfo.GetAsVideoInfo();
- MOZ_ASSERT(videoInfo);
- // Check Windows format constraints, based on:
- // https://msdn.microsoft.com/en-us/library/windows/desktop/dd797815(v=vs.85).aspx
- if (IsWin8OrLater() || IsWin7H264Decoder4KCapable()) {
- // Windows >7, and Win7 with recent-enough decoder, support at most
- // 4096x2304.
- if (videoInfo->mImage.width > 4096 || videoInfo->mImage.height > 2304) {
- return false;
- }
- } else {
- // Windows <=7 (with original decoder) supports at most 1920x1088.
- if (videoInfo->mImage.width > 1920 || videoInfo->mImage.height > 1088) {
- return false;
- }
- }
- }
return true;
}
if (aTrackInfo.mMimeType.EqualsLiteral("audio/mpeg") &&
CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) {
return true;
}
if (MediaPrefs::PDMWMFVP9DecoderEnabled()) {
if ((VPXDecoder::IsVP8(aTrackInfo.mMimeType) ||
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -94,16 +94,48 @@ extern const GUID CLSID_WebmMfVpxDec =
0xe3aaf548,
0xc9a4,
0x4c6e,
{ 0x23, 0x4d, 0x5a, 0xda, 0x37, 0x4b, 0x00, 0x00 }
};
namespace mozilla {
+static bool
+IsWin7H264Decoder4KCapable()
+{
+ WCHAR systemPath[MAX_PATH + 1];
+ if (!ConstructSystem32Path(L"msmpeg2vdec.dll", systemPath, MAX_PATH + 1)) {
+ // Cannot build path -> Assume it's the old DLL or it's missing.
+ return false;
+ }
+
+ DWORD zero;
+ DWORD infoSize = GetFileVersionInfoSizeW(systemPath, &zero);
+ if (infoSize == 0) {
+ // Can't get file info -> Assume it's the old DLL or it's missing.
+ return false;
+ }
+ auto infoData = MakeUnique<unsigned char[]>(infoSize);
+ VS_FIXEDFILEINFO *vInfo;
+ UINT vInfoLen;
+ if (GetFileVersionInfoW(systemPath, 0, infoSize, infoData.get()) &&
+ VerQueryValueW(infoData.get(), L"\\", (LPVOID*)&vInfo, &vInfoLen))
+ {
+ uint64_t version =
+ uint64_t(vInfo->dwFileVersionMS) << 32 | uint64_t(vInfo->dwFileVersionLS);
+ // 12.0.9200.16426 & later allow for >1920x1088 resolutions.
+ const uint64_t minimum =
+ (uint64_t(12) << 48) | (uint64_t(9200) << 16) | uint64_t(16426);
+ return version >= minimum;
+ }
+ // Can't get file version -> Assume it's the old DLL.
+ return false;
+}
+
template<class T>
class DeleteObjectTask: public Runnable {
public:
explicit DeleteObjectTask(nsAutoPtr<T>& aObject)
: Runnable("VideoUtils::DeleteObjectTask")
, mObject(aObject)
{
}
@@ -521,32 +553,49 @@ WMFVideoMFTManager::InitializeDXVA()
mDXVA2Manager = event->mDXVA2Manager;
return mDXVA2Manager != nullptr;
}
MediaResult
WMFVideoMFTManager::ValidateVideoInfo()
{
+ if (mStreamType != H264 ||
+ gfxPrefs::PDMWMFAllowUnsupportedResolutions()) {
+ return NS_OK;
+ }
+
// The WMF H.264 decoder is documented to have a minimum resolution
// 48x48 pixels. We've observed the decoder working for output smaller than
// that, but on some output it hangs in IMFTransform::ProcessOutput(), so
// we just reject streams which are less than the documented minimum.
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd797815(v=vs.85).aspx
+ const bool Is4KCapable = IsWin8OrLater() || IsWin7H264Decoder4KCapable();
static const int32_t MIN_H264_FRAME_DIMENSION = 48;
+ static const int32_t MAX_H264_FRAME_WIDTH = Is4KCapable ? 4096 : 1920;
+ static const int32_t MAX_H264_FRAME_HEIGHT = Is4KCapable ? 2304 : 1088;
+
if (mStreamType == H264 &&
(mVideoInfo.mImage.width < MIN_H264_FRAME_DIMENSION ||
mVideoInfo.mImage.height < MIN_H264_FRAME_DIMENSION)) {
mIsValid = false;
return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("Can't decode H.264 stream with width or "
"height less than 48 pixels."));
}
- return MediaResult(NS_OK);
+ if (mVideoInfo.mImage.width > MAX_H264_FRAME_WIDTH ||
+ mVideoInfo.mImage.height > MAX_H264_FRAME_HEIGHT) {
+ mIsValid = false;
+ return MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ RESULT_DETAIL("Can't decode H.264 stream because its "
+ "resolution is out of the maximum limitation"));
+ }
+
+ return NS_OK;
}
already_AddRefed<MFTDecoder>
WMFVideoMFTManager::LoadAMDVP9Decoder()
{
MOZ_ASSERT(mStreamType == VP9);
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -665,16 +665,17 @@ private:
DECL_GFX_PREF(Live, "media.windows-media-foundation.allow-d3d11-dxva", PDMWMFAllowD3D11, bool, true);
DECL_GFX_PREF(Live, "media.windows-media-foundation.max-dxva-videos", PDMWMFMaxDXVAVideos, uint32_t, 8);
DECL_GFX_PREF(Live, "media.windows-media-foundation.use-nv12-format", PDMWMFUseNV12Format, bool, true);
DECL_GFX_PREF(Once, "media.windows-media-foundation.use-sync-texture", PDMWMFUseSyncTexture, bool, true);
DECL_GFX_PREF(Live, "media.wmf.low-latency.enabled", PDMWMFLowLatencyEnabled, bool, false);
DECL_GFX_PREF(Live, "media.wmf.skip-blacklist", PDMWMFSkipBlacklist, bool, false);
DECL_GFX_PREF(Live, "media.wmf.deblacklisting-for-telemetry-in-gpu-process", PDMWMFDeblacklistingForTelemetryInGPUProcess, bool, false);
DECL_GFX_PREF(Live, "media.wmf.amd.vp9.enabled", PDMWMFAMDVP9DecoderEnabled, bool, true);
+ DECL_GFX_PREF(Live, "media.wmf.allow-unsupported-resolutions", PDMWMFAllowUnsupportedResolutions, bool, false);
#endif
// These affect how line scrolls from wheel events will be accelerated.
DECL_GFX_PREF(Live, "mousewheel.acceleration.factor", MouseWheelAccelerationFactor, int32_t, -1);
DECL_GFX_PREF(Live, "mousewheel.acceleration.start", MouseWheelAccelerationStart, int32_t, -1);
// This affects whether events will be routed through APZ or not.
DECL_GFX_PREF(Live, "mousewheel.system_scroll_override_on_root_content.enabled",