Bug 1397141 - part2 : move the resolution check into WMFVideoMFTManager.
MozReview-Commit-ID: 760xXxgVSj
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -164,48 +164,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()
@@ -230,34 +198,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
@@ -8,16 +8,17 @@
#include "DXVA2Manager.h"
#include "GMPUtils.h" // For SplitAt. TODO: Move SplitAt to a central place.
#include "IMFYCbCrImage.h"
#include "ImageContainer.h"
#include "Layers.h"
#include "MP4Decoder.h"
#include "MediaInfo.h"
+#include "MediaPrefs.h"
#include "MediaTelemetryConstants.h"
#include "VPXDecoder.h"
#include "VideoUtils.h"
#include "WMFUtils.h"
#include "gfx2DGlue.h"
#include "gfxPrefs.h"
#include "gfxWindowsPlatform.h"
#include "mozilla/gfx/gfxVars.h"
@@ -94,16 +95,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)
{
}
@@ -526,25 +559,39 @@ WMFVideoMFTManager::InitializeDXVA()
bool
WMFVideoMFTManager::ValidateVideoInfo(MediaResult* aError)
{
// 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;
- if (mStreamType == H264 &&
- (mVideoInfo.mImage.width < MIN_H264_FRAME_DIMENSION ||
- mVideoInfo.mImage.height < MIN_H264_FRAME_DIMENSION)) {
- MOZ_ASSERT(aError);
+ 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 ||
+ MediaPrefs::PDMWMFAllowUnsupportedResolutions()) {
+ return mIsValid;
+ }
+
+ MOZ_ASSERT(aError);
+ if (mVideoInfo.mImage.width < MIN_H264_FRAME_DIMENSION ||
+ mVideoInfo.mImage.height < MIN_H264_FRAME_DIMENSION) {
*aError = MediaResult(
NS_ERROR_DOM_MEDIA_FATAL_ERR,
RESULT_DETAIL("Can't decode H.264 stream with width or height less than 48 pixels."));
mIsValid = false;
+ } else if (mVideoInfo.mImage.width > MAX_H264_FRAME_WIDTH ||
+ mVideoInfo.mImage.height > MAX_H264_FRAME_HEIGHT) {
+ *aError = MediaResult(
+ NS_ERROR_DOM_MEDIA_FATAL_ERR,
+ RESULT_DETAIL("Can't decode H.264 stream with oversize image resolution."));
+ mIsValid = false;
}
return mIsValid;
}
already_AddRefed<MFTDecoder>
WMFVideoMFTManager::LoadAMDVP9Decoder()
{