#include "config.h"
#include "VP9Utilities.h"
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringToIntegerConversion.h>
namespace WebCore {
static bool isValidVPLevel(uint8_t level)
{
constexpr uint8_t validLevels[] = {
VPConfigurationLevel::Level_1,
VPConfigurationLevel::Level_1_1,
VPConfigurationLevel::Level_2,
VPConfigurationLevel::Level_2_1,
VPConfigurationLevel::Level_3,
VPConfigurationLevel::Level_3_1,
VPConfigurationLevel::Level_4,
VPConfigurationLevel::Level_4_1,
VPConfigurationLevel::Level_5,
VPConfigurationLevel::Level_5_1,
VPConfigurationLevel::Level_5_2,
VPConfigurationLevel::Level_6,
VPConfigurationLevel::Level_6_1,
VPConfigurationLevel::Level_6_2,
};
ASSERT(std::is_sorted(std::begin(validLevels), std::end(validLevels)));
return std::binary_search(std::begin(validLevels), std::end(validLevels), level);
}
static bool isValidVPColorPrimaries(uint8_t colorPrimaries)
{
constexpr uint8_t validColorPrimaries[] = {
VPConfigurationColorPrimaries::BT_709_6,
VPConfigurationColorPrimaries::Unspecified,
VPConfigurationColorPrimaries::BT_470_6_M,
VPConfigurationColorPrimaries::BT_470_7_BG,
VPConfigurationColorPrimaries::BT_601_7,
VPConfigurationColorPrimaries::SMPTE_ST_240,
VPConfigurationColorPrimaries::Film,
VPConfigurationColorPrimaries::BT_2020_Nonconstant_Luminance,
VPConfigurationColorPrimaries::SMPTE_ST_428_1,
VPConfigurationColorPrimaries::SMPTE_RP_431_2,
VPConfigurationColorPrimaries::SMPTE_EG_432_1,
VPConfigurationColorPrimaries::EBU_Tech_3213_E,
};
ASSERT(std::is_sorted(std::begin(validColorPrimaries), std::end(validColorPrimaries)));
return std::binary_search(std::begin(validColorPrimaries), std::end(validColorPrimaries), colorPrimaries);
}
static bool isValidVPTransferCharacteristics(uint8_t transferCharacteristics)
{
constexpr uint8_t validTransferCharacteristics[] = {
VPConfigurationTransferCharacteristics::BT_709_6,
VPConfigurationTransferCharacteristics::Unspecified,
VPConfigurationTransferCharacteristics::BT_470_6_M,
VPConfigurationTransferCharacteristics::BT_470_7_BG,
VPConfigurationTransferCharacteristics::BT_601_7,
VPConfigurationTransferCharacteristics::SMPTE_ST_240,
VPConfigurationTransferCharacteristics::Linear,
VPConfigurationTransferCharacteristics::Logrithmic,
VPConfigurationTransferCharacteristics::Logrithmic_Sqrt,
VPConfigurationTransferCharacteristics::IEC_61966_2_4,
VPConfigurationTransferCharacteristics::BT_1361_0,
VPConfigurationTransferCharacteristics::IEC_61966_2_1,
VPConfigurationTransferCharacteristics::BT_2020_10bit,
VPConfigurationTransferCharacteristics::BT_2020_12bit,
VPConfigurationTransferCharacteristics::SMPTE_ST_2084,
VPConfigurationTransferCharacteristics::SMPTE_ST_428_1,
VPConfigurationTransferCharacteristics::BT_2100_HLG,
};
ASSERT(std::is_sorted(std::begin(validTransferCharacteristics), std::end(validTransferCharacteristics)));
return std::binary_search(std::begin(validTransferCharacteristics), std::end(validTransferCharacteristics), transferCharacteristics);
}
static bool isValidVPMatrixCoefficients(uint8_t matrixCoefficients)
{
constexpr uint8_t validMatrixCoefficients[] = {
VPConfigurationMatrixCoefficients::Identity,
VPConfigurationMatrixCoefficients::BT_709_6,
VPConfigurationMatrixCoefficients::Unspecified,
VPConfigurationMatrixCoefficients::FCC,
VPConfigurationMatrixCoefficients::BT_470_7_BG,
VPConfigurationMatrixCoefficients::BT_601_7,
VPConfigurationMatrixCoefficients::SMPTE_ST_240,
VPConfigurationMatrixCoefficients::YCgCo,
VPConfigurationMatrixCoefficients::BT_2020_Nonconstant_Luminance,
VPConfigurationMatrixCoefficients::BT_2020_Constant_Luminance,
VPConfigurationMatrixCoefficients::SMPTE_ST_2085,
VPConfigurationMatrixCoefficients::Chromacity_Constant_Luminance,
VPConfigurationMatrixCoefficients::Chromacity_Nonconstant_Luminance,
VPConfigurationMatrixCoefficients::BT_2100_ICC,
};
ASSERT(std::is_sorted(std::begin(validMatrixCoefficients), std::end(validMatrixCoefficients)));
return std::binary_search(std::begin(validMatrixCoefficients), std::end(validMatrixCoefficients), matrixCoefficients);
}
Optional<VPCodecConfigurationRecord> parseVPCodecParameters(StringView codecView)
{
auto codecSplit = codecView.split('.');
auto nextElement = codecSplit.begin();
if (nextElement == codecSplit.end())
return WTF::nullopt;
VPCodecConfigurationRecord configuration;
configuration.codecName = (*nextElement).toString();
if (configuration.codecName != "vp08" && configuration.codecName != "vp09")
return WTF::nullopt;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto profile = toIntegralType<uint8_t>(*nextElement);
if (!profile || *profile > 3)
return WTF::nullopt;
configuration.profile = *profile;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto level = toIntegralType<uint8_t>(*nextElement);
if (!level || !isValidVPLevel(*level))
return WTF::nullopt;
configuration.level = *level;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto bitDepth = toIntegralType<uint8_t>(*nextElement);
if (!bitDepth || (*bitDepth != 8 && *bitDepth != 10 && *bitDepth != 12))
return WTF::nullopt;
configuration.bitDepth = *bitDepth;
if (++nextElement == codecSplit.end())
return configuration;
auto chromaSubsampling = toIntegralType<uint8_t>(*nextElement);
if (!chromaSubsampling || *chromaSubsampling > VPConfigurationChromaSubsampling::Subsampling_444)
return WTF::nullopt;
configuration.chromaSubsampling = *chromaSubsampling;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto colorPrimaries = toIntegralType<uint8_t>(*nextElement);
if (!colorPrimaries || !isValidVPColorPrimaries(*colorPrimaries))
return WTF::nullopt;
configuration.colorPrimaries = *colorPrimaries;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto transferCharacteristics = toIntegralType<uint8_t>(*nextElement);
if (!transferCharacteristics || !isValidVPTransferCharacteristics(*transferCharacteristics))
return WTF::nullopt;
configuration.transferCharacteristics = *transferCharacteristics;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto matrixCoefficients = toIntegralType<uint8_t>(*nextElement);
if (!matrixCoefficients || !isValidVPMatrixCoefficients(*matrixCoefficients))
return WTF::nullopt;
configuration.matrixCoefficients = *matrixCoefficients;
if (!configuration.matrixCoefficients && configuration.chromaSubsampling != 3)
return WTF::nullopt;
if (++nextElement == codecSplit.end())
return WTF::nullopt;
auto videoFullRangeFlag = toIntegralType<uint8_t>(*nextElement);
if (!videoFullRangeFlag || *videoFullRangeFlag > 1)
return WTF::nullopt;
configuration.videoFullRangeFlag = *videoFullRangeFlag;
if (++nextElement != codecSplit.end())
return WTF::nullopt;
return configuration;
}
}