Diff
Modified: trunk/LayoutTests/ChangeLog (277092 => 277093)
--- trunk/LayoutTests/ChangeLog 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/LayoutTests/ChangeLog 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,3 +1,14 @@
+2021-05-06 Darin Adler <da...@apple.com>
+
+ Streamline codec parsing, replacing uses of HashMap with SortedArrayMap
+ https://bugs.webkit.org/show_bug.cgi?id=225368
+
+ Reviewed by Sam Weinig.
+
+ * media/hevc-codec-parameters-expected.txt: Remove testing of generalTierFlag, which is ignored
+ by our actual media code after parsing.
+ * media/hevc-codec-parameters.html: Ditto.
+
2021-05-06 Tim Nguyen <n...@apple.com>
Re-import css/css-fonts WPT
Modified: trunk/LayoutTests/media/hevc-codec-parameters-expected.txt (277092 => 277093)
--- trunk/LayoutTests/media/hevc-codec-parameters-expected.txt 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/LayoutTests/media/hevc-codec-parameters-expected.txt 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,8 +1,8 @@
EXPECTED (internals.parseHEVCCodecParameters("bad-parameter") == 'null') OK
EXPECTED (internals.parseHEVCCodecParameters("hvc1") == 'null') OK
-EXPECTED (internals.parseHEVCCodecParameters("hev1.1.6.L93") === '{ 0, 1, 6, false, 93 }') OK
-EXPECTED (internals.parseHEVCCodecParameters("hev1.A4.41.H120") === '{ 1, 4, 65, true, 120 }') OK
-EXPECTED (internals.parseHEVCCodecParameters("hev1.B1.4.L63") === '{ 2, 1, 4, false, 63 }') OK
+EXPECTED (internals.parseHEVCCodecParameters("hev1.1.6.L93") === '{ 0, 1, 6, 93 }') OK
+EXPECTED (internals.parseHEVCCodecParameters("hev1.A4.41.H120") === '{ 1, 4, 65, 120 }') OK
+EXPECTED (internals.parseHEVCCodecParameters("hev1.B1.4.L63") === '{ 2, 1, 4, 63 }') OK
EXPECTED (internals.parseHEVCCodecParameters("hev1.D1.4.L63") == 'null') OK
EXPECTED (internals.parseHEVCCodecParameters("hev1.B1.4.L68000") == 'null') OK
END OF TEST
Modified: trunk/LayoutTests/media/hevc-codec-parameters.html (277092 => 277093)
--- trunk/LayoutTests/media/hevc-codec-parameters.html 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/LayoutTests/media/hevc-codec-parameters.html 2021-05-06 16:08:17 UTC (rev 277093)
@@ -4,22 +4,20 @@
<script src=""
<script>
function HEVCParameterSetToString(set) {
- return `{ ${set.generalProfileSpace }, ${set.generalProfileIDC }, ${set.generalProfileCompatibilityFlags }, ${set.generalTierFlag }, ${set.generalLevelIDC } }`;
+ return `{ ${set.generalProfileSpace }, ${set.generalProfileIDC }, ${set.generalProfileCompatibilityFlags }, ${set.generalLevelIDC } }`;
}
function isEqualHEVCParameterSet(setA, setB) {
return setA.generalProfileSpace === setB.generalProfileSpace
&& setA.generalProfileIDC === setB.generalProfileIDC
&& setA.generalProfileCompatibilityFlags === setB.generalProfileCompatibilityFlags
- && setA.generalTierFlag === setB.generalTierFlag
&& setA.generalLevelIDC === setB.generalLevelIDC
}
- function makeHEVCParameterSet(generalProfileSpace, generalProfileIDC, generalProfileCompatibilityFlags, generalTierFlag, generalLevelIDC)
+ function makeHEVCParameterSet(generalProfileSpace, generalProfileIDC, generalProfileCompatibilityFlags, generalLevelIDC)
{
return {
generalProfileSpace: generalProfileSpace,
generalProfileIDC: generalProfileIDC,
generalProfileCompatibilityFlags: generalProfileCompatibilityFlags,
- generalTierFlag: generalTierFlag,
generalLevelIDC: generalLevelIDC,
};
}
@@ -32,9 +30,9 @@
window.addEventListener('load', event => {
testExpected('internals.parseHEVCCodecParameters("bad-parameter")', null);
testExpected('internals.parseHEVCCodecParameters("hvc1")', null);
- testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.1.6.L93")', makeHEVCParameterSet(0, 1, 6, false, 93));
- testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.A4.41.H120")', makeHEVCParameterSet(1, 4, 65, true, 120));
- testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.B1.4.L63")', makeHEVCParameterSet(2, 1, 4, false, 63));
+ testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.1.6.L93")', makeHEVCParameterSet(0, 1, 6, 93));
+ testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.A4.41.H120")', makeHEVCParameterSet(1, 4, 65, 120));
+ testExpectedHEVCParameterSet('internals.parseHEVCCodecParameters("hev1.B1.4.L63")', makeHEVCParameterSet(2, 1, 4, 63));
testExpected('internals.parseHEVCCodecParameters("hev1.D1.4.L63")', null);
testExpected('internals.parseHEVCCodecParameters("hev1.B1.4.L68000")', null);
endTest();
Modified: trunk/Source/WTF/ChangeLog (277092 => 277093)
--- trunk/Source/WTF/ChangeLog 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WTF/ChangeLog 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,3 +1,13 @@
+2021-05-06 Darin Adler <da...@apple.com>
+
+ Streamline codec parsing, replacing uses of HashMap with SortedArrayMap
+ https://bugs.webkit.org/show_bug.cgi?id=225368
+
+ Reviewed by Sam Weinig.
+
+ * wtf/SortedArrayMap.h: Moved PackedASCIILowerCodes here for reuse.
+ Slightly tweaked ComparableASCIISubsetLiteral to match better.
+
2021-05-05 Devin Rousso <drou...@apple.com>
Sampled Page Top Color: take additional snapshots further down the page to see if the sampled top color is more than just a tiny strip
Modified: trunk/Source/WTF/wtf/SortedArrayMap.h (277092 => 277093)
--- trunk/Source/WTF/wtf/SortedArrayMap.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WTF/wtf/SortedArrayMap.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -81,7 +81,7 @@
template<ASCIISubset> struct ComparableASCIISubsetLiteral {
ASCIILiteral literal;
- template<std::size_t size> constexpr ComparableASCIISubsetLiteral(const char (&characters)[size]);
+ template<unsigned size> constexpr ComparableASCIISubsetLiteral(const char (&characters)[size]);
static Optional<ComparableStringView> parse(StringView string) { return { { string } }; }
};
@@ -103,8 +103,24 @@
bool operator<(ComparableLettersLiteral, ComparableStringView);
template<typename OtherType> bool operator==(OtherType, ComparableStringView);
-template<typename OtherType> bool operator!=(ComparableStringView, OtherType);
+template<typename StorageInteger> class PackedASCIILowerCodes {
+public:
+ static_assert(std::is_unsigned_v<StorageInteger>);
+
+ template<unsigned size> constexpr PackedASCIILowerCodes(const char (&characters)[size]);
+ static Optional<PackedASCIILowerCodes> parse(StringView);
+ constexpr StorageInteger value() const { return m_value; }
+
+private:
+ template<unsigned size> static constexpr StorageInteger pack(const char (&characters)[size]);
+ explicit constexpr PackedASCIILowerCodes(StorageInteger);
+ StorageInteger m_value { 0 };
+};
+
+template<typename StorageInteger> constexpr bool operator==(PackedASCIILowerCodes<StorageInteger>, PackedASCIILowerCodes<StorageInteger>);
+template<typename StorageInteger> constexpr bool operator<(PackedASCIILowerCodes<StorageInteger>, PackedASCIILowerCodes<StorageInteger>);
+
template<ASCIISubset subset> constexpr bool isInSubset(char character)
{
if (!(character && isASCII(character)))
@@ -119,7 +135,7 @@
}
}
-template<ASCIISubset subset> template<std::size_t size> constexpr ComparableASCIISubsetLiteral<subset>::ComparableASCIISubsetLiteral(const char (&characters)[size])
+template<ASCIISubset subset> template<unsigned size> constexpr ComparableASCIISubsetLiteral<subset>::ComparableASCIISubsetLiteral(const char (&characters)[size])
: literal { ASCIILiteral::fromLiteralUnsafe(characters) }
{
ASSERT_UNDER_CONSTEXPR_CONTEXT(allOfConstExpr(&characters[0], &characters[size - 1], [] (char character) {
@@ -301,17 +317,62 @@
return b == a;
}
-template<typename OtherType> inline bool operator!=(ComparableStringView a, OtherType b)
+template<typename StorageInteger> template<unsigned size> constexpr PackedASCIILowerCodes<StorageInteger>::PackedASCIILowerCodes(const char (&string)[size])
+ : m_value { pack(string) }
{
- return !(a == b);
}
+template<typename StorageInteger> constexpr PackedASCIILowerCodes<StorageInteger>::PackedASCIILowerCodes(StorageInteger value)
+ : m_value { value }
+{
}
+template<typename StorageInteger> template<unsigned size> constexpr StorageInteger PackedASCIILowerCodes<StorageInteger>::pack(const char (&string)[size])
+{
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(size);
+ constexpr unsigned length = size - 1;
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(!string[length]);
+ ASSERT_UNDER_CONSTEXPR_CONTEXT(length <= sizeof(StorageInteger));
+ StorageInteger result = 0;
+ for (unsigned index = 0; index < length; ++index) {
+ StorageInteger code = static_cast<uint8_t>(string[index]);
+ result |= code << ((sizeof(StorageInteger) - index - 1) * 8);
+ }
+ return result;
+}
+
+template<typename StorageInteger> auto PackedASCIILowerCodes<StorageInteger>::parse(StringView string) -> Optional<PackedASCIILowerCodes>
+{
+ if (string.length() > sizeof(StorageInteger))
+ return WTF::nullopt;
+ StorageInteger result = 0;
+ for (unsigned index = 0; index < string.length(); ++index) {
+ UChar code = string[index];
+ if (!isASCII(code))
+ return WTF::nullopt;
+ result |= static_cast<StorageInteger>(toASCIILower(code)) << ((sizeof(StorageInteger) - index - 1) * 8);
+ }
+ return PackedASCIILowerCodes(result);
+}
+
+template<typename StorageInteger> constexpr bool operator==(PackedASCIILowerCodes<StorageInteger> a, PackedASCIILowerCodes<StorageInteger> b)
+{
+ return a.value() == b.value();
+}
+
+template<typename StorageInteger> constexpr bool operator<(PackedASCIILowerCodes<StorageInteger> a, PackedASCIILowerCodes<StorageInteger> b)
+{
+ return a.value() < b.value();
+}
+
+}
+
+// FIXME: Rename the Comparable and Packed types for clarity and to align them better with each other.
using WTF::ASCIISubset;
using WTF::ComparableASCIILiteral;
using WTF::ComparableASCIISubsetLiteral;
using WTF::ComparableCaseFoldingASCIILiteral;
using WTF::ComparableLettersLiteral;
+using WTF::PackedASCIILowerCodes;
using WTF::SortedArrayMap;
using WTF::SortedArraySet;
Modified: trunk/Source/WebCore/ChangeLog (277092 => 277093)
--- trunk/Source/WebCore/ChangeLog 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/ChangeLog 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,3 +1,108 @@
+2021-05-06 Darin Adler <da...@apple.com>
+
+ Streamline codec parsing, replacing uses of HashMap with SortedArrayMap
+ https://bugs.webkit.org/show_bug.cgi?id=225368
+
+ Reviewed by Sam Weinig.
+
+ * platform/ContentType.cpp:
+ (WebCore::ContentType::parameter const): Use early return instead of nesting.
+ Strip HTML spaces, not all whitespace, and do it only once rather than twice.
+ Fixed a small bug where we search for the second quotation mark in a way that
+ could find the same quotation mark twice if there is a space before the first
+ one. Added FIXME comments about a few obvious problems in the parsing algorithm.
+ Improved efficiency by using StringView, saving the allocation of one temporary
+ StringImpl in the case where we have some HTML spaces to strip.
+ (WebCore::ContentType::containerType const): Simplified the implemementation
+ by taking advantage of the fact that our notFound value is designed to be used
+ as an argument to functions like String::left, telling them to return the
+ entire string. Strip HTML spaces, not all whitespace.
+
+ * platform/graphics/HEVCUtilities.cpp:
+ (WebCore::parseHEVCCodecParameters): Take a StringView instead of a String
+ for greater flexibility and efficiency. Don't store codecName, which is
+ never used after verifying that it is a legal value here. Don't store the
+ generalTierFlag, which is never used after verifying that it is a legal
+ value here. Don't store the constraint flags, which are never used after
+ verifying that they are legal values here.
+ (WebCore::makeOptionalFromPointer): Added to make code below cleaner.
+ (WebCore::parseDoViCodecType): Renamed from codecStringForDoViCodecType
+ since it now returns an enumeration value instead of a string. Also
+ take a StringView instead of a String for greater flexibility and efficiency.
+ Also use a SortedArrayMap instead of a MemoryCompactLookupOnlyRobinHoodHashMap.
+ (WebCore::profileIDForAlphabeticDoViProfile): Take a StringView instead of
+ a String for greater flexibility and efficiency. Use a SortedArrayMap instead
+ of a MemoryCompactLookupOnlyRobinHoodHashMap.
+ (WebCore::isValidProfileIDForCodec): Take a codec enumeration value parameter
+ instead of a string.
+ (WebCore::parseDoViCodecParameters): Take a StringView instead of a String
+ for greater flexibility and efficiency. Store the codec as an enumeration
+ instead of a String. Don't create a temporary String just so we can call the
+ profileIDForAlphabeticDoViProfile function.
+
+ * platform/graphics/HEVCUtilities.h: Renamed HEVCParameterSet and
+ DoViParameterSet to HEVCParameters and DoViParameters. The word "set" is not
+ helpful in these names. Removed codecName, generalTierFlag, and constraintFlags
+ from HEVCParameterSet. Changed the parse functions to take StringView instead
+ of String. Replaced the string codecName in DoViParameterSet with an enumeration
+ since there are only a few valid values.
+
+ * platform/graphics/cocoa/HEVCUtilitiesCocoa.h: Use Optional return value
+ instead of a bool and an out argument.
+
+ * platform/graphics/cocoa/HEVCUtilitiesCocoa.mm:
+ (WebCore::validateHEVCParameters): Updated to return Optional.
+ (WebCore::codecType): Updated to take an enumeration value and no longer
+ need to return an optional. Also renamed from codecTypeForDoViCodecString
+ since the type now makes this clear without a long function name.
+ (WebCore::parseStringArrayFromDictionaryToUInt16Vector): Renamed from
+ CFStringArrayToNumberVector, and moved the dictionary lookup in here.
+ The old name was a little vague; "NumberVector" doesn't say 16-bit unsigned.
+ Simplified code by using an Objective-C for loop instead of a block and
+ enumeration. This cut the size of the function down quite a bit.
+ (WebCore::validateDoViParameters): Updated to return Optional. Also
+ refactored to use the imrpoved helper functions above.
+
+ * platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp:
+ (WebCore::videoCodecTypeFromRFC4281Type): Take a StringView instead of a String
+ for greater flexibility and efficiency.
+ (WebCore::computeMediaCapabilitiesInfo): Factored out this helper function
+ so we don't have such complicated callback logic. Refactored to use the new
+ versions of validateHEVCParameters, validateDoViParameters, and
+ validateVPParameters.
+ (WebCore::createMediaPlayerDecodingConfigurationCocoa): Moved most of the
+ code into computeMediaCapabilitiesInfo; this mostly deals with the callback.
+
+ * platform/graphics/cocoa/VP9UtilitiesCocoa.h: Removed extraneous use of extern.
+ Added const for input-only reference arguments. Changed validateVPParameters to
+ return Optional instead of a bool with an out argument.
+
+ * platform/graphics/cocoa/VP9UtilitiesCocoa.mm:
+ (WebCore::isVP9CodecConfigurationRecordSupported): Added const.
+ (WebCore::isVP8CodecConfigurationRecordSupported): Ditto.
+ (WebCore::isVPCodecConfigurationRecordSupported): Ditto.
+ (WebCore::validateVPParameters): Refactored to return Optional.
+
+ * platform/network/HTTPHeaderMap.h: Removed unneeded includes.
+
+ * platform/text/LocaleToScriptMapping.cpp: Moved PackedASCIILowerCodes from
+ here into the SortedArrayMap.h header.
+
+ * testing/Internals.cpp:
+ (WebCore::Internals::parseHEVCCodecParameters): Tweaked since HEVCParameterSet
+ is now only the correct name here in the Internals class.
+ (WebCore::Internals::parseDoViCodecParameters): Ditto. Also added code to
+ expose the codec enumeration as a string. This is now a testing-only thing.
+ (WebCore::Internals::parseVPCodecParameters): Ditto.
+
+ * testing/Internals.h: Tweaked the ParameterSet types since they now don't
+ exactly match the structures used in the real code.
+
+ * testing/Internals.idl: Removed codecName, generalTierFlag, and
+ constraintFlags from HEVCParameterSet. Neither codecName nor constraintFlags
+ was used in any test. And the generalTierFlag test was something we can
+ do without; the parsed value isn't actually used in any WebKit code.
+
2021-05-06 Philippe Normand <pnorm...@igalia.com>
[GStreamer] Fallback to texture mapper video orientation handling when glvideoflip is not available
Modified: trunk/Source/WebCore/platform/ContentType.cpp (277092 => 277093)
--- trunk/Source/WebCore/platform/ContentType.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/ContentType.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2021 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2009 Google Inc. All rights reserved.
*
@@ -57,43 +57,44 @@
String ContentType::parameter(const String& parameterName) const
{
- String parameterValue;
- String strippedType = m_type.stripWhiteSpace();
+ // A MIME type can have one or more "param=value" after a semicolon, separated from each other by semicolons.
- // a MIME type can have one or more "param=value" after a semi-colon, and separated from each other by semi-colons
- size_t semi = strippedType.find(';');
- if (semi != notFound) {
- size_t start = strippedType.findIgnoringASCIICase(parameterName, semi + 1);
- if (start != notFound) {
- start = strippedType.find('=', start + parameterName.length());
- if (start != notFound) {
- size_t quote = strippedType.find('\"', start + 1);
- size_t end = strippedType.find('\"', start + 2);
- if (quote != notFound && end != notFound)
- start = quote;
- else {
- end = strippedType.find(';', start + 1);
- if (end == notFound)
- end = strippedType.length();
- }
- parameterValue = strippedType.substring(start + 1, end - (start + 1)).stripWhiteSpace();
- }
- }
+ // FIXME: This will ignore a quotation mark if it comes before the semicolon. Is that the desired behavior?
+ auto semicolonPosition = m_type.find(';');
+ if (semicolonPosition == notFound)
+ return { };
+
+ // FIXME: This matches parameters that have parameterName as a suffix; that is not the desired behavior.
+ auto nameStart = m_type.findIgnoringASCIICase(parameterName, semicolonPosition + 1);
+ if (nameStart == notFound)
+ return { };
+
+ auto equalSignPosition = m_type.find('=', nameStart + parameterName.length());
+ if (equalSignPosition == notFound)
+ return { };
+
+ // FIXME: This skips over any characters that come before a quotation mark; that is not the desired behavior.
+ auto quotePosition = m_type.find('"', equalSignPosition + 1);
+ // FIXME: This does not work if there is an escaped quotation mark in the quoted string. Is that the desired behavior?
+ auto secondQuotePosition = m_type.find('"', quotePosition + 1);
+ size_t start;
+ size_t end;
+ if (quotePosition != notFound && secondQuotePosition != notFound) {
+ start = quotePosition + 1;
+ end = secondQuotePosition;
+ } else {
+ // FIXME: If there is only one quotation mark, this will treat it as part of the string; that is not the desired behavior.
+ start = equalSignPosition + 1;
+ end = m_type.find(';', start);
}
-
- return parameterValue;
+ return StringView { m_type }.substring(start, end - start).stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>).toString();
}
String ContentType::containerType() const
{
- String strippedType = m_type.stripWhiteSpace();
-
- // "type" can have parameters after a semi-colon, strip them
- size_t semi = strippedType.find(';');
- if (semi != notFound)
- strippedType = strippedType.left(semi).stripWhiteSpace();
-
- return strippedType;
+ // Strip parameters that come after a semicolon.
+ // FIXME: This will ignore a quotation mark if it comes before the semicolon. Is that the desired behavior?
+ return stripLeadingAndTrailingHTMLSpaces(m_type.left(m_type.find(';')));
}
static inline Vector<String> splitParameters(StringView parametersView)
Modified: trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/HEVCUtilities.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,13 +27,12 @@
#include "HEVCUtilities.h"
#include <wtf/NeverDestroyed.h>
-#include <wtf/RobinHoodHashMap.h>
-#include <wtf/text/StringHash.h>
+#include <wtf/SortedArrayMap.h>
#include <wtf/text/StringToIntegerConversion.h>
namespace WebCore {
-Optional<HEVCParameterSet> parseHEVCCodecParameters(const String& codecString)
+Optional<HEVCParameters> parseHEVCCodecParameters(StringView codecString)
{
// The format of the 'hevc' codec string is specified in ISO/IEC 14496-15:2014, Annex E.3.
StringView codecView(codecString);
@@ -42,11 +41,11 @@
if (nextElement == codecSplit.end())
return WTF::nullopt;
- HEVCParameterSet parameters;
+ HEVCParameters parameters;
// Codec identifier: legal values are specified in ISO/IEC 14496-15:2014, section 8:
- parameters.codecName = (*nextElement).toString();
- if (!equal(parameters.codecName, "hvc1") && !equal(parameters.codecName, "hev1"))
+ auto codecName = *nextElement;
+ if (codecName != "hvc1" && codecName != "hev1")
return WTF::nullopt;
if (++nextElement == codecSplit.end())
@@ -91,21 +90,18 @@
if (firstCharacter != 'L' && firstCharacter != 'H')
return WTF::nullopt;
- parameters.generalTierFlag = firstCharacter == 'H';
bool isValidGeneralLevelIDC = false;
parameters.generalLevelIDC = toIntegralType<uint8_t>(generalTier.substring(1), &isValidGeneralLevelIDC);
if (!isValidGeneralLevelIDC)
return WTF::nullopt;
- // Optional fourth and remaning elements: a sequence of 6 1-byte constraint flags, each byte encoded
+ // Optional fourth and remaining elements: a sequence of 6 1-byte constraint flags, each byte encoded
// in hex, and separated by a period, with trailing zero bytes omitted.
- parameters.constraintFlags.fill(0, 6);
- for (auto& flag : parameters.constraintFlags) {
+ for (unsigned i = 0; i < 6; ++i) {
if (++nextElement == codecSplit.end())
break;
-
bool isValidFlag = false;
- flag = toIntegralType<uint8_t>(*nextElement, &isValidFlag, 16);
+ toIntegralType<uint8_t>(*nextElement, &isValidFlag, 16);
if (!isValidFlag)
return WTF::nullopt;
}
@@ -113,41 +109,40 @@
return parameters;
}
-static String codecStringForDoViCodecType(const String& codec)
+template<typename ValueType> inline Optional<ValueType> makeOptionalFromPointer(const ValueType* pointer)
{
- using MapType = MemoryCompactLookupOnlyRobinHoodHashMap<String, String>;
- static NeverDestroyed<MapType> types = std::initializer_list<MapType::KeyValuePairType>({
- { "dvhe"_s, "hev1"_s },
- { "dvh1"_s, "hvc1"_s },
- { "dvav"_s, "avc3"_s },
- { "dva1"_s, "avc1"_s }
- });
+ if (!pointer)
+ return WTF::nullopt;
+ return *pointer;
+}
- auto findResults = types.get().find(codec);
- if (findResults == types.get().end())
- return nullString();
- return findResults->value;
+static Optional<DoViParameters::Codec> parseDoViCodecType(StringView string)
+{
+ static constexpr std::pair<PackedASCIILowerCodes<uint32_t>, DoViParameters::Codec> typesArray[] = {
+ { "dva1", DoViParameters::Codec::AVC1 },
+ { "dvav", DoViParameters::Codec::AVC3 },
+ { "dvh1", DoViParameters::Codec::HVC1 },
+ { "dvhe", DoViParameters::Codec::HEV1 },
+ };
+ static constexpr SortedArrayMap typesMap { typesArray };
+ return makeOptionalFromPointer(typesMap.tryGet(string));
}
-static Optional<unsigned short> profileIDForAlphabeticDoViProfile(const String& profile)
+static Optional<uint16_t> profileIDForAlphabeticDoViProfile(StringView profile)
{
// See Table 7 of "Dolby Vision Profiles and Levels Version 1.3.2"
- using MapType = MemoryCompactLookupOnlyRobinHoodHashMap<String, unsigned short>;
- static NeverDestroyed<MapType> map = std::initializer_list<MapType::KeyValuePairType>({
- { "dvhe.dtr"_s, 4 },
- { "dvhe.stn"_s, 5 },
- { "dvhe.dtb"_s, 7 },
- { "dvhe.st"_s, 8 },
- { "dvav.se"_s, 9 }
- });
-
- auto findResults = map.get().find(profile);
- if (findResults == map.get().end())
- return WTF::nullopt;
- return findResults->value;
+ static constexpr std::pair<PackedASCIILowerCodes<uint64_t>, uint16_t> profilesArray[] = {
+ { "dvav.se", 9 },
+ { "dvhe.dtb", 7 },
+ { "dvhe.dtr", 4 },
+ { "dvhe.st", 8 },
+ { "dvhe.stn", 5 },
+ };
+ static constexpr SortedArrayMap profilesMap { profilesArray };
+ return makeOptionalFromPointer(profilesMap.tryGet(profile));
}
-static bool isValidDoViProfileID(unsigned short profileID)
+static bool isValidDoViProfileID(uint16_t profileID)
{
switch (profileID) {
case 4:
@@ -161,7 +156,7 @@
}
}
-static Optional<unsigned short> maximumLevelIDForDoViProfileID(unsigned short profileID)
+static Optional<uint16_t> maximumLevelIDForDoViProfileID(uint16_t profileID)
{
// See Section 4.1 of "Dolby Vision Profiles and Levels Version 1.3.2"
switch (profileID) {
@@ -174,27 +169,27 @@
}
}
-static bool isValidProfileIDForCodecName(unsigned short profileID, const String& codecName)
+static bool isValidProfileIDForCodec(uint16_t profileID, DoViParameters::Codec codec)
{
if (profileID == 9)
- return codecName == "avc1" || codecName == "avc3";
- return codecName == "hvc1" || codecName == "hev1";
+ return codec == DoViParameters::Codec::AVC1 || codec == DoViParameters::Codec::AVC3;
+ return codec == DoViParameters::Codec::HVC1 || codec == DoViParameters::Codec::HEV1;
}
-Optional<DoViParameterSet> parseDoViCodecParameters(const String& codecString)
+Optional<DoViParameters> parseDoViCodecParameters(StringView codecView)
{
// The format of the DoVi codec string is specified in "Dolby Vision Profiles and Levels Version 1.3.2"
- StringView codecView(codecString);
auto codecSplit = codecView.split('.');
auto nextElement = codecSplit.begin();
if (nextElement == codecSplit.end())
return WTF::nullopt;
- DoViParameterSet parameters;
+ DoViParameters parameters;
- parameters.codecName = codecStringForDoViCodecType((*nextElement).toString());
- if (!parameters.codecName)
+ auto codec = parseDoViCodecType(*nextElement);
+ if (!codec)
return WTF::nullopt;
+ parameters.codec = *codec;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
@@ -211,17 +206,16 @@
if (!isIntegral)
return WTF::nullopt;
} else {
- auto alphanumericProfileString = codecView.left(5 + profileID.length()).toString();
- auto profileID = profileIDForAlphabeticDoViProfile(alphanumericProfileString);
- if (!profileID)
+ auto bitstreamProfileID = profileIDForAlphabeticDoViProfile(codecView.left(5 + profileID.length()));
+ if (!bitstreamProfileID)
return WTF::nullopt;
- parameters.bitstreamProfileID = profileID.value();
+ parameters.bitstreamProfileID = *bitstreamProfileID;
}
if (!isValidDoViProfileID(parameters.bitstreamProfileID))
return WTF::nullopt;
- if (!isValidProfileIDForCodecName(parameters.bitstreamProfileID, parameters.codecName))
+ if (!isValidProfileIDForCodec(parameters.bitstreamProfileID, parameters.codec))
return WTF::nullopt;
if (++nextElement == codecSplit.end())
@@ -236,7 +230,7 @@
return WTF::nullopt;
auto maximumLevelID = maximumLevelIDForDoViProfileID(parameters.bitstreamProfileID);
- if (!maximumLevelID || parameters.bitstreamLevelID > maximumLevelID.value())
+ if (!maximumLevelID || parameters.bitstreamLevelID > *maximumLevelID)
return WTF::nullopt;
return parameters;
Modified: trunk/Source/WebCore/platform/graphics/HEVCUtilities.h (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/HEVCUtilities.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/HEVCUtilities.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2021 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,29 +25,25 @@
#pragma once
-#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/Forward.h>
namespace WebCore {
-struct HEVCParameterSet {
- String codecName;
- unsigned short generalProfileSpace { 0 };
- unsigned short generalProfileIDC { 0 };
+struct HEVCParameters {
+ uint16_t generalProfileSpace { 0 };
+ uint16_t generalProfileIDC { 0 };
uint32_t generalProfileCompatibilityFlags { 0 };
- bool generalTierFlag { false };
- unsigned short generalLevelIDC { 0 };
- Vector<unsigned short> constraintFlags { 6, 0 };
+ uint16_t generalLevelIDC { 0 };
};
-WEBCORE_EXPORT Optional<HEVCParameterSet> parseHEVCCodecParameters(const String& codecString);
+WEBCORE_EXPORT Optional<HEVCParameters> parseHEVCCodecParameters(StringView);
-struct DoViParameterSet {
- String codecName;
- unsigned short bitstreamProfileID { 0 };
- unsigned short bitstreamLevelID { 0 };
+struct DoViParameters {
+ enum class Codec { AVC1, AVC3, HEV1, HVC1 } codec;
+ uint16_t bitstreamProfileID { 0 };
+ uint16_t bitstreamLevelID { 0 };
};
-WEBCORE_EXPORT Optional<DoViParameterSet> parseDoViCodecParameters(const String& codecString);
+WEBCORE_EXPORT Optional<DoViParameters> parseDoViCodecParameters(StringView);
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.h (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -33,8 +33,8 @@
struct MediaCapabilitiesInfo;
-extern bool validateHEVCParameters(HEVCParameterSet&, MediaCapabilitiesInfo&, bool hasAlphaChannel, bool hdrSupport);
-extern bool validateDoViParameters(DoViParameterSet&, MediaCapabilitiesInfo&, bool hasAlphaChannel, bool hdrSupport);
+Optional<MediaCapabilitiesInfo> validateHEVCParameters(const HEVCParameters&, bool hasAlphaChannel, bool hdrSupport);
+Optional<MediaCapabilitiesInfo> validateDoViParameters(const DoViParameters&, bool hasAlphaChannel, bool hdrSupport);
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.mm (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.mm 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/cocoa/HEVCUtilitiesCocoa.mm 2021-05-06 16:08:17 UTC (rev 277093)
@@ -40,16 +40,16 @@
namespace WebCore {
-bool validateHEVCParameters(HEVCParameterSet& parameters, MediaCapabilitiesInfo& info, bool hasAlphaChannel, bool hdrSupport)
+Optional<MediaCapabilitiesInfo> validateHEVCParameters(const HEVCParameters& parameters, bool hasAlphaChannel, bool hdrSupport)
{
CMVideoCodecType codec = kCMVideoCodecType_HEVC;
if (hasAlphaChannel) {
if (!PAL::isAVFoundationFrameworkAvailable() || !PAL::canLoad_AVFoundation_AVVideoCodecTypeHEVCWithAlpha())
- return false;
+ return WTF::nullopt;
auto codecCode = FourCC::fromString(AVVideoCodecTypeHEVCWithAlpha);
if (!codecCode)
- return false;
+ return WTF::nullopt;
codec = codecCode.value().value;
}
@@ -59,12 +59,12 @@
bool isMain10 = parameters.generalProfileSpace == 0
&& (parameters.generalProfileIDC == 2 || parameters.generalProfileCompatibilityFlags == 1);
if (!isMain10)
- return false;
+ return WTF::nullopt;
}
OSStatus status = VTSelectAndCreateVideoDecoderInstance(codec, kCFAllocatorDefault, nullptr, nullptr);
if (status != noErr)
- return false;
+ return WTF::nullopt;
if (!canLoad_VideoToolbox_VTCopyHEVCDecoderCapabilitiesDictionary()
|| !canLoad_VideoToolbox_kVTHEVCDecoderCapability_SupportedProfiles()
@@ -72,31 +72,35 @@
|| !canLoad_VideoToolbox_kVTHEVCDecoderProfileCapability_IsHardwareAccelerated()
|| !canLoad_VideoToolbox_kVTHEVCDecoderProfileCapability_MaxDecodeLevel()
|| !canLoad_VideoToolbox_kVTHEVCDecoderProfileCapability_MaxPlaybackLevel())
- return false;
+ return WTF::nullopt;
- RetainPtr<CFDictionaryRef> capabilities = adoptCF(VTCopyHEVCDecoderCapabilitiesDictionary());
+ auto capabilities = adoptCF(VTCopyHEVCDecoderCapabilitiesDictionary());
if (!capabilities)
- return false;
+ return WTF::nullopt;
auto supportedProfiles = (CFArrayRef)CFDictionaryGetValue(capabilities.get(), kVTHEVCDecoderCapability_SupportedProfiles);
if (!supportedProfiles || CFGetTypeID(supportedProfiles) != CFArrayGetTypeID())
- return false;
+ return WTF::nullopt;
int16_t generalProfileIDC = parameters.generalProfileIDC;
auto cfGeneralProfileIDC = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt16Type, &generalProfileIDC));
auto searchRange = CFRangeMake(0, CFArrayGetCount(supportedProfiles));
if (!CFArrayContainsValue(supportedProfiles, searchRange, cfGeneralProfileIDC.get()))
- return false;
+ return WTF::nullopt;
auto perProfileSupport = (CFDictionaryRef)CFDictionaryGetValue(capabilities.get(), kVTHEVCDecoderCapability_PerProfileSupport);
if (!perProfileSupport || CFGetTypeID(perProfileSupport) != CFDictionaryGetTypeID())
- return false;
+ return WTF::nullopt;
auto generalProfileIDCString = String::number(generalProfileIDC).createCFString();
auto profileSupport = (CFDictionaryRef)CFDictionaryGetValue(perProfileSupport, generalProfileIDCString.get());
if (!profileSupport || CFGetTypeID(profileSupport) != CFDictionaryGetTypeID())
- return false;
+ return WTF::nullopt;
+ MediaCapabilitiesInfo info;
+
+ info.supported = true;
+
auto isHardwareAccelerated = (CFBooleanRef)CFDictionaryGetValue(profileSupport, kVTHEVCDecoderProfileCapability_IsHardwareAccelerated);
if (isHardwareAccelerated && CFGetTypeID(isHardwareAccelerated) == CFBooleanGetTypeID())
info.powerEfficient = CFBooleanGetValue(isHardwareAccelerated);
@@ -105,12 +109,10 @@
if (cfMaxDecodeLevel && CFGetTypeID(cfMaxDecodeLevel) == CFNumberGetTypeID()) {
int16_t maxDecodeLevel = 0;
if (!CFNumberGetValue(cfMaxDecodeLevel, kCFNumberSInt16Type, &maxDecodeLevel))
- return false;
+ return WTF::nullopt;
if (parameters.generalLevelIDC > maxDecodeLevel)
- return false;
-
- info.supported = true;
+ return WTF::nullopt;
}
auto cfMaxPlaybackLevel = (CFNumberRef)CFDictionaryGetValue(profileSupport, kVTHEVCDecoderProfileCapability_MaxPlaybackLevel);
@@ -117,68 +119,50 @@
if (cfMaxPlaybackLevel && CFGetTypeID(cfMaxPlaybackLevel) == CFNumberGetTypeID()) {
int16_t maxPlaybackLevel = 0;
if (!CFNumberGetValue(cfMaxPlaybackLevel, kCFNumberSInt16Type, &maxPlaybackLevel))
- return false;
+ return WTF::nullopt;
info.smooth = parameters.generalLevelIDC <= maxPlaybackLevel;
}
- return true;
+ return info;
}
-static Optional<CMVideoCodecType> codecTypeForDoViCodecString(const String& codecString)
+static CMVideoCodecType codecType(DoViParameters::Codec codec)
{
- static auto map = makeNeverDestroyed<MemoryCompactLookupOnlyRobinHoodHashMap<String, CMVideoCodecType>>({
- { "avc1"_s, kCMVideoCodecType_H264 },
- { "avc3"_s, kCMVideoCodecType_H264 },
- { "hvc1"_s, kCMVideoCodecType_HEVC },
- { "hev1"_s, kCMVideoCodecType_HEVC },
- });
-
- auto findResult = map.get().find(codecString);
- if (findResult == map.get().end())
- return WTF::nullopt;
- return findResult->value;
+ switch (codec) {
+ case DoViParameters::Codec::AVC1:
+ case DoViParameters::Codec::AVC3:
+ return kCMVideoCodecType_H264;
+ case DoViParameters::Codec::HEV1:
+ case DoViParameters::Codec::HVC1:
+ return kCMVideoCodecType_HEVC;
+ }
}
-static Optional<Vector<unsigned short>> CFStringArrayToNumberVector(CFArrayRef arrayCF)
+static Optional<Vector<uint16_t>> parseStringArrayFromDictionaryToUInt16Vector(CFDictionaryRef dictionary, const void* key)
{
- if (!arrayCF || CFGetTypeID(arrayCF) != CFArrayGetTypeID())
+ auto value = CFDictionaryGetValue(dictionary, key);
+ if (!value || CFGetTypeID(value) != CFArrayGetTypeID())
return WTF::nullopt;
-
- auto arrayNS = (__bridge NSArray<NSString*>*)arrayCF;
- Vector<unsigned short> values;
- values.reserveInitialCapacity(arrayNS.count);
-
- bool areAllValidNumbers = true;
- [arrayNS enumerateObjectsUsingBlock:[&] (NSString* value, NSUInteger, BOOL *stop) {
- if (![value isKindOfClass:NSString.class]) {
- areAllValidNumbers = false;
- if (stop)
- *stop = true;
- return;
- }
-
+ NSArray *array = (__bridge NSArray *)value;
+ Vector<uint16_t> vector;
+ vector.reserveInitialCapacity(array.count);
+ for (id value in array) {
+ if (![value isKindOfClass:NSString.class])
+ return WTF::nullopt;
bool isValidNumber = false;
- auto numericValue = toIntegralType<unsigned short>(String(value), &isValidNumber);
- if (!isValidNumber) {
- areAllValidNumbers = false;
- if (stop)
- *stop = true;
- return;
- }
-
- values.uncheckedAppend(numericValue);
- }];
-
- if (!areAllValidNumbers)
- return WTF::nullopt;
- return values;
+ auto numericValue = toIntegralType<uint16_t>(String((NSString *)value), &isValidNumber);
+ if (!isValidNumber)
+ return WTF::nullopt;
+ vector.uncheckedAppend(numericValue);
+ }
+ return vector;
}
-bool validateDoViParameters(DoViParameterSet& parameters, MediaCapabilitiesInfo& info, bool hasAlphaChannel, bool hdrSupport)
+Optional<MediaCapabilitiesInfo> validateDoViParameters(const DoViParameters& parameters, bool hasAlphaChannel, bool hdrSupport)
{
if (hasAlphaChannel)
- return false;
+ return WTF::nullopt;
if (hdrSupport) {
// Platform supports HDR playback of HEVC Main10 Profile, which is signalled by DoVi profiles 4, 5, 7, & 8.
@@ -189,50 +173,41 @@
case 8:
break;
default:
- return false;
+ return WTF::nullopt;
}
}
- auto codecType = codecTypeForDoViCodecString(parameters.codecName);
- if (!codecType)
- return false;
-
- OSStatus status = VTSelectAndCreateVideoDecoderInstance(codecType.value(), kCFAllocatorDefault, nullptr, nullptr);
+ OSStatus status = VTSelectAndCreateVideoDecoderInstance(codecType(parameters.codec), kCFAllocatorDefault, nullptr, nullptr);
if (status != noErr)
- return false;
+ return WTF::nullopt;
if (!canLoad_VideoToolbox_VTCopyHEVCDecoderCapabilitiesDictionary()
|| !canLoad_VideoToolbox_kVTDolbyVisionDecoderCapability_SupportedProfiles()
|| !canLoad_VideoToolbox_kVTDolbyVisionDecoderCapability_SupportedLevels()
|| !canLoad_VideoToolbox_kVTDolbyVisionDecoderCapability_IsHardwareAccelerated())
- return false;
+ return WTF::nullopt;
- RetainPtr<CFDictionaryRef> capabilities = adoptCF(VTCopyHEVCDecoderCapabilitiesDictionary());
+ auto capabilities = adoptCF(VTCopyHEVCDecoderCapabilitiesDictionary());
if (!capabilities)
- return false;
+ return WTF::nullopt;
- auto supportedProfilesCF = (CFArrayRef)CFDictionaryGetValue(capabilities.get(), kVTDolbyVisionDecoderCapability_SupportedProfiles);
- auto supportedProfiles = CFStringArrayToNumberVector(supportedProfilesCF);
+ auto supportedProfiles = parseStringArrayFromDictionaryToUInt16Vector(capabilities.get(), kVTDolbyVisionDecoderCapability_SupportedProfiles);
if (!supportedProfiles)
- return false;
+ return WTF::nullopt;
- auto supportedLevelsCF = (CFArrayRef)CFDictionaryGetValue(capabilities.get(), kVTDolbyVisionDecoderCapability_SupportedLevels);
- auto supportedLevels = CFStringArrayToNumberVector(supportedLevelsCF);
+ auto supportedLevels = parseStringArrayFromDictionaryToUInt16Vector(capabilities.get(), kVTDolbyVisionDecoderCapability_SupportedLevels);
if (!supportedLevels)
- return false;
+ return WTF::nullopt;
auto isHardwareAcceleratedCF = (CFBooleanRef)CFDictionaryGetValue(capabilities.get(), kVTDolbyVisionDecoderCapability_IsHardwareAccelerated);
if (!isHardwareAcceleratedCF || CFGetTypeID(isHardwareAcceleratedCF) != CFBooleanGetTypeID())
- return false;
+ return WTF::nullopt;
+ bool isHardwareAccelerated = CFBooleanGetValue(isHardwareAcceleratedCF);
if (!supportedProfiles.value().contains(parameters.bitstreamProfileID) || !supportedLevels.value().contains(parameters.bitstreamLevelID))
- return false;
+ return WTF::nullopt;
- info.supported = true;
- info.smooth = true;
- info.powerEfficient = CFBooleanGetValue(isHardwareAcceleratedCF);
-
- return true;
+ return { { true, true, isHardwareAccelerated } };
}
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/cocoa/MediaEngineConfigurationFactoryCocoa.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -40,7 +40,7 @@
namespace WebCore {
-static CMVideoCodecType videoCodecTypeFromRFC4281Type(String type)
+static CMVideoCodecType videoCodecTypeFromRFC4281Type(StringView type)
{
if (type.startsWith("mp4v"))
return kCMVideoCodecType_MPEG4Video;
@@ -55,9 +55,9 @@
return 0;
}
-void createMediaPlayerDecodingConfigurationCocoa(MediaDecodingConfiguration&& configuration, WTF::Function<void(MediaCapabilitiesDecodingInfo&&)>&& callback)
+static Optional<MediaCapabilitiesInfo> computeMediaCapabilitiesInfo(const MediaDecodingConfiguration& configuration)
{
- MediaCapabilitiesDecodingInfo info;
+ MediaCapabilitiesInfo info;
if (configuration.video) {
auto& videoConfiguration = configuration.video.value();
@@ -64,24 +64,18 @@
MediaEngineSupportParameters parameters { };
parameters.type = ContentType(videoConfiguration.contentType);
parameters.isMediaSource = configuration.type == MediaDecodingType::MediaSource;
- if (MediaPlayer::supportsType(parameters) != MediaPlayer::SupportsType::IsSupported) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (MediaPlayer::supportsType(parameters) != MediaPlayer::SupportsType::IsSupported)
+ return WTF::nullopt;
auto codecs = parameters.type.codecs();
- if (codecs.size() != 1) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (codecs.size() != 1)
+ return WTF::nullopt;
info.supported = true;
auto& codec = codecs[0];
auto videoCodecType = videoCodecTypeFromRFC4281Type(codec);
- if (!videoCodecType && !(codec.startsWith("dvh1") || codec.startsWith("dvhe"))) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (!videoCodecType && !(codec.startsWith("dvh1") || codec.startsWith("dvhe")))
+ return WTF::nullopt;
bool hdrSupported = videoConfiguration.colorGamut || videoConfiguration.hdrMetadataType || videoConfiguration.transferFunction;
bool alphaChannel = videoConfiguration.alphaChannel && videoConfiguration.alphaChannel.value();
@@ -88,33 +82,35 @@
if (videoCodecType == kCMVideoCodecType_HEVC) {
auto parameters = parseHEVCCodecParameters(codec);
- if (!parameters || !validateHEVCParameters(parameters.value(), info, alphaChannel, hdrSupported)) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (!parameters)
+ return WTF::nullopt;
+ auto parsedInfo = validateHEVCParameters(*parameters, alphaChannel, hdrSupported);
+ if (!parsedInfo)
+ return WTF::nullopt;
+ info = *parsedInfo;
} else if (codec.startsWith("dvh1") || codec.startsWith("dvhe")) {
auto parameters = parseDoViCodecParameters(codec);
- if (!parameters || !validateDoViParameters(parameters.value(), info, alphaChannel, hdrSupported)) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (!parameters)
+ return WTF::nullopt;
+ auto parsedInfo = validateDoViParameters(*parameters, alphaChannel, hdrSupported);
+ if (!parsedInfo)
+ return WTF::nullopt;
+ info = *parsedInfo;
#if ENABLE(VP9)
} else if (videoCodecType == kCMVideoCodecType_VP9) {
- if (!configuration.canExposeVP9) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
- auto codecConfiguration = parseVPCodecParameters(codec);
- if (!codecConfiguration || !validateVPParameters(*codecConfiguration, info, videoConfiguration)) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (!configuration.canExposeVP9)
+ return WTF::nullopt;
+ auto parameters = parseVPCodecParameters(codec);
+ if (!parameters)
+ return WTF::nullopt;
+ auto parsedInfo = validateVPParameters(*parameters, videoConfiguration);
+ if (!parsedInfo)
+ return WTF::nullopt;
+ info = *parsedInfo;
#endif
} else {
- if (alphaChannel || hdrSupported) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (alphaChannel || hdrSupported)
+ return WTF::nullopt;
if (canLoad_VideoToolbox_VTIsHardwareDecodeSupported()) {
info.powerEfficient = VTIsHardwareDecodeSupported(videoCodecType);
@@ -127,42 +123,39 @@
MediaEngineSupportParameters parameters { };
parameters.type = ContentType(configuration.audio.value().contentType);
parameters.isMediaSource = configuration.type == MediaDecodingType::MediaSource;
- if (MediaPlayer::supportsType(parameters) != MediaPlayer::SupportsType::IsSupported) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (MediaPlayer::supportsType(parameters) != MediaPlayer::SupportsType::IsSupported)
+ return WTF::nullopt;
if (configuration.audio->spatialRendering.valueOr(false)) {
auto context = PAL::OutputContext::sharedAudioPresentationOutputContext();
- if (!context) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ if (!context)
+ return WTF::nullopt;
auto devices = context->outputDevices();
if (devices.isEmpty() || !WTF::allOf(devices, [](auto& device) {
return device.supportsSpatialAudio();
- })) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
+ }))
+ return WTF::nullopt;
// Only multichannel audio can be spatially rendered.
- if (!configuration.audio->channels.isNull()) {
- bool isOk = false;
- auto parsedChannels = configuration.audio->channels.toDouble(&isOk);
- if (!isOk || parsedChannels <= 2) {
- callback({{ }, WTFMove(configuration)});
- return;
- }
- }
+ if (!configuration.audio->channels.isNull() && configuration.audio->channels.toDouble() <= 2)
+ return WTF::nullopt;
}
info.supported = true;
}
- info.supportedConfiguration = WTFMove(configuration);
+ return info;
+}
- callback(WTFMove(info));
+void createMediaPlayerDecodingConfigurationCocoa(MediaDecodingConfiguration&& configuration, WTF::Function<void(MediaCapabilitiesDecodingInfo&&)>&& callback)
+{
+ auto info = computeMediaCapabilitiesInfo(configuration);
+ if (!info)
+ callback({ { }, WTFMove(configuration) });
+ else {
+ MediaCapabilitiesDecodingInfo infoWithConfiguration = { WTFMove(*info), WTFMove(configuration) };
+ callback(WTFMove(infoWithConfiguration));
+ }
}
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.h (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -41,13 +41,13 @@
struct MediaCapabilitiesInfo;
struct VideoConfiguration;
-WEBCORE_EXPORT extern void registerWebKitVP9Decoder();
-WEBCORE_EXPORT extern void registerWebKitVP8Decoder();
-WEBCORE_EXPORT extern void registerSupplementalVP9Decoder();
-extern bool isVP9DecoderAvailable();
-extern bool isVP8DecoderAvailable();
-extern bool isVPCodecConfigurationRecordSupported(VPCodecConfigurationRecord&);
-extern bool validateVPParameters(VPCodecConfigurationRecord&, MediaCapabilitiesInfo&, const VideoConfiguration&);
+WEBCORE_EXPORT void registerWebKitVP9Decoder();
+WEBCORE_EXPORT void registerWebKitVP8Decoder();
+WEBCORE_EXPORT void registerSupplementalVP9Decoder();
+bool isVP9DecoderAvailable();
+bool isVP8DecoderAvailable();
+bool isVPCodecConfigurationRecordSupported(const VPCodecConfigurationRecord&);
+Optional<MediaCapabilitiesInfo> validateVPParameters(const VPCodecConfigurationRecord&, const VideoConfiguration&);
RetainPtr<CMFormatDescriptionRef> createFormatDescriptionFromVP9HeaderParser(const vp9_parser::Vp9HeaderParser&, const webm::Element<webm::Colour>&);
Modified: trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.mm (277092 => 277093)
--- trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.mm 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/graphics/cocoa/VP9UtilitiesCocoa.mm 2021-05-06 16:08:17 UTC (rev 277093)
@@ -148,7 +148,7 @@
return canLoad_VideoToolbox_VTIsHardwareDecodeSupported() && VTIsHardwareDecodeSupported(kCMVideoCodecType_VP9);
}
-static bool isVP9CodecConfigurationRecordSupported(VPCodecConfigurationRecord& codecConfiguration)
+static bool isVP9CodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
if (!isVP9DecoderAvailable())
return false;
@@ -199,7 +199,7 @@
return has4kScreen;
}
-static bool isVP8CodecConfigurationRecordSupported(VPCodecConfigurationRecord& codecConfiguration)
+static bool isVP8CodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
if (!isVP8DecoderAvailable())
return false;
@@ -219,7 +219,7 @@
return true;
}
-bool isVPCodecConfigurationRecordSupported(VPCodecConfigurationRecord& codecConfiguration)
+bool isVPCodecConfigurationRecordSupported(const VPCodecConfigurationRecord& codecConfiguration)
{
if (codecConfiguration.codecName == "vp08" || codecConfiguration.codecName == "vp8")
return isVP8CodecConfigurationRecordSupported(codecConfiguration);
@@ -230,36 +230,38 @@
return false;
}
-bool validateVPParameters(VPCodecConfigurationRecord& codecConfiguration, MediaCapabilitiesInfo& info, const VideoConfiguration& videoConfiguration)
+Optional<MediaCapabilitiesInfo> validateVPParameters(const VPCodecConfigurationRecord& codecConfiguration, const VideoConfiguration& videoConfiguration)
{
if (!isVPCodecConfigurationRecordSupported(codecConfiguration))
- return false;
+ return WTF::nullopt;
// VideoConfiguration and VPCodecConfigurationRecord can have conflicting values for HDR properties. If so, reject.
if (videoConfiguration.transferFunction) {
// Note: Transfer Characteristics are defined by ISO/IEC 23091-2:2019.
if (*videoConfiguration.transferFunction == TransferFunction::SRGB && codecConfiguration.transferCharacteristics > 15)
- return false;
+ return WTF::nullopt;
if (*videoConfiguration.transferFunction == TransferFunction::PQ && codecConfiguration.transferCharacteristics != 16)
- return false;
+ return WTF::nullopt;
if (*videoConfiguration.transferFunction == TransferFunction::HLG && codecConfiguration.transferCharacteristics != 18)
- return false;
+ return WTF::nullopt;
}
if (videoConfiguration.colorGamut) {
if (*videoConfiguration.colorGamut == ColorGamut::Rec2020 && codecConfiguration.colorPrimaries != 9)
- return false;
+ return WTF::nullopt;
}
+ MediaCapabilitiesInfo info;
+
if (vp9HardwareDecoderAvailable()) {
// HW VP9 Decoder does not support alpha channel:
if (videoConfiguration.alphaChannel && *videoConfiguration.alphaChannel)
- return false;
+ return WTF::nullopt;
// HW VP9 Decoder can support up to 4K @ 120 or 8K @ 30
auto resolution = resolutionCategory({ (float)videoConfiguration.width, (float)videoConfiguration.height });
if (resolution > ResolutionCategory::R_8K)
- return false;
+ return WTF::nullopt;
if (resolution == ResolutionCategory::R_8K && videoConfiguration.framerate > 30)
info.smooth = false;
else if (resolution <= ResolutionCategory::R_4K && videoConfiguration.framerate > 120)
@@ -269,7 +271,7 @@
info.powerEfficient = true;
info.supported = true;
- return true;
+ return info;
}
info.powerEfficient = false;
@@ -287,7 +289,7 @@
// For wall-powered devices, always report VP9 as supported, even if not powerEfficient.
if (!systemHasBattery()) {
info.supported = true;
- return true;
+ return info;
}
// For battery-powered devices, always report VP9 as supported when running on AC power,
@@ -295,7 +297,7 @@
// to support 4K video.
if (systemHasAC()) {
info.supported = true;
- return true;
+ return info;
}
bool has4kScreen = false;
@@ -313,10 +315,10 @@
}
if (!has4kScreen)
- return false;
+ return WTF::nullopt;
info.supported = true;
- return true;
+ return info;
}
static uint8_t convertToColorPrimaries(const Primaries& coefficients)
Modified: trunk/Source/WebCore/platform/network/HTTPHeaderMap.h (277092 => 277093)
--- trunk/Source/WebCore/platform/network/HTTPHeaderMap.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/network/HTTPHeaderMap.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -28,9 +28,7 @@
#include "HTTPHeaderNames.h"
#include <utility>
-#include <wtf/HashMap.h>
-#include <wtf/Optional.h>
-#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/text/LocaleToScriptMapping.cpp (277092 => 277093)
--- trunk/Source/WebCore/platform/text/LocaleToScriptMapping.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/platform/text/LocaleToScriptMapping.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -38,81 +38,6 @@
namespace WebCore {
-// FIXME: Consider moving alongside ComparableASCIILiteral and giving an even better name.
-template<typename StorageInteger>
-class PackedASCIILowerCodes {
-public:
- static_assert(std::is_unsigned_v<StorageInteger>);
-
- template<unsigned characterCountPlusOne>
- constexpr PackedASCIILowerCodes(const char (&string)[characterCountPlusOne])
- {
- constexpr unsigned length = characterCountPlusOne - 1;
- ASSERT_UNDER_CONSTEXPR_CONTEXT(length <= sizeof(StorageInteger));
- ASSERT_UNDER_CONSTEXPR_CONTEXT(!string[length]);
- StorageInteger result = 0;
- for (unsigned index = 0; index < length; ++index) {
- uint8_t code = static_cast<uint8_t>(string[index]);
- result |= static_cast<StorageInteger>(code) << ((sizeof(StorageInteger) - index - 1) * 8);
- }
- m_value = result;
- }
-
- static Optional<PackedASCIILowerCodes> parse(StringView string)
- {
- if (string.length() > sizeof(StorageInteger))
- return WTF::nullopt;
- StorageInteger result = 0;
- for (unsigned index = 0; index < string.length(); ++index) {
- UChar code = string[index];
- if (!isASCII(code))
- return WTF::nullopt;
- result |= static_cast<StorageInteger>(toASCIILower(code)) << ((sizeof(StorageInteger) - index - 1) * 8);
- }
- return PackedASCIILowerCodes(result);
- }
-
- friend constexpr bool operator==(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value == rhs.m_value;
- }
-
- friend constexpr bool operator!=(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value != rhs.m_value;
- }
-
- friend constexpr bool operator<(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value < rhs.m_value;
- }
-
- friend constexpr bool operator<=(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value <= rhs.m_value;
- }
-
- friend constexpr bool operator>(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value > rhs.m_value;
- }
-
- friend constexpr bool operator>=(PackedASCIILowerCodes lhs, PackedASCIILowerCodes rhs)
- {
- return lhs.m_value >= rhs.m_value;
- }
-
- constexpr StorageInteger value() const { return m_value; }
-
-private:
- explicit constexpr PackedASCIILowerCodes(StorageInteger value)
- : m_value(value)
- {
- }
-
- StorageInteger m_value { 0 };
-};
-
UScriptCode scriptNameToCode(StringView scriptName)
{
// This generally maps an ISO 15924 script code to its UScriptCode, but certain families of script codes are
Modified: trunk/Source/WebCore/testing/Internals.cpp (277092 => 277093)
--- trunk/Source/WebCore/testing/Internals.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/testing/Internals.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -5758,19 +5758,39 @@
return WebCore::PlatformKeyboardEvent::currentCapsLockState();
}
-Optional<HEVCParameterSet> Internals::parseHEVCCodecParameters(const String& codecString)
+auto Internals::parseHEVCCodecParameters(StringView string) -> Optional<HEVCParameterSet>
{
- return WebCore::parseHEVCCodecParameters(codecString);
+ return WebCore::parseHEVCCodecParameters(string);
}
-Optional<DoViParameterSet> Internals::parseDoViCodecParameters(const String& codecString)
+auto Internals::parseDoViCodecParameters(StringView string) -> Optional<DoViParameterSet>
{
- return WebCore::parseDoViCodecParameters(codecString);
+ auto parseResult = WebCore::parseDoViCodecParameters(string);
+ if (!parseResult)
+ return WTF::nullopt;
+ DoViParameterSet convertedResult;
+ switch (parseResult->codec) {
+ case DoViParameters::Codec::AVC1:
+ convertedResult.codecName = "avc1"_s;
+ break;
+ case DoViParameters::Codec::AVC3:
+ convertedResult.codecName = "avc3"_s;
+ break;
+ case DoViParameters::Codec::HEV1:
+ convertedResult.codecName = "hev1"_s;
+ break;
+ case DoViParameters::Codec::HVC1:
+ convertedResult.codecName = "hvc1"_s;
+ break;
+ }
+ convertedResult.bitstreamProfileID = parseResult->bitstreamProfileID;
+ convertedResult.bitstreamLevelID = parseResult->bitstreamLevelID;
+ return convertedResult;
}
-Optional<VPCodecConfigurationRecord> Internals::parseVPCodecParameters(const String& codecString)
+Optional<VPCodecConfigurationRecord> Internals::parseVPCodecParameters(StringView string)
{
- return WebCore::parseVPCodecParameters(codecString);
+ return WebCore::parseVPCodecParameters(string);
}
auto Internals::getCookies() const -> Vector<CookieData>
Modified: trunk/Source/WebCore/testing/Internals.h (277092 => 277093)
--- trunk/Source/WebCore/testing/Internals.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/testing/Internals.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -974,14 +974,18 @@
bool capsLockIsOn();
- using HEVCParameterSet = WebCore::HEVCParameterSet;
- Optional<HEVCParameterSet> parseHEVCCodecParameters(const String& codecString);
+ using HEVCParameterSet = WebCore::HEVCParameters;
+ Optional<HEVCParameterSet> parseHEVCCodecParameters(StringView);
- using DoViParameterSet = WebCore::DoViParameterSet;
- Optional<DoViParameterSet> parseDoViCodecParameters(const String& codecString);
+ struct DoViParameterSet {
+ String codecName;
+ uint16_t bitstreamProfileID;
+ uint16_t bitstreamLevelID;
+ };
+ Optional<DoViParameterSet> parseDoViCodecParameters(StringView);
using VPCodecConfigurationRecord = WebCore::VPCodecConfigurationRecord;
- Optional<VPCodecConfigurationRecord> parseVPCodecParameters(const String& codecString);
+ Optional<VPCodecConfigurationRecord> parseVPCodecParameters(StringView);
struct CookieData {
String name;
Modified: trunk/Source/WebCore/testing/Internals.idl (277092 => 277093)
--- trunk/Source/WebCore/testing/Internals.idl 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebCore/testing/Internals.idl 2021-05-06 16:08:17 UTC (rev 277093)
@@ -171,13 +171,10 @@
ExportMacro=WEBCORE_TESTSUPPORT_EXPORT,
JSGenerateToJSObject,
] dictionary HEVCParameterSet {
- DOMString codecName;
unsigned short generalProfileSpace;
unsigned short generalProfileIDC;
unsigned long generalProfileCompatibilityFlags;
- boolean generalTierFlag;
unsigned short generalLevelIDC;
- sequence<unsigned short> constraintFlags;
};
[
Modified: trunk/Source/WebKit/ChangeLog (277092 => 277093)
--- trunk/Source/WebKit/ChangeLog 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebKit/ChangeLog 2021-05-06 16:08:17 UTC (rev 277093)
@@ -1,3 +1,14 @@
+2021-05-06 Darin Adler <da...@apple.com>
+
+ Streamline codec parsing, replacing uses of HashMap with SortedArrayMap
+ https://bugs.webkit.org/show_bug.cgi?id=225368
+
+ Reviewed by Sam Weinig.
+
+ * Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
+ Removed unneeded include.
+ * Shared/WebsiteData/WebsiteData.h: Ditto.
+
2021-05-06 Martin Robinson <mrobin...@webkit.org>
[css-scroll-snap] Compute proximity information while snapping
Modified: trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp (277092 => 277093)
--- trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp 2021-05-06 16:08:17 UTC (rev 277093)
@@ -41,7 +41,6 @@
#include <WebCore/ScrollingStatePositionedNode.h>
#include <WebCore/ScrollingStateStickyNode.h>
#include <WebCore/ScrollingStateTree.h>
-#include <wtf/HashMap.h>
#include <wtf/text/CString.h>
#include <wtf/text/TextStream.h>
Modified: trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h (277092 => 277093)
--- trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h 2021-05-06 15:47:46 UTC (rev 277092)
+++ trunk/Source/WebKit/Shared/WebsiteData/WebsiteData.h 2021-05-06 16:08:17 UTC (rev 277093)
@@ -27,7 +27,6 @@
#include <WebCore/RegistrableDomain.h>
#include <WebCore/SecurityOriginData.h>
-#include <wtf/HashMap.h>
#include <wtf/HashSet.h>
#include <wtf/OptionSet.h>
#include <wtf/Vector.h>