зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1207019 - Remove WMF availability check in MediaKeySystemAccess requests. r=edwin
This commit is contained in:
Родитель
93999bd66d
Коммит
d4ed7efef9
|
@ -567,7 +567,7 @@ nsresult ChannelMediaResource::OpenChannel(nsIStreamListener** aStreamListener)
|
|||
|
||||
rv = mChannel->AsyncOpen2(mListener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
||||
// Tell the media element that we are fetching data from a channel.
|
||||
MediaDecoderOwner* owner = mDecoder->GetMediaOwner();
|
||||
NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "mozilla/Base64.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/Function.h"
|
||||
|
||||
#include "MediaResource.h"
|
||||
#include "TimeUnits.h"
|
||||
|
@ -21,6 +22,8 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -466,4 +469,78 @@ LogToBrowserConsole(const nsAString& aMsg)
|
|||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
bool
|
||||
ParseCodecsString(const nsAString& aCodecs, nsTArray<nsString>& aOutCodecs)
|
||||
{
|
||||
aOutCodecs.Clear();
|
||||
bool expectMoreTokens = false;
|
||||
nsCharSeparatedTokenizer tokenizer(aCodecs, ',');
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& token = tokenizer.nextToken();
|
||||
expectMoreTokens = tokenizer.separatorAfterCurrentToken();
|
||||
aOutCodecs.AppendElement(token);
|
||||
}
|
||||
if (expectMoreTokens) {
|
||||
// Last codec name was empty
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckContentType(const nsAString& aContentType,
|
||||
mozilla::Function<bool(const nsAString&)> aSubtypeFilter,
|
||||
mozilla::Function<bool(const nsAString&)> aCodecFilter)
|
||||
{
|
||||
nsContentTypeParser parser(aContentType);
|
||||
nsAutoString mimeType;
|
||||
nsresult rv = parser.GetType(mimeType);
|
||||
if (NS_FAILED(rv) || !aSubtypeFilter(mimeType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsString codecsStr;
|
||||
parser.GetParameter("codecs", codecsStr);
|
||||
nsTArray<nsString> codecs;
|
||||
if (!ParseCodecsString(codecsStr, codecs)) {
|
||||
return false;
|
||||
}
|
||||
for (const nsString& codec : codecs) {
|
||||
if (!aCodecFilter(codec)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IsH264ContentType(const nsAString& aContentType)
|
||||
{
|
||||
return CheckContentType(aContentType,
|
||||
[](const nsAString& type) {
|
||||
return type.EqualsLiteral("video/mp4");
|
||||
},
|
||||
[](const nsAString& codec) {
|
||||
int16_t profile = 0;
|
||||
int16_t level = 0;
|
||||
return ExtractH264CodecDetails(codec, profile, level);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
bool
|
||||
IsAACContentType(const nsAString& aContentType)
|
||||
{
|
||||
return CheckContentType(aContentType,
|
||||
[](const nsAString& type) {
|
||||
return type.EqualsLiteral("audio/mp4") ||
|
||||
type.EqualsLiteral("audio/x-m4a");
|
||||
},
|
||||
[](const nsAString& codec) {
|
||||
return codec.EqualsLiteral("mp4a.40.2") || // MPEG4 AAC-LC
|
||||
codec.EqualsLiteral("mp4a.40.5") || // MPEG4 HE-AAC
|
||||
codec.EqualsLiteral("mp4a.67"); // MPEG2 AAC-LC
|
||||
});
|
||||
}
|
||||
|
||||
} // end namespace mozilla
|
||||
|
|
|
@ -329,6 +329,15 @@ private:
|
|||
void
|
||||
LogToBrowserConsole(const nsAString& aMsg);
|
||||
|
||||
bool
|
||||
ParseCodecsString(const nsAString& aCodecs, nsTArray<nsString>& aOutCodecs);
|
||||
|
||||
bool
|
||||
IsH264ContentType(const nsAString& aContentType);
|
||||
|
||||
bool
|
||||
IsAACContentType(const nsAString& aContentType);
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "gmp-audio-decode.h"
|
||||
#include "gmp-video-decode.h"
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
#define PRIMETIME_EME_SUPPORTED 1
|
||||
|
@ -297,52 +299,107 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
|
|||
}
|
||||
|
||||
static bool
|
||||
IsPlayableWithGMP(mozIGeckoMediaPluginService* aGMPS,
|
||||
const nsAString& aKeySystem,
|
||||
const nsAString& aContentType)
|
||||
GMPDecryptsAndDecodesAAC(mozIGeckoMediaPluginService* aGMPS,
|
||||
const nsAString& aKeySystem)
|
||||
{
|
||||
#ifdef MOZ_FMP4
|
||||
nsContentTypeParser parser(aContentType);
|
||||
nsAutoString mimeType;
|
||||
nsresult rv = parser.GetType(mimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
|
||||
return HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
|
||||
NS_LITERAL_CSTRING("aac"));
|
||||
}
|
||||
|
||||
if (!mimeType.EqualsLiteral("audio/mp4") &&
|
||||
!mimeType.EqualsLiteral("audio/x-m4a") &&
|
||||
!mimeType.EqualsLiteral("video/mp4")) {
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
GMPDecryptsAndDecodesH264(mozIGeckoMediaPluginService* aGMPS,
|
||||
const nsAString& aKeySystem)
|
||||
{
|
||||
MOZ_ASSERT(HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
|
||||
return HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
|
||||
NS_LITERAL_CSTRING("aac"));
|
||||
}
|
||||
|
||||
nsAutoString codecs;
|
||||
parser.GetParameter("codecs", codecs);
|
||||
|
||||
NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
|
||||
bool hasAAC = false;
|
||||
bool hasH264 = false;
|
||||
bool hasMP3 = false;
|
||||
if (!MP4Decoder::CanHandleMediaType(mimeTypeUTF8,
|
||||
codecs,
|
||||
hasAAC,
|
||||
hasH264,
|
||||
hasMP3) ||
|
||||
hasMP3) {
|
||||
return false;
|
||||
}
|
||||
return (!hasAAC ||
|
||||
!HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
|
||||
NS_LITERAL_CSTRING("aac"))) &&
|
||||
(!hasH264 ||
|
||||
!HaveGMPFor(aGMPS,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR),
|
||||
NS_LITERAL_CSTRING("h264")));
|
||||
#else
|
||||
return false;
|
||||
// If this keysystem's CDM explicitly says it doesn't support decoding,
|
||||
// that means it's OK with passing the decrypted samples back to Gecko
|
||||
// for decoding. Note we special case Clearkey on Windows, where we need
|
||||
// to check for whether WMF is usable because the CDM uses that
|
||||
// to decode.
|
||||
static bool
|
||||
GMPDecryptsAndGeckoDecodesH264(mozIGeckoMediaPluginService* aGMPService,
|
||||
const nsAString& aKeySystem,
|
||||
const nsAString& aContentType)
|
||||
{
|
||||
MOZ_ASSERT(HaveGMPFor(aGMPService,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
|
||||
MOZ_ASSERT(IsH264ContentType(aContentType));
|
||||
return
|
||||
(!HaveGMPFor(aGMPService,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
|
||||
NS_LITERAL_CSTRING("h264"))
|
||||
#ifdef XP_WIN
|
||||
// Clearkey on Windows XP can't decode, but advertises that it can
|
||||
// in its GMP info file.
|
||||
|| (aKeySystem.EqualsLiteral("org.w3.clearkey") && !IsVistaOrLater())
|
||||
#endif
|
||||
) && MP4Decoder::CanHandleMediaType(aContentType);
|
||||
}
|
||||
|
||||
static bool
|
||||
GMPDecryptsAndGeckoDecodesAAC(mozIGeckoMediaPluginService* aGMPService,
|
||||
const nsAString& aKeySystem,
|
||||
const nsAString& aContentType)
|
||||
{
|
||||
MOZ_ASSERT(HaveGMPFor(aGMPService,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
|
||||
MOZ_ASSERT(IsAACContentType(aContentType));
|
||||
return
|
||||
(!HaveGMPFor(aGMPService,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
|
||||
NS_LITERAL_CSTRING("aac"))
|
||||
#ifdef XP_WIN
|
||||
// Clearkey on Windows XP can't decode, but advertises that it can
|
||||
// in its GMP info file.
|
||||
|| (aKeySystem.EqualsLiteral("org.w3.clearkey") && !IsVistaOrLater())
|
||||
#endif
|
||||
) && MP4Decoder::CanHandleMediaType(aContentType);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSupported(mozIGeckoMediaPluginService* aGMPService,
|
||||
const nsAString& aKeySystem,
|
||||
const MediaKeySystemOptions& aConfig)
|
||||
{
|
||||
if (!aConfig.mInitDataType.EqualsLiteral("cenc")) {
|
||||
return false;
|
||||
}
|
||||
if (!aConfig.mAudioCapability.IsEmpty() ||
|
||||
!aConfig.mVideoCapability.IsEmpty()) {
|
||||
// Don't support any capabilities until we know we have a CDM with
|
||||
// capabilities...
|
||||
return false;
|
||||
}
|
||||
if (!aConfig.mAudioType.IsEmpty() &&
|
||||
(!IsAACContentType(aConfig.mAudioType) ||
|
||||
(!GMPDecryptsAndDecodesAAC(aGMPService, aKeySystem) &&
|
||||
!GMPDecryptsAndGeckoDecodesAAC(aGMPService, aKeySystem, aConfig.mAudioType)))) {
|
||||
return false;
|
||||
}
|
||||
if (!aConfig.mVideoType.IsEmpty() &&
|
||||
(!IsH264ContentType(aConfig.mVideoType) ||
|
||||
(!GMPDecryptsAndDecodesH264(aGMPService, aKeySystem) &&
|
||||
!GMPDecryptsAndGeckoDecodesH264(aGMPService, aKeySystem, aConfig.mVideoType)))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
@ -356,32 +413,16 @@ MediaKeySystemAccess::IsSupported(const nsAString& aKeySystem,
|
|||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aOptions.Length(); i++) {
|
||||
const MediaKeySystemOptions& options = aOptions[i];
|
||||
if (!options.mInitDataType.EqualsLiteral("cenc")) {
|
||||
continue;
|
||||
}
|
||||
if (!options.mAudioCapability.IsEmpty() ||
|
||||
!options.mVideoCapability.IsEmpty()) {
|
||||
// Don't support any capabilites until we know we have a CDM with
|
||||
// capabilities...
|
||||
continue;
|
||||
}
|
||||
if (!options.mAudioType.IsEmpty() &&
|
||||
!IsPlayableWithGMP(mps, aKeySystem, options.mAudioType)) {
|
||||
continue;
|
||||
}
|
||||
if (!options.mVideoType.IsEmpty() &&
|
||||
!IsPlayableWithGMP(mps, aKeySystem, options.mVideoType)) {
|
||||
continue;
|
||||
}
|
||||
if (!HaveGMPFor(mps,
|
||||
NS_ConvertUTF16toUTF8(aKeySystem),
|
||||
NS_LITERAL_CSTRING(GMP_API_DECRYPTOR))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Our sandbox provides an origin specific unique identifier, and the
|
||||
// ability to persist data. We don't yet have a way to turn those off
|
||||
// and on for specific GMPs/CDMs, so we don't check the uniqueidentifier
|
||||
// and stateful attributes here.
|
||||
|
||||
return true;
|
||||
for (const MediaKeySystemOptions& config : aOptions) {
|
||||
if (mozilla::dom::IsSupported(mps, aKeySystem, config)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#endif
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
@ -139,30 +140,45 @@ MP4Decoder::CanHandleMediaType(const nsACString& aType,
|
|||
|
||||
// Verify that all the codecs specifed are ones that we expect that
|
||||
// we can play.
|
||||
nsCharSeparatedTokenizer tokenizer(aCodecs, ',');
|
||||
bool expectMoreTokens = false;
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
const nsSubstring& token = tokenizer.nextToken();
|
||||
expectMoreTokens = tokenizer.separatorAfterCurrentToken();
|
||||
if (IsSupportedAudioCodec(token,
|
||||
nsTArray<nsString> codecs;
|
||||
if (!ParseCodecsString(aCodecs, codecs)) {
|
||||
return false;
|
||||
}
|
||||
for (const nsString& codec : codecs) {
|
||||
if (IsSupportedAudioCodec(codec,
|
||||
aOutContainsAAC,
|
||||
aOutContainsMP3)) {
|
||||
continue;
|
||||
}
|
||||
if (IsSupportedH264Codec(token)) {
|
||||
if (IsSupportedH264Codec(codec)) {
|
||||
aOutContainsH264 = true;
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (expectMoreTokens) {
|
||||
// Last codec name was empty
|
||||
// Some unsupported codec.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
MP4Decoder::CanHandleMediaType(const nsAString& aContentType)
|
||||
{
|
||||
nsContentTypeParser parser(aContentType);
|
||||
nsAutoString mimeType;
|
||||
nsresult rv = parser.GetType(mimeType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
nsString codecs;
|
||||
parser.GetParameter("codecs", codecs);
|
||||
|
||||
bool ignoreAAC, ignoreH264, ignoreMP3;
|
||||
return CanHandleMediaType(NS_ConvertUTF16toUTF8(mimeType),
|
||||
codecs,
|
||||
ignoreAAC, ignoreH264, ignoreMP3);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsFFmpegAvailable()
|
||||
{
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
bool& aOutContainsH264,
|
||||
bool& aOutContainsMP3);
|
||||
|
||||
static bool CanHandleMediaType(const nsAString& aMIMEType);
|
||||
|
||||
// Returns true if the MP4 backend is preffed on.
|
||||
static bool IsEnabled();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче