зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1860198 - part1 : show the result of lacking of extension for AV1 in about:support. r=desktop-theme-reviewers,fluent-reviewers,azebrowski,bolsson,jules
Gecko uses the media foundation API to perform the video decoding, so we need users to install this free AV1 [1] extension in order to provide hardware decoding ability [2]. If we detect that AV1 extension is not installed by users, then we would tell users in the Codec Support Information section to ask them install the extension in order to get the hardware decoding support. [1] https://apps.microsoft.com/detail/9MVZQVXJBQ9V?hl=en-us&gl=US [2] https://techcommunity.microsoft.com/t5/media-at-microsoft-blog/av1-hardware-accelerated-video-on-windows-10/ba-p/1765451 Differential Revision: https://phabricator.services.mozilla.com/D191504
This commit is contained in:
Родитель
900d367030
Коммит
b718108959
|
@ -84,6 +84,9 @@ MediaCodecsSupported MCSInfo::GetDecodeMediaCodecsSupported(
|
||||||
if (aSupportSet.contains(DecodeSupport::HardwareDecode)) {
|
if (aSupportSet.contains(DecodeSupport::HardwareDecode)) {
|
||||||
support += supportInfo.hwDecodeSupport;
|
support += supportInfo.hwDecodeSupport;
|
||||||
}
|
}
|
||||||
|
if (aSupportSet.contains(DecodeSupport::UnsureDueToLackOfExtension)) {
|
||||||
|
support += supportInfo.lackOfHWExtenstion;
|
||||||
|
}
|
||||||
return support;
|
return support;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +130,10 @@ void MCSInfo::GetMediaCodecsSupportedString(
|
||||||
aSupportString.Append(" HW"_ns);
|
aSupportString.Append(" HW"_ns);
|
||||||
foundSupport = true;
|
foundSupport = true;
|
||||||
}
|
}
|
||||||
|
if (aSupportedCodecs.contains(it.lackOfHWExtenstion)) {
|
||||||
|
aSupportString.Append(" LACK_OF_EXTENSION"_ns);
|
||||||
|
foundSupport = true;
|
||||||
|
}
|
||||||
if (!foundSupport) {
|
if (!foundSupport) {
|
||||||
aSupportString.Append(" NONE"_ns);
|
aSupportString.Append(" NONE"_ns);
|
||||||
}
|
}
|
||||||
|
@ -281,40 +288,41 @@ std::array<CodecDefinition, 13> MCSInfo::GetAllCodecDefinitions() {
|
||||||
static constexpr std::array<CodecDefinition, 13> codecDefinitions = {
|
static constexpr std::array<CodecDefinition, 13> codecDefinitions = {
|
||||||
{{MediaCodec::H264, "H264", "video/avc",
|
{{MediaCodec::H264, "H264", "video/avc",
|
||||||
MediaCodecsSupport::H264SoftwareDecode,
|
MediaCodecsSupport::H264SoftwareDecode,
|
||||||
MediaCodecsSupport::H264HardwareDecode},
|
MediaCodecsSupport::H264HardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::VP9, "VP9", "video/vp9",
|
{MediaCodec::VP9, "VP9", "video/vp9",
|
||||||
MediaCodecsSupport::VP9SoftwareDecode,
|
MediaCodecsSupport::VP9SoftwareDecode,
|
||||||
MediaCodecsSupport::VP9HardwareDecode},
|
MediaCodecsSupport::VP9HardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::VP8, "VP8", "video/vp8",
|
{MediaCodec::VP8, "VP8", "video/vp8",
|
||||||
MediaCodecsSupport::VP8SoftwareDecode,
|
MediaCodecsSupport::VP8SoftwareDecode,
|
||||||
MediaCodecsSupport::VP8HardwareDecode},
|
MediaCodecsSupport::VP8HardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::AV1, "AV1", "video/av1",
|
{MediaCodec::AV1, "AV1", "video/av1",
|
||||||
MediaCodecsSupport::AV1SoftwareDecode,
|
MediaCodecsSupport::AV1SoftwareDecode,
|
||||||
MediaCodecsSupport::AV1HardwareDecode},
|
MediaCodecsSupport::AV1HardwareDecode,
|
||||||
|
MediaCodecsSupport::AV1LackOfExtension},
|
||||||
{MediaCodec::HEVC, "HEVC", "video/hevc",
|
{MediaCodec::HEVC, "HEVC", "video/hevc",
|
||||||
MediaCodecsSupport::HEVCSoftwareDecode,
|
MediaCodecsSupport::HEVCSoftwareDecode,
|
||||||
MediaCodecsSupport::HEVCHardwareDecode},
|
MediaCodecsSupport::HEVCHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::Theora, "Theora", "video/theora",
|
{MediaCodec::Theora, "Theora", "video/theora",
|
||||||
MediaCodecsSupport::TheoraSoftwareDecode,
|
MediaCodecsSupport::TheoraSoftwareDecode,
|
||||||
MediaCodecsSupport::TheoraHardwareDecode},
|
MediaCodecsSupport::TheoraHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::AAC, "AAC", "audio/mp4a-latm",
|
{MediaCodec::AAC, "AAC", "audio/mp4a-latm",
|
||||||
MediaCodecsSupport::AACSoftwareDecode,
|
MediaCodecsSupport::AACSoftwareDecode,
|
||||||
MediaCodecsSupport::AACHardwareDecode},
|
MediaCodecsSupport::AACHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::MP3, "MP3", "audio/mpeg",
|
{MediaCodec::MP3, "MP3", "audio/mpeg",
|
||||||
MediaCodecsSupport::MP3SoftwareDecode,
|
MediaCodecsSupport::MP3SoftwareDecode,
|
||||||
MediaCodecsSupport::MP3HardwareDecode},
|
MediaCodecsSupport::MP3HardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::Opus, "Opus", "audio/opus",
|
{MediaCodec::Opus, "Opus", "audio/opus",
|
||||||
MediaCodecsSupport::OpusSoftwareDecode,
|
MediaCodecsSupport::OpusSoftwareDecode,
|
||||||
MediaCodecsSupport::OpusHardwareDecode},
|
MediaCodecsSupport::OpusHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::Vorbis, "Vorbis", "audio/vorbis",
|
{MediaCodec::Vorbis, "Vorbis", "audio/vorbis",
|
||||||
MediaCodecsSupport::VorbisSoftwareDecode,
|
MediaCodecsSupport::VorbisSoftwareDecode,
|
||||||
MediaCodecsSupport::VorbisHardwareDecode},
|
MediaCodecsSupport::VorbisHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::FLAC, "FLAC", "audio/flac",
|
{MediaCodec::FLAC, "FLAC", "audio/flac",
|
||||||
MediaCodecsSupport::FLACSoftwareDecode,
|
MediaCodecsSupport::FLACSoftwareDecode,
|
||||||
MediaCodecsSupport::FLACHardwareDecode},
|
MediaCodecsSupport::FLACHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::Wave, "Wave", "audio/x-wav",
|
{MediaCodec::Wave, "Wave", "audio/x-wav",
|
||||||
MediaCodecsSupport::WaveSoftwareDecode,
|
MediaCodecsSupport::WaveSoftwareDecode,
|
||||||
MediaCodecsSupport::WaveHardwareDecode},
|
MediaCodecsSupport::WaveHardwareDecode, MediaCodecsSupport::SENTINEL},
|
||||||
{MediaCodec::SENTINEL, "Undefined codec name",
|
{MediaCodec::SENTINEL, "Undefined codec name",
|
||||||
"Undefined MIME type string", MediaCodecsSupport::SENTINEL,
|
"Undefined MIME type string", MediaCodecsSupport::SENTINEL,
|
||||||
MediaCodecsSupport::SENTINEL}}};
|
MediaCodecsSupport::SENTINEL}}};
|
||||||
|
|
|
@ -46,6 +46,10 @@ using MediaCodecSet = EnumSet<MediaCodec, uint64_t>;
|
||||||
#define SW_DECODE(codec) codec##SoftwareDecode
|
#define SW_DECODE(codec) codec##SoftwareDecode
|
||||||
#define HW_DECODE(codec) codec##HardwareDecode
|
#define HW_DECODE(codec) codec##HardwareDecode
|
||||||
|
|
||||||
|
// For codec which we can do hardware decoding once user installs the free
|
||||||
|
// platform extension, eg. AV1 on Windows
|
||||||
|
#define LACK_HW_EXTENSION(codec) codec##LackOfExtension
|
||||||
|
|
||||||
// Generate the MediaCodecsSupport enum, containing
|
// Generate the MediaCodecsSupport enum, containing
|
||||||
// codec-specific SW/HW decode/encode information.
|
// codec-specific SW/HW decode/encode information.
|
||||||
// Entries for HW audio decode/encode should never be set as we
|
// Entries for HW audio decode/encode should never be set as we
|
||||||
|
@ -53,7 +57,7 @@ using MediaCodecSet = EnumSet<MediaCodec, uint64_t>;
|
||||||
// for debug purposes / check for erroneous PDM return values.
|
// for debug purposes / check for erroneous PDM return values.
|
||||||
// Example: MediaCodecsSupport::AACSoftwareDecode
|
// Example: MediaCodecsSupport::AACSoftwareDecode
|
||||||
enum class MediaCodecsSupport : int {
|
enum class MediaCodecsSupport : int {
|
||||||
#define X(name) SW_DECODE(name), HW_DECODE(name),
|
#define X(name) SW_DECODE(name), HW_DECODE(name), LACK_HW_EXTENSION(name),
|
||||||
CODEC_LIST
|
CODEC_LIST
|
||||||
#undef X
|
#undef X
|
||||||
SENTINEL
|
SENTINEL
|
||||||
|
@ -69,6 +73,7 @@ using MediaCodecsSupported = EnumSet<MediaCodecsSupport, uint64_t>;
|
||||||
enum class DecodeSupport : int {
|
enum class DecodeSupport : int {
|
||||||
SoftwareDecode,
|
SoftwareDecode,
|
||||||
HardwareDecode,
|
HardwareDecode,
|
||||||
|
UnsureDueToLackOfExtension,
|
||||||
};
|
};
|
||||||
using DecodeSupportSet = EnumSet<DecodeSupport, uint64_t>;
|
using DecodeSupportSet = EnumSet<DecodeSupport, uint64_t>;
|
||||||
|
|
||||||
|
@ -80,6 +85,7 @@ struct CodecDefinition {
|
||||||
const char* mimeTypeString = "Undefined MIME type string";
|
const char* mimeTypeString = "Undefined MIME type string";
|
||||||
MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL;
|
MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL;
|
||||||
MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL;
|
MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL;
|
||||||
|
MediaCodecsSupport lackOfHWExtenstion = MediaCodecsSupport::SENTINEL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Singleton class used to collect, manage, and report codec support data.
|
// Singleton class used to collect, manage, and report codec support data.
|
||||||
|
|
|
@ -87,6 +87,7 @@ static bool IsRemoteAcceleratedCompositor(
|
||||||
|
|
||||||
static Atomic<bool> sSupportedTypesInitialized(false);
|
static Atomic<bool> sSupportedTypesInitialized(false);
|
||||||
static EnumSet<WMFStreamType> sSupportedTypes;
|
static EnumSet<WMFStreamType> sSupportedTypes;
|
||||||
|
static EnumSet<WMFStreamType> sLackOfExtensionTypes;
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
void WMFDecoderModule::Init(Config aConfig) {
|
void WMFDecoderModule::Init(Config aConfig) {
|
||||||
|
@ -135,6 +136,7 @@ void WMFDecoderModule::Init(Config aConfig) {
|
||||||
mozilla::mscom::EnsureMTA([&]() {
|
mozilla::mscom::EnsureMTA([&]() {
|
||||||
// Store the supported MFT decoders.
|
// Store the supported MFT decoders.
|
||||||
sSupportedTypes.clear();
|
sSupportedTypes.clear();
|
||||||
|
sLackOfExtensionTypes.clear();
|
||||||
// i = 1 to skip Unknown.
|
// i = 1 to skip Unknown.
|
||||||
for (uint32_t i = 1; i < static_cast<uint32_t>(WMFStreamType::SENTINEL);
|
for (uint32_t i = 1; i < static_cast<uint32_t>(WMFStreamType::SENTINEL);
|
||||||
i++) {
|
i++) {
|
||||||
|
@ -151,6 +153,12 @@ void WMFDecoderModule::Init(Config aConfig) {
|
||||||
WmfDecoderModuleMarkerAndLog("WMFInit Decoder Failed",
|
WmfDecoderModuleMarkerAndLog("WMFInit Decoder Failed",
|
||||||
"%s failed with code 0x%lx",
|
"%s failed with code 0x%lx",
|
||||||
StreamTypeToString(type), hr);
|
StreamTypeToString(type), hr);
|
||||||
|
if (hr == WINCODEC_ERR_COMPONENTNOTFOUND &&
|
||||||
|
type == WMFStreamType::AV1) {
|
||||||
|
WmfDecoderModuleMarkerAndLog("No AV1 extension",
|
||||||
|
"Lacking of AV1 extension");
|
||||||
|
sLackOfExtensionTypes += type;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -375,8 +383,9 @@ media::DecodeSupportSet WMFDecoderModule::Supports(
|
||||||
return media::DecodeSupport::SoftwareDecode;
|
return media::DecodeSupport::SoftwareDecode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return sLackOfExtensionTypes.contains(type)
|
||||||
return media::DecodeSupportSet{};
|
? media::DecodeSupport::UnsureDueToLackOfExtension
|
||||||
|
: media::DecodeSupportSet{};
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult WMFDecoderModule::Startup() {
|
nsresult WMFDecoderModule::Startup() {
|
||||||
|
|
|
@ -1141,12 +1141,14 @@ var snapshotFormatters = {
|
||||||
codecNameHeaderText,
|
codecNameHeaderText,
|
||||||
codecSWDecodeText,
|
codecSWDecodeText,
|
||||||
codecHWDecodeText,
|
codecHWDecodeText,
|
||||||
|
lackOfExtensionText,
|
||||||
] = await document.l10n.formatValues([
|
] = await document.l10n.formatValues([
|
||||||
"media-codec-support-supported",
|
"media-codec-support-supported",
|
||||||
"media-codec-support-unsupported",
|
"media-codec-support-unsupported",
|
||||||
"media-codec-support-codec-name",
|
"media-codec-support-codec-name",
|
||||||
"media-codec-support-sw-decoding",
|
"media-codec-support-sw-decoding",
|
||||||
"media-codec-support-hw-decoding",
|
"media-codec-support-hw-decoding",
|
||||||
|
"media-codec-support-lack-of-extension",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function formatCodecRowHeader(a, b, c) {
|
function formatCodecRowHeader(a, b, c) {
|
||||||
|
@ -1175,6 +1177,18 @@ var snapshotFormatters = {
|
||||||
return $.new("tr", [$.new("td", codec), swCell, hwCell]);
|
return $.new("tr", [$.new("td", codec), swCell, hwCell]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatCodecRowForLackOfExtension(codec, sw) {
|
||||||
|
let swCell = $.new("td", sw ? supportText : unsupportedText);
|
||||||
|
let hwCell = $.new("td", lackOfExtensionText);
|
||||||
|
if (sw) {
|
||||||
|
swCell.classList.add("supported");
|
||||||
|
} else {
|
||||||
|
swCell.classList.add("unsupported");
|
||||||
|
}
|
||||||
|
hwCell.classList.add("lack-of-extension");
|
||||||
|
return $.new("tr", [$.new("td", codec), swCell, hwCell]);
|
||||||
|
}
|
||||||
|
|
||||||
// Parse codec support string and create dictionary containing
|
// Parse codec support string and create dictionary containing
|
||||||
// SW/HW support information for each codec found
|
// SW/HW support information for each codec found
|
||||||
let codecs = {};
|
let codecs = {};
|
||||||
|
@ -1188,6 +1202,7 @@ var snapshotFormatters = {
|
||||||
name: codec_name,
|
name: codec_name,
|
||||||
sw: false,
|
sw: false,
|
||||||
hw: false,
|
hw: false,
|
||||||
|
lackOfExtension: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,6 +1212,9 @@ var snapshotFormatters = {
|
||||||
if (codec_support.includes("HW")) {
|
if (codec_support.includes("HW")) {
|
||||||
codecs[codec_name].hw = true;
|
codecs[codec_name].hw = true;
|
||||||
}
|
}
|
||||||
|
if (codec_support.includes("LACK_OF_EXTENSION")) {
|
||||||
|
codecs[codec_name].lackOfExtension = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create row in support table for each codec
|
// Create row in support table for each codec
|
||||||
|
@ -1205,9 +1223,15 @@ var snapshotFormatters = {
|
||||||
if (!codecs.hasOwnProperty(c)) {
|
if (!codecs.hasOwnProperty(c)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
codecSupportRows.push(
|
if (codecs[c].lackOfExtension) {
|
||||||
formatCodecRow(codecs[c].name, codecs[c].sw, codecs[c].hw)
|
codecSupportRows.push(
|
||||||
);
|
formatCodecRowForLackOfExtension(codecs[c].name, codecs[c].sw)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
codecSupportRows.push(
|
||||||
|
formatCodecRow(codecs[c].name, codecs[c].sw, codecs[c].hw)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let codecSupportTable = $.new("table", [
|
let codecSupportTable = $.new("table", [
|
||||||
|
|
|
@ -191,6 +191,7 @@ media-codec-support-codec-name = Codec Name
|
||||||
media-codec-support-supported = Supported
|
media-codec-support-supported = Supported
|
||||||
media-codec-support-unsupported = Unsupported
|
media-codec-support-unsupported = Unsupported
|
||||||
media-codec-support-error = Codec support information unavailable. Try again after playing back a media file.
|
media-codec-support-error = Codec support information unavailable. Try again after playing back a media file.
|
||||||
|
media-codec-support-lack-of-extension = Install extension
|
||||||
|
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,10 @@ td.integer {
|
||||||
color: var(--codec-text-supported);
|
color: var(--codec-text-supported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#codec-table tr > td.lack-of-extension {
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
}
|
||||||
|
|
||||||
#codec-table tr:nth-child(even) > td.unsupported {
|
#codec-table tr:nth-child(even) > td.unsupported {
|
||||||
background-color: var(--codec-bg-unsupported-even);
|
background-color: var(--codec-bg-unsupported-even);
|
||||||
}
|
}
|
||||||
|
@ -103,6 +107,14 @@ td.integer {
|
||||||
background-color: var(--codec-bg-supported-odd);
|
background-color: var(--codec-bg-supported-odd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#codec-table tr:nth-child(even) > td.lack-of-extension {
|
||||||
|
background-color: var(--in-content-box-background-even);
|
||||||
|
}
|
||||||
|
|
||||||
|
#codec-table tr:nth-child(odd) > td.lack-of-extension {
|
||||||
|
background-color: var(--in-content-box-background-odd);
|
||||||
|
}
|
||||||
|
|
||||||
#update-dir-row > td:dir(rtl),
|
#update-dir-row > td:dir(rtl),
|
||||||
#profile-row > td:dir(rtl) {
|
#profile-row > td:dir(rtl) {
|
||||||
/* Overrides info-pages.css to display the buttons in the right order compared to the text */
|
/* Overrides info-pages.css to display the buttons in the right order compared to the text */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче