author | Chris Pearce <cpearce@mozilla.com> |
Fri, 08 May 2015 13:36:32 +1200 | |
changeset 242915 | 03dc784d54560da7a828b1b7ec5a3654507a31d5 |
parent 242914 | 4923c566a7f2adb0c143be6a2007c7b5735b5df6 |
child 242916 | b0ebc8d237f08cff537ed569a7e7f1a5eb0d6deb |
push id | 28713 |
push user | kwierso@gmail.com |
push date | Fri, 08 May 2015 17:06:43 +0000 |
treeherder | mozilla-central@fd5e9b7eec13 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mattwoodrow |
bugs | 1160321 |
milestone | 40.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -21,17 +21,17 @@ #include "mozilla/dom/Touch.h" #include "mozilla/PendingAnimationTracker.h" #include "nsIObjectLoadingContent.h" #include "nsFrame.h" #include "mozilla/layers/ShadowLayers.h" #include "ClientLayerManager.h" #include "nsQueryObject.h" #ifdef MOZ_FMP4 -#include "MP4Reader.h" +#include "MP4Decoder.h" #endif #include "nsIScrollableFrame.h" #include "nsContentUtils.h" #include "nsIFrame.h" #include "nsIWidget.h" @@ -2248,17 +2248,17 @@ nsDOMWindowUtils::GetSupportsHardwareH26 nsCOMPtr<nsIWidget> widget = GetWidget(); if (!widget) return NS_ERROR_FAILURE; LayerManager *mgr = widget->GetLayerManager(); if (!mgr) return NS_ERROR_FAILURE; - *retval = MP4Reader::IsVideoAccelerated(mgr->GetCompositorBackendType()); + *retval = MP4Decoder::IsVideoAccelerated(mgr->GetCompositorBackendType()); #else *retval = false; #endif return NS_OK; } NS_IMETHODIMP nsDOMWindowUtils::StartFrameTimeRecording(uint32_t *startIndex)
--- a/dom/media/eme/MediaKeySystemAccess.cpp +++ b/dom/media/eme/MediaKeySystemAccess.cpp @@ -156,17 +156,18 @@ MediaKeySystemAccess::GetKeySystemStatus aKeySystem.EqualsLiteral("com.adobe.primetime"))) { // Win Vista and later only. if (!IsVistaOrLater()) { return MediaKeySystemStatus::Cdm_not_supported; } if (!Preferences::GetBool("media.gmp-eme-adobe.enabled", false)) { return MediaKeySystemStatus::Cdm_disabled; } - if ((!WMFDecoderModule::HasH264() || !WMFDecoderModule::HasAAC()) || + if (!MP4Decoder::CanCreateH264Decoder() || + !MP4Decoder::CanCreateAACDecoder() || !EMEVoucherFileExists()) { // The system doesn't have the codecs that Adobe EME relies // on installed, or doesn't have a voucher for the plugin-container. // Adobe EME isn't going to work, so don't advertise that it will. return MediaKeySystemStatus::Cdm_not_supported; } return EnsureMinCDMVersion(mps, aKeySystem, aMinCdmVersion, true); }
--- a/dom/media/fmp4/MP4Decoder.cpp +++ b/dom/media/fmp4/MP4Decoder.cpp @@ -23,16 +23,17 @@ #endif #ifdef MOZ_APPLEMEDIA #include "apple/AppleDecoderModule.h" #endif #ifdef MOZ_WIDGET_ANDROID #include "nsIGfxInfo.h" #include "AndroidBridge.h" #endif +#include "mozilla/layers/LayersTypes.h" namespace mozilla { MediaDecoderStateMachine* MP4Decoder::CreateStateMachine() { return new MediaDecoderStateMachine(this, new MP4Reader(this)); } @@ -59,22 +60,16 @@ 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 @@ -88,21 +83,16 @@ IsSupportedH264Codec(const nsAString& aC { 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; - } - // Disable 4k video on windows vista since it performs poorly. if (!IsWin7OrLater() && level >= H264_LEVEL_5) { return false; } #endif // Just assume what we can play on all platforms the codecs/formats that @@ -129,23 +119,25 @@ MP4Decoder::CanHandleMediaType(const nsA bool& aOutContainsH264, bool& aOutContainsMP3) { if (!IsEnabled()) { return false; } if (aType.EqualsASCII("audio/mp4") || aType.EqualsASCII("audio/x-m4a")) { - return aCodecs.IsEmpty() || - IsSupportedAudioCodec(aCodecs, - aOutContainsAAC, - aOutContainsMP3); + return MP4Decoder::CanCreateAACDecoder() && + (aCodecs.IsEmpty() || + IsSupportedAudioCodec(aCodecs, + aOutContainsAAC, + aOutContainsMP3)); } - if (!aType.EqualsASCII("video/mp4")) { + if (!aType.EqualsASCII("video/mp4") || + !MP4Decoder::CanCreateH264Decoder()) { return false; } // Verify that all the codecs specifed are ones that we expect that // we can play. nsCharSeparatedTokenizer tokenizer(aCodecs, ','); bool expectMoreTokens = false; while (tokenizer.hasMoreTokens()) { @@ -248,10 +240,138 @@ HavePlatformMPEGDecoders() /* static */ bool MP4Decoder::IsEnabled() { return Preferences::GetBool("media.fragmented-mp4.enabled") && HavePlatformMPEGDecoders(); } +static const uint8_t sTestH264ExtraData[] = { + 0x01, 0x64, 0x00, 0x0a, 0xff, 0xe1, 0x00, 0x17, 0x67, 0x64, + 0x00, 0x0a, 0xac, 0xd9, 0x44, 0x26, 0x84, 0x00, 0x00, 0x03, + 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xc8, 0x3c, 0x48, 0x96, + 0x58, 0x01, 0x00, 0x06, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0 +}; + +static already_AddRefed<MediaDataDecoder> +CreateTestH264Decoder(layers::LayersBackend aBackend, + VideoInfo& aConfig) +{ + aConfig.mMimeType = "video/avc"; + aConfig.mId = 1; + aConfig.mDuration = 40000; + aConfig.mMediaTime = 0; + aConfig.mDisplay = aConfig.mImage = nsIntSize(64, 64); + aConfig.mExtraData = new MediaByteBuffer(); + aConfig.mExtraData->AppendElements(sTestH264ExtraData, + MOZ_ARRAY_LENGTH(sTestH264ExtraData)); + + PlatformDecoderModule::Init(); + + nsRefPtr<PlatformDecoderModule> platform = PlatformDecoderModule::Create(); + if (!platform) { + return nullptr; + } + + nsRefPtr<MediaDataDecoder> decoder( + platform->CreateDecoder(aConfig, nullptr, nullptr, aBackend, nullptr)); + if (!decoder) { + return nullptr; + } + nsresult rv = decoder->Init(); + NS_ENSURE_SUCCESS(rv, nullptr); + + return decoder.forget(); +} + +/* static */ bool +MP4Decoder::IsVideoAccelerated(layers::LayersBackend aBackend) +{ + VideoInfo config; + nsRefPtr<MediaDataDecoder> decoder(CreateTestH264Decoder(aBackend, config)); + if (!decoder) { + return false; + } + bool result = decoder->IsHardwareAccelerated(); + decoder->Shutdown(); + return result; +} + +/* static */ bool +MP4Decoder::CanCreateH264Decoder() +{ + static bool haveCachedResult = false; + static bool result = false; + if (haveCachedResult) { + return result; + } + VideoInfo config; + nsRefPtr<MediaDataDecoder> decoder( + CreateTestH264Decoder(layers::LayersBackend::LAYERS_BASIC, config)); + if (decoder) { + decoder->Shutdown(); + result = true; + } + haveCachedResult = true; + return result; +} + +static already_AddRefed<MediaDataDecoder> +CreateTestAACDecoder(AudioInfo& aConfig) +{ + PlatformDecoderModule::Init(); + + nsRefPtr<PlatformDecoderModule> platform = PlatformDecoderModule::Create(); + if (!platform) { + return nullptr; + } + + nsRefPtr<MediaDataDecoder> decoder( + platform->CreateDecoder(aConfig, nullptr, nullptr)); + if (!decoder) { + return nullptr; + } + nsresult rv = decoder->Init(); + NS_ENSURE_SUCCESS(rv, nullptr); + + return decoder.forget(); +} + +// bipbop.mp4's extradata/config... +static const uint8_t sTestAACExtraData[] = { + 0x03, 0x80, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, 0x04, 0x80, + 0x80, 0x80, 0x14, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x51, 0x00, 0x00, 0x11, 0x51, 0x05, 0x80, 0x80, 0x80, + 0x02, 0x13, 0x90, 0x06, 0x80, 0x80, 0x80, 0x01, 0x02 +}; + +static const uint8_t sTestAACConfig[] = { 0x13, 0x90 }; + +/* static */ bool +MP4Decoder::CanCreateAACDecoder() +{ + static bool haveCachedResult = false; + static bool result = false; + if (haveCachedResult) { + return result; + } + AudioInfo config; + config.mMimeType = "audio/mp4a-latm"; + config.mRate = 22050; + config.mChannels = 2; + config.mBitDepth = 16; + config.mProfile = 2; + config.mExtendedProfile = 2; + config.mCodecSpecificConfig->AppendElements(sTestAACConfig, + MOZ_ARRAY_LENGTH(sTestAACConfig)); + config.mExtraData->AppendElements(sTestAACExtraData, + MOZ_ARRAY_LENGTH(sTestAACExtraData)); + nsRefPtr<MediaDataDecoder> decoder(CreateTestAACDecoder(config)); + if (decoder) { + decoder->Shutdown(); + result = true; + } + haveCachedResult = true; + return result; +} + } // namespace mozilla -
--- a/dom/media/fmp4/MP4Decoder.h +++ b/dom/media/fmp4/MP4Decoder.h @@ -36,13 +36,17 @@ public: const nsAString& aCodecs, bool& aOutContainsAAC, bool& aOutContainsH264, bool& aOutContainsMP3); // Returns true if the MP4 backend is preffed on, and we're running on a // platform that is likely to have decoders for the contained formats. static bool IsEnabled(); + + static bool IsVideoAccelerated(layers::LayersBackend aBackend); + static bool CanCreateAACDecoder(); + static bool CanCreateH264Decoder(); }; } // namespace mozilla #endif
--- a/dom/media/fmp4/MP4Reader.cpp +++ b/dom/media/fmp4/MP4Reader.cpp @@ -68,53 +68,16 @@ TrackTypeToStr(TrackInfo::TrackType aTra case TrackInfo::kVideoTrack: return "Video"; default: return "Unknown"; } } #endif -uint8_t sTestExtraData[40] = { 0x01, 0x64, 0x00, 0x0a, 0xff, 0xe1, 0x00, 0x17, 0x67, 0x64, 0x00, 0x0a, 0xac, 0xd9, 0x44, 0x26, 0x84, 0x00, 0x00, 0x03, - 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xc8, 0x3c, 0x48, 0x96, 0x58, 0x01, 0x00, 0x06, 0x68, 0xeb, 0xe3, 0xcb, 0x22, 0xc0 }; - -/* static */ bool -MP4Reader::IsVideoAccelerated(LayersBackend aBackend) -{ - VideoInfo config; - config.mMimeType = "video/avc"; - config.mId = 1; - config.mDuration = 40000; - config.mMediaTime = 0; - config.mDisplay = config.mImage = nsIntSize(64, 64); - config.mExtraData = new MediaByteBuffer(); - config.mExtraData->AppendElements(sTestExtraData, 40); - - PlatformDecoderModule::Init(); - - nsRefPtr<PlatformDecoderModule> platform = PlatformDecoderModule::Create(); - if (!platform) { - return false; - } - - nsRefPtr<MediaDataDecoder> decoder = - platform->CreateDecoder(config, nullptr, nullptr, aBackend, nullptr); - if (!decoder) { - return false; - } - nsresult rv = decoder->Init(); - NS_ENSURE_SUCCESS(rv, false); - - bool result = decoder->IsHardwareAccelerated(); - - decoder->Shutdown(); - - return result; -} - bool AccumulateSPSTelemetry(const MediaByteBuffer* aExtradata) { SPSData spsdata; if (H264::DecodeSPSFromExtraData(aExtradata, spsdata)) { uint8_t constraints = (spsdata.constraint_set0_flag ? (1 << 0) : 0) | (spsdata.constraint_set1_flag ? (1 << 1) : 0) | (spsdata.constraint_set2_flag ? (1 << 2) : 0) |
--- a/dom/media/fmp4/MP4Reader.h +++ b/dom/media/fmp4/MP4Reader.h @@ -82,18 +82,16 @@ public: virtual nsRefPtr<ShutdownPromise> Shutdown() override; virtual bool IsAsync() const override { return true; } virtual bool VideoIsHardwareAccelerated() const override; virtual void DisableHardwareAcceleration() override; - static bool IsVideoAccelerated(layers::LayersBackend aBackend); - private: bool InitDemuxer(); void ReturnOutput(MediaData* aData, TrackType aTrack); bool EnsureDecodersSetup(); // Sends input to decoder for aTrack, and output to the state machine,
--- a/dom/media/fmp4/apple/AppleDecoderModule.cpp +++ b/dom/media/fmp4/apple/AppleDecoderModule.cpp @@ -67,17 +67,21 @@ public: AppleDecoderModule::AppleDecoderModule() { } AppleDecoderModule::~AppleDecoderModule() { nsCOMPtr<nsIRunnable> task(new UnlinkTask()); - NS_DispatchToMainThread(task); + if (!NS_IsMainThread()) { + NS_DispatchToMainThread(task); + } else { + task->Run(); + } } /* static */ void AppleDecoderModule::Init() { MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); @@ -119,16 +123,17 @@ public: } }; /* static */ nsresult AppleDecoderModule::CanDecode() { if (!sInitialized) { + // Note: We can be called on the main thread from MP4Decoder::CanHandleMediaType(). if (NS_IsMainThread()) { Init(); } else { nsCOMPtr<nsIRunnable> task(new InitTask()); NS_DispatchToMainThread(task, NS_DISPATCH_SYNC); } } @@ -137,18 +142,23 @@ AppleDecoderModule::CanDecode() nsresult AppleDecoderModule::Startup() { if (!sIsVDAAvailable && !sIsVTAvailable) { return NS_ERROR_FAILURE; } + // Note: We can be called on the main thread from MP4Decoder::CanHandleMediaType(). nsCOMPtr<nsIRunnable> task(new LinkTask()); - NS_DispatchToMainThread(task, NS_DISPATCH_SYNC); + if (!NS_IsMainThread()) { + NS_DispatchToMainThread(task, NS_DISPATCH_SYNC); + } else { + task->Run(); + } return NS_OK; } already_AddRefed<MediaDataDecoder> AppleDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig, layers::LayersBackend aLayersBackend, layers::ImageContainer* aImageContainer,