Bug 1107889 - On Windows, detect when unable to play H.264/AAC (for example due to lacking service pack on Vista). r=kinetik,r=dmajor
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -11,16 +11,17 @@
#include "nsCharSeparatedTokenizer.h"
#ifdef MOZ_EME
#include "mozilla/CDMProxy.h"
#endif
#include "prlog.h"
#ifdef XP_WIN
#include "mozilla/WindowsVersion.h"
+#include "WMFDecoderModule.h"
#endif
#ifdef MOZ_FFMPEG
#include "FFmpegRuntimeLinker.h"
#endif
#ifdef MOZ_APPLEMEDIA
#include "apple/AppleDecoderModule.h"
#endif
#ifdef MOZ_WIDGET_ANDROID
@@ -58,16 +59,22 @@ static bool
IsSupportedAudioCodec(const nsAString& aCodec,
bool& aOutContainsAAC,
bool& aOutContainsMP3)
{
// AAC-LC or HE-AAC in M4A.
aOutContainsAAC = aCodec.EqualsASCII("mp4a.40.2") ||
aCodec.EqualsASCII("mp4a.40.5");
if (aOutContainsAAC) {
+#ifdef XP_WIN
+ if (!Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") &&
+ !WMFDecoderModule::HasAAC()) {
+ return false;
+ }
+#endif
return true;
}
#ifndef MOZ_GONK_MEDIACODEC // B2G doesn't support MP3 in MP4 yet.
aOutContainsMP3 = aCodec.EqualsASCII("mp3");
if (aOutContainsMP3) {
return true;
}
#else
@@ -80,16 +87,23 @@ static bool
IsSupportedH264Codec(const nsAString& aCodec)
{
int16_t profile = 0, level = 0;
if (!ExtractH264CodecDetails(aCodec, profile, level)) {
return false;
}
+#ifdef XP_WIN
+ if (!Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") &&
+ !WMFDecoderModule::HasH264()) {
+ return false;
+ }
+#endif
+
// Just assume what we can play on all platforms the codecs/formats that
// WMF can play, since we don't have documentation about what other
// platforms can play... According to the WMF documentation:
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
// "The Media Foundation H.264 video decoder is a Media Foundation Transform
// that supports decoding of Baseline, Main, and High profiles, up to level
// 5.1.". We also report that we can play Extended profile, as there are
// bitstreams that are Extended compliant that are also Baseline compliant.
--- a/dom/media/fmp4/wmf/WMFDecoderModule.cpp
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.cpp
@@ -7,16 +7,18 @@
#include "WMF.h"
#include "WMFDecoderModule.h"
#include "WMFDecoder.h"
#include "WMFVideoMFTManager.h"
#include "WMFAudioMFTManager.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
#include "WMFMediaDataDecoder.h"
+#include "nsIWindowsRegKey.h"
+#include "nsComponentManagerUtils.h"
namespace mozilla {
bool WMFDecoderModule::sIsWMFEnabled = false;
bool WMFDecoderModule::sDXVAEnabled = false;
WMFDecoderModule::WMFDecoderModule()
{
@@ -102,9 +104,48 @@ WMFDecoderModule::SupportsVideoMimeType(
bool
WMFDecoderModule::SupportsAudioMimeType(const char* aMimeType)
{
return !strcmp(aMimeType, "audio/mp4a-latm") ||
!strcmp(aMimeType, "audio/mpeg");
}
+static bool
+ClassesRootRegKeyExists(const nsAString& aRegKeyPath)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIWindowsRegKey> regKey =
+ do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return false;
+ }
+
+ rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
+ aRegKeyPath,
+ nsIWindowsRegKey::ACCESS_READ);
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ regKey->Close();
+
+ return true;
+}
+
+/* static */ bool
+WMFDecoderModule::HasH264()
+{
+ // CLSID_CMSH264DecoderMFT
+ return ClassesRootRegKeyExists(
+ NS_LITERAL_STRING("CLSID\\{32D186A7-218F-4C75-8876-DD77273A8999}"));
+}
+
+/* static */ bool
+WMFDecoderModule::HasAAC()
+{
+ // CLSID_CMSAACDecMFT
+ return ClassesRootRegKeyExists(
+ NS_LITERAL_STRING("CLSID\\{62CE7E72-4C71-4D20-B15D-452831A87D9D}"));
+}
+
} // namespace mozilla
--- a/dom/media/fmp4/wmf/WMFDecoderModule.h
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.h
@@ -32,16 +32,23 @@ public:
virtual already_AddRefed<MediaDataDecoder>
CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
MediaTaskQueue* aAudioTaskQueue,
MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
bool SupportsVideoMimeType(const char* aMimeType) MOZ_OVERRIDE;
bool SupportsAudioMimeType(const char* aMimeType) MOZ_OVERRIDE;
+ // Accessors that report whether we have the required MFTs available
+ // on the system to play various codecs. Windows Vista doesn't have the
+ // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
+ // is not installed.
+ static bool HasAAC();
+ static bool HasH264();
+
// Called on main thread.
static void Init();
private:
static bool sIsWMFEnabled;
static bool sDXVAEnabled;
};
} // namespace mozilla