Bug 852915 - Disable MP3 playback using WMF on Win7SP0 to prevent random crashes. r=bbondy

This commit is contained in:
Chris Pearce 2013-04-18 16:38:14 +12:00
Родитель 144880157b
Коммит 3fa3e4a95c
5 изменённых файлов: 79 добавлений и 9 удалений

Просмотреть файл

@ -21,6 +21,27 @@ MediaDecoderStateMachine* WMFDecoder::CreateStateMachine()
return new MediaDecoderStateMachine(this, new WMFReader(this));
}
/* static */
bool
WMFDecoder::IsMP3Supported()
{
if (!MediaDecoder::IsWMFEnabled()) {
return false;
}
if (WinUtils::GetWindowsVersion() != WinUtils::WIN7_VERSION) {
return true;
}
// We're on Windows 7. MP3 support is disabled if no service pack
// is installed, as it's crashy on Win7 SP0.
UINT spMajorVer = 0, spMinorVer = 0;
if (!WinUtils::GetWindowsServicePackVersion(spMajorVer, spMinorVer)) {
// Um... We can't determine the service pack version... Just block
// MP3 as a precaution...
return false;
}
return spMajorVer != 0;
}
bool
WMFDecoder::GetSupportedCodecs(const nsACString& aType,
char const *const ** aCodecList)
@ -30,13 +51,15 @@ WMFDecoder::GetSupportedCodecs(const nsACString& aType,
return false;
// Assume that if LoadDLLs() didn't fail, we can playback the types that
// we know should be supported on Windows 7+ using WMF.
// we know should be supported by Windows Media Foundation.
static char const *const mp3AudioCodecs[] = {
"mp3",
nullptr
};
if (aType.EqualsASCII("audio/mpeg") ||
aType.EqualsASCII("audio/mp3")) {
if ((aType.EqualsASCII("audio/mpeg") || aType.EqualsASCII("audio/mp3")) &&
IsMP3Supported()) {
// Note: We block MP3 playback on Window 7 SP0 since it seems to crash
// in some circumstances.
if (aCodecList) {
*aCodecList = mp3AudioCodecs;
}

Просмотреть файл

@ -42,6 +42,10 @@ public:
// Returns true if the WMF backend is preffed on, and we're running on a
// version of Windows which is likely to support WMF.
static bool IsEnabled();
// Returns true if MP3 decoding is enabled on this system. We block
// MP3 playback on Windows 7 SP0, since it's crashy on that platform.
static bool IsMP3Supported();
};
} // namespace mozilla

Просмотреть файл

@ -388,6 +388,28 @@ WMFReader::ConfigureVideoDecoder()
return S_OK;
}
static void
GetSupportedAudioCodecs(const GUID** aCodecs, uint32_t* aNumCodecs)
{
MOZ_ASSERT(aCodecs);
MOZ_ASSERT(aNumCodecs);
if (WMFDecoder::IsMP3Supported()) {
static const GUID codecs[] = {
MFAudioFormat_AAC,
MFAudioFormat_MP3
};
*aCodecs = codecs;
*aNumCodecs = NS_ARRAY_LENGTH(codecs);
} else {
static const GUID codecs[] = {
MFAudioFormat_AAC
};
*aCodecs = codecs;
*aNumCodecs = NS_ARRAY_LENGTH(codecs);
}
}
HRESULT
WMFReader::ConfigureAudioDecoder()
{
@ -399,15 +421,15 @@ WMFReader::ConfigureAudioDecoder()
return S_OK;
}
static const GUID MP4AudioTypes[] = {
MFAudioFormat_AAC,
MFAudioFormat_MP3
};
const GUID* codecs;
uint32_t numCodecs = 0;
GetSupportedAudioCodecs(&codecs, &numCodecs);
HRESULT hr = ConfigureSourceReaderStream(mSourceReader,
MF_SOURCE_READER_FIRST_AUDIO_STREAM,
MFAudioFormat_Float,
MP4AudioTypes,
NS_ARRAY_LENGTH(MP4AudioTypes));
codecs,
numCodecs);
if (FAILED(hr)) {
NS_WARNING("Failed to configure WMF Audio decoder for PCM output");
return hr;

Просмотреть файл

@ -73,6 +73,23 @@ WinUtils::GetWindowsVersion()
return static_cast<WinVersion>(version);
}
/* static */
bool
WinUtils::GetWindowsServicePackVersion(UINT& aOutMajor, UINT& aOutMinor)
{
OSVERSIONINFOEX osInfo;
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
// This cast is safe and supposed to be here, don't worry
if (!::GetVersionEx((OSVERSIONINFO*)&osInfo)) {
return false;
}
aOutMajor = osInfo.wServicePackMajor;
aOutMinor = osInfo.wServicePackMinor;
return true;
}
/* static */
bool
WinUtils::PeekMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage,

Просмотреть файл

@ -49,6 +49,10 @@ public:
};
static WinVersion GetWindowsVersion();
// Retrieves the Service Pack version number.
// Returns true on success, false on failure.
static bool GetWindowsServicePackVersion(UINT& aOutMajor, UINT& aOutMinor);
/**
* PeekMessage() and GetMessage() are wrapper methods for PeekMessageW(),
* GetMessageW(), ITfMessageMgr::PeekMessageW() and