mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-23 15:47:30 +09:00
Issue #1820 - Part 1 : Add an extraction function to parse the RFC-6381 VP9 codec string.
This commit is contained in:
parent
f0e5e56533
commit
55504b39bf
2 changed files with 202 additions and 1 deletions
|
|
@ -223,13 +223,186 @@ already_AddRefed<SharedThreadPool> GetMediaThreadPool(MediaThreadType aType)
|
||||||
return pool.forget();
|
return pool.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ExtractVPXCodecDetails(const nsAString& aCodec,
|
||||||
|
uint8_t& aProfile,
|
||||||
|
uint8_t& aLevel,
|
||||||
|
uint8_t& aBitDepth)
|
||||||
|
{
|
||||||
|
uint8_t dummyChromaSubsampling = 1;
|
||||||
|
VideoColorSpace dummyColorspace;
|
||||||
|
return ExtractVPXCodecDetails(aCodec,
|
||||||
|
aProfile,
|
||||||
|
aLevel,
|
||||||
|
aBitDepth,
|
||||||
|
dummyChromaSubsampling,
|
||||||
|
dummyColorspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExtractVPXCodecDetails(const nsAString& aCodec,
|
||||||
|
uint8_t& aProfile,
|
||||||
|
uint8_t& aLevel,
|
||||||
|
uint8_t& aBitDepth,
|
||||||
|
uint8_t& aChromaSubsampling,
|
||||||
|
VideoColorSpace& aColorSpace)
|
||||||
|
{
|
||||||
|
nsTArray<nsString> fieldsArr;
|
||||||
|
|
||||||
|
// Assign default value.
|
||||||
|
aChromaSubsampling = 1;
|
||||||
|
|
||||||
|
nsCharSeparatedTokenizer tokenizer(aCodec, '.');
|
||||||
|
while (tokenizer.hasMoreTokens()) {
|
||||||
|
const nsSubstring& token = tokenizer.nextToken();
|
||||||
|
fieldsArr.AppendElement(token);
|
||||||
|
}
|
||||||
|
auto fourCC = fieldsArr[0];
|
||||||
|
|
||||||
|
if (!fourCC.EqualsLiteral("vp09") && !fourCC.EqualsLiteral("vp08")) {
|
||||||
|
// Invalid 4CC
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t *fields[] = { &aProfile, &aLevel, &aBitDepth, &aChromaSubsampling,
|
||||||
|
&aColorSpace.mPrimaryId, &aColorSpace.mTransferId,
|
||||||
|
&aColorSpace.mMatrixId, &aColorSpace.mRangeId };
|
||||||
|
int fieldsCount = 0;
|
||||||
|
nsresult rv;
|
||||||
|
for (int fieldsItr = 1; fieldsItr < fieldsArr.Length(); ++fieldsItr, ++fieldsCount) {
|
||||||
|
if (fieldsCount > 7) {
|
||||||
|
// No more than 8 fields are expected.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*(fields[fieldsCount]) =
|
||||||
|
static_cast<uint8_t>(fieldsArr[fieldsItr].ToInteger(&rv));
|
||||||
|
// We got invalid field value, parsing error.
|
||||||
|
NS_ENSURE_SUCCESS(rv, false);
|
||||||
|
}
|
||||||
|
// Mandatory Fields
|
||||||
|
// <sample entry 4CC>.<profile>.<level>.<bitDepth>.
|
||||||
|
// Optional Fields
|
||||||
|
// <chromaSubsampling>.<colourPrimaries>.<transferCharacteristics>.
|
||||||
|
// <matrixCoefficients>.<videoFullRangeFlag>
|
||||||
|
// First three fields are mandatory(we have parsed 4CC).
|
||||||
|
if (fieldsCount < 3) {
|
||||||
|
// Invalid number of fields.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Start to validate the parsing value.
|
||||||
|
|
||||||
|
// profile should be 0,1,2 or 3.
|
||||||
|
// See https://www.webmproject.org/vp9/profiles/
|
||||||
|
// We don't support more than profile 2
|
||||||
|
if (aProfile > 2) {
|
||||||
|
// Invalid profile.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// level, See https://www.webmproject.org/vp9/mp4/#semantics_1
|
||||||
|
switch (aLevel) {
|
||||||
|
case 10:
|
||||||
|
case 11:
|
||||||
|
case 20:
|
||||||
|
case 21:
|
||||||
|
case 30:
|
||||||
|
case 31:
|
||||||
|
case 40:
|
||||||
|
case 41:
|
||||||
|
case 50:
|
||||||
|
case 51:
|
||||||
|
case 52:
|
||||||
|
case 60:
|
||||||
|
case 61:
|
||||||
|
case 62:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Invalid level.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aBitDepth != 8 && aBitDepth != 10 && aBitDepth != 12) {
|
||||||
|
// Invalid bitDepth:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsCount == 3) {
|
||||||
|
// No more options.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// chromaSubsampling should be 0,1,2,3...4~7 are reserved.
|
||||||
|
if (aChromaSubsampling > 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsCount == 4) {
|
||||||
|
// No more options.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is an integer that is defined by the "Colour primaries"
|
||||||
|
// section of ISO/IEC 23001-8:2016 Table 2.
|
||||||
|
// We treat reserved value as false case.
|
||||||
|
const auto& primaryId = aColorSpace.mPrimaryId;
|
||||||
|
if (primaryId == 0 || primaryId == 3 || primaryId > 22) {
|
||||||
|
// reserved value.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (primaryId > 12 && primaryId < 22) {
|
||||||
|
// 13~21 are reserved values.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsCount == 5) {
|
||||||
|
// No more options.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is an integer that is defined by the
|
||||||
|
// "Transfer characteristics" section of ISO/IEC 23001-8:2016 Table 3.
|
||||||
|
// We treat reserved value as false case.
|
||||||
|
const auto& transferId = aColorSpace.mTransferId;
|
||||||
|
if (transferId == 0 || transferId == 3 || transferId > 18) {
|
||||||
|
// reserved value.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsCount == 6) {
|
||||||
|
// No more options.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is an integer that is defined by the
|
||||||
|
// "Matrix coefficients" section of ISO/IEC 23001-8:2016 Table 4.
|
||||||
|
// We treat reserved value as false case.
|
||||||
|
const auto& matrixId = aColorSpace.mMatrixId;
|
||||||
|
if (matrixId == 3 || matrixId > 11) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If matrixCoefficients is 0 (RGB), then chroma subsampling MUST be 3 (4:4:4).
|
||||||
|
if (matrixId == 0 && aChromaSubsampling != 3) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fieldsCount == 7) {
|
||||||
|
// No more options.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// videoFullRangeFlag indicates the black level and range of the luma and
|
||||||
|
// chroma signals. 0 = legal range (e.g. 16-235 for 8 bit sample depth);
|
||||||
|
// 1 = full range (e.g. 0-255 for 8-bit sample depth).
|
||||||
|
const auto& rangeId = aColorSpace.mRangeId;
|
||||||
|
return rangeId <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ExtractH264CodecDetails(const nsAString& aCodec,
|
ExtractH264CodecDetails(const nsAString& aCodec,
|
||||||
int16_t& aProfile,
|
int16_t& aProfile,
|
||||||
int16_t& aLevel)
|
int16_t& aLevel)
|
||||||
{
|
{
|
||||||
// H.264 codecs parameters have a type defined as avcN.PPCCLL, where
|
// H.264 codecs parameters have a type defined as avcN.PPCCLL, where
|
||||||
// N = avc type. avc3 is avcc with SPS & PPS implicit (within stream)
|
// N = avc type. avc3 is avcc with SPS & PPS implicit (within stream)
|
||||||
// PP = profile_idc, CC = constraint_set flags, LL = level_idc.
|
// PP = profile_idc, CC = constraint_set flags, LL = level_idc.
|
||||||
// We ignore the constraint_set flags, as it's not clear from any
|
// We ignore the constraint_set flags, as it's not clear from any
|
||||||
// documentation what constraints the platform decoders support.
|
// documentation what constraints the platform decoders support.
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,34 @@ ExtractH264CodecDetails(const nsAString& aCodecs,
|
||||||
int16_t& aProfile,
|
int16_t& aProfile,
|
||||||
int16_t& aLevel);
|
int16_t& aLevel);
|
||||||
|
|
||||||
|
struct VideoColorSpace
|
||||||
|
{
|
||||||
|
// TODO: Define the value type as strong type enum
|
||||||
|
// to better know the exact meaning corresponding to ISO/IEC 23001-8:2016.
|
||||||
|
// Default value is listed https://www.webmproject.org/vp9/mp4/#optional-fields
|
||||||
|
uint8_t mPrimaryId = 1; // Table 2
|
||||||
|
uint8_t mTransferId = 1; // Table 3
|
||||||
|
uint8_t mMatrixId = 1; // Table 4
|
||||||
|
uint8_t mRangeId = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Extracts the VPX codecs parameter string.
|
||||||
|
// See https://www.webmproject.org/vp9/mp4/#codecs-parameter-string
|
||||||
|
// for more details.
|
||||||
|
// Returns false on failure.
|
||||||
|
bool
|
||||||
|
ExtractVPXCodecDetails(const nsAString& aCodec,
|
||||||
|
uint8_t& aProfile,
|
||||||
|
uint8_t& aLevel,
|
||||||
|
uint8_t& aBitDepth);
|
||||||
|
bool
|
||||||
|
ExtractVPXCodecDetails(const nsAString& aCodec,
|
||||||
|
uint8_t& aProfile,
|
||||||
|
uint8_t& aLevel,
|
||||||
|
uint8_t& aBitDepth,
|
||||||
|
uint8_t& aChromaSubsampling,
|
||||||
|
VideoColorSpace& aColorSpace);
|
||||||
|
|
||||||
// Use a cryptographic quality PRNG to generate raw random bytes
|
// Use a cryptographic quality PRNG to generate raw random bytes
|
||||||
// and convert that to a base64 string.
|
// and convert that to a base64 string.
|
||||||
nsresult
|
nsresult
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue