mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 08:18:41 +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();
|
||||
}
|
||||
|
||||
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
|
||||
ExtractH264CodecDetails(const nsAString& aCodec,
|
||||
int16_t& aProfile,
|
||||
int16_t& aLevel)
|
||||
{
|
||||
// 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.
|
||||
// We ignore the constraint_set flags, as it's not clear from any
|
||||
// documentation what constraints the platform decoders support.
|
||||
|
|
|
|||
|
|
@ -258,6 +258,34 @@ ExtractH264CodecDetails(const nsAString& aCodecs,
|
|||
int16_t& aProfile,
|
||||
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
|
||||
// and convert that to a base64 string.
|
||||
nsresult
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue