Bug 1160321 - Test whether we can create H.264/AAC decoders before we report we support them. r=mattwoodrow

This commit is contained in:
Chris Pearce 2015-05-06 11:40:45 +12:00
parent 2d1c9f6a2b
commit b8de3abe20
6 changed files with 145 additions and 59 deletions

View File

@ -26,7 +26,7 @@
#include "ClientLayerManager.h"
#include "nsQueryObject.h"
#ifdef MOZ_FMP4
#include "MP4Reader.h"
#include "MP4Decoder.h"
#endif
#include "nsIScrollableFrame.h"
@ -2253,7 +2253,7 @@ nsDOMWindowUtils::GetSupportsHardwareH264Decoding(bool* retval)
if (!mgr)
return NS_ERROR_FAILURE;
*retval = MP4Reader::IsVideoAccelerated(mgr->GetCompositorBackendType());
*retval = MP4Decoder::IsVideoAccelerated(mgr->GetCompositorBackendType());
#else
*retval = false;
#endif

View File

@ -161,7 +161,8 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
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.

View File

@ -28,6 +28,7 @@
#include "nsIGfxInfo.h"
#include "AndroidBridge.h"
#endif
#include "mozilla/layers/LayersTypes.h"
namespace mozilla {
@ -64,12 +65,6 @@ IsSupportedAudioCodec(const nsAString& aCodec,
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.
@ -93,11 +88,6 @@ IsSupportedH264Codec(const nsAString& aCodec)
}
#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) {
@ -134,13 +124,15 @@ MP4Decoder::CanHandleMediaType(const nsACString& aType,
}
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;
}
@ -253,5 +245,133 @@ MP4Decoder::IsEnabled()
HavePlatformMPEGDecoders();
}
} // namespace mozilla
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

View File

@ -41,6 +41,10 @@ public:
// 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

View File

@ -73,43 +73,6 @@ TrackTypeToStr(TrackInfo::TrackType aTrack)
}
#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)
{

View File

@ -87,8 +87,6 @@ public:
virtual void DisableHardwareAcceleration() override;
static bool IsVideoAccelerated(layers::LayersBackend aBackend);
private:
bool InitDemuxer();