From b7181089595e3c10e3728e09dfcfc81d25f4827d Mon Sep 17 00:00:00 2001 From: alwu Date: Fri, 27 Oct 2023 18:49:41 +0000 Subject: [PATCH] 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 --- dom/media/platforms/MediaCodecsSupport.cpp | 32 ++++++++++++------- dom/media/platforms/MediaCodecsSupport.h | 8 ++++- dom/media/platforms/wmf/WMFDecoderModule.cpp | 13 ++++++-- toolkit/content/aboutSupport.js | 30 +++++++++++++++-- .../en-US/toolkit/about/aboutSupport.ftl | 1 + toolkit/themes/shared/aboutSupport.css | 12 +++++++ 6 files changed, 78 insertions(+), 18 deletions(-) diff --git a/dom/media/platforms/MediaCodecsSupport.cpp b/dom/media/platforms/MediaCodecsSupport.cpp index 0cd8ee638816..8672df3e3d89 100644 --- a/dom/media/platforms/MediaCodecsSupport.cpp +++ b/dom/media/platforms/MediaCodecsSupport.cpp @@ -84,6 +84,9 @@ MediaCodecsSupported MCSInfo::GetDecodeMediaCodecsSupported( if (aSupportSet.contains(DecodeSupport::HardwareDecode)) { support += supportInfo.hwDecodeSupport; } + if (aSupportSet.contains(DecodeSupport::UnsureDueToLackOfExtension)) { + support += supportInfo.lackOfHWExtenstion; + } return support; } @@ -127,6 +130,10 @@ void MCSInfo::GetMediaCodecsSupportedString( aSupportString.Append(" HW"_ns); foundSupport = true; } + if (aSupportedCodecs.contains(it.lackOfHWExtenstion)) { + aSupportString.Append(" LACK_OF_EXTENSION"_ns); + foundSupport = true; + } if (!foundSupport) { aSupportString.Append(" NONE"_ns); } @@ -281,40 +288,41 @@ std::array MCSInfo::GetAllCodecDefinitions() { static constexpr std::array codecDefinitions = { {{MediaCodec::H264, "H264", "video/avc", MediaCodecsSupport::H264SoftwareDecode, - MediaCodecsSupport::H264HardwareDecode}, + MediaCodecsSupport::H264HardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::VP9, "VP9", "video/vp9", MediaCodecsSupport::VP9SoftwareDecode, - MediaCodecsSupport::VP9HardwareDecode}, + MediaCodecsSupport::VP9HardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::VP8, "VP8", "video/vp8", MediaCodecsSupport::VP8SoftwareDecode, - MediaCodecsSupport::VP8HardwareDecode}, + MediaCodecsSupport::VP8HardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::AV1, "AV1", "video/av1", MediaCodecsSupport::AV1SoftwareDecode, - MediaCodecsSupport::AV1HardwareDecode}, + MediaCodecsSupport::AV1HardwareDecode, + MediaCodecsSupport::AV1LackOfExtension}, {MediaCodec::HEVC, "HEVC", "video/hevc", MediaCodecsSupport::HEVCSoftwareDecode, - MediaCodecsSupport::HEVCHardwareDecode}, + MediaCodecsSupport::HEVCHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::Theora, "Theora", "video/theora", MediaCodecsSupport::TheoraSoftwareDecode, - MediaCodecsSupport::TheoraHardwareDecode}, + MediaCodecsSupport::TheoraHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::AAC, "AAC", "audio/mp4a-latm", MediaCodecsSupport::AACSoftwareDecode, - MediaCodecsSupport::AACHardwareDecode}, + MediaCodecsSupport::AACHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::MP3, "MP3", "audio/mpeg", MediaCodecsSupport::MP3SoftwareDecode, - MediaCodecsSupport::MP3HardwareDecode}, + MediaCodecsSupport::MP3HardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::Opus, "Opus", "audio/opus", MediaCodecsSupport::OpusSoftwareDecode, - MediaCodecsSupport::OpusHardwareDecode}, + MediaCodecsSupport::OpusHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::Vorbis, "Vorbis", "audio/vorbis", MediaCodecsSupport::VorbisSoftwareDecode, - MediaCodecsSupport::VorbisHardwareDecode}, + MediaCodecsSupport::VorbisHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::FLAC, "FLAC", "audio/flac", MediaCodecsSupport::FLACSoftwareDecode, - MediaCodecsSupport::FLACHardwareDecode}, + MediaCodecsSupport::FLACHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::Wave, "Wave", "audio/x-wav", MediaCodecsSupport::WaveSoftwareDecode, - MediaCodecsSupport::WaveHardwareDecode}, + MediaCodecsSupport::WaveHardwareDecode, MediaCodecsSupport::SENTINEL}, {MediaCodec::SENTINEL, "Undefined codec name", "Undefined MIME type string", MediaCodecsSupport::SENTINEL, MediaCodecsSupport::SENTINEL}}}; diff --git a/dom/media/platforms/MediaCodecsSupport.h b/dom/media/platforms/MediaCodecsSupport.h index 9bd46e24f238..ead44262590f 100644 --- a/dom/media/platforms/MediaCodecsSupport.h +++ b/dom/media/platforms/MediaCodecsSupport.h @@ -46,6 +46,10 @@ using MediaCodecSet = EnumSet; #define SW_DECODE(codec) codec##SoftwareDecode #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 // codec-specific SW/HW decode/encode information. // Entries for HW audio decode/encode should never be set as we @@ -53,7 +57,7 @@ using MediaCodecSet = EnumSet; // for debug purposes / check for erroneous PDM return values. // Example: MediaCodecsSupport::AACSoftwareDecode 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 #undef X SENTINEL @@ -69,6 +73,7 @@ using MediaCodecsSupported = EnumSet; enum class DecodeSupport : int { SoftwareDecode, HardwareDecode, + UnsureDueToLackOfExtension, }; using DecodeSupportSet = EnumSet; @@ -80,6 +85,7 @@ struct CodecDefinition { const char* mimeTypeString = "Undefined MIME type string"; MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL; MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL; + MediaCodecsSupport lackOfHWExtenstion = MediaCodecsSupport::SENTINEL; }; // Singleton class used to collect, manage, and report codec support data. diff --git a/dom/media/platforms/wmf/WMFDecoderModule.cpp b/dom/media/platforms/wmf/WMFDecoderModule.cpp index 88714ec9014b..080613024c59 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.cpp +++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp @@ -87,6 +87,7 @@ static bool IsRemoteAcceleratedCompositor( static Atomic sSupportedTypesInitialized(false); static EnumSet sSupportedTypes; +static EnumSet sLackOfExtensionTypes; /* static */ void WMFDecoderModule::Init(Config aConfig) { @@ -135,6 +136,7 @@ void WMFDecoderModule::Init(Config aConfig) { mozilla::mscom::EnsureMTA([&]() { // Store the supported MFT decoders. sSupportedTypes.clear(); + sLackOfExtensionTypes.clear(); // i = 1 to skip Unknown. for (uint32_t i = 1; i < static_cast(WMFStreamType::SENTINEL); i++) { @@ -151,6 +153,12 @@ void WMFDecoderModule::Init(Config aConfig) { WmfDecoderModuleMarkerAndLog("WMFInit Decoder Failed", "%s failed with code 0x%lx", 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::DecodeSupportSet{}; + return sLackOfExtensionTypes.contains(type) + ? media::DecodeSupport::UnsureDueToLackOfExtension + : media::DecodeSupportSet{}; } nsresult WMFDecoderModule::Startup() { diff --git a/toolkit/content/aboutSupport.js b/toolkit/content/aboutSupport.js index 2f909b2a6154..e57a6e139965 100644 --- a/toolkit/content/aboutSupport.js +++ b/toolkit/content/aboutSupport.js @@ -1141,12 +1141,14 @@ var snapshotFormatters = { codecNameHeaderText, codecSWDecodeText, codecHWDecodeText, + lackOfExtensionText, ] = await document.l10n.formatValues([ "media-codec-support-supported", "media-codec-support-unsupported", "media-codec-support-codec-name", "media-codec-support-sw-decoding", "media-codec-support-hw-decoding", + "media-codec-support-lack-of-extension", ]); function formatCodecRowHeader(a, b, c) { @@ -1175,6 +1177,18 @@ var snapshotFormatters = { 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 // SW/HW support information for each codec found let codecs = {}; @@ -1188,6 +1202,7 @@ var snapshotFormatters = { name: codec_name, sw: false, hw: false, + lackOfExtension: false, }; } @@ -1197,6 +1212,9 @@ var snapshotFormatters = { if (codec_support.includes("HW")) { 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 @@ -1205,9 +1223,15 @@ var snapshotFormatters = { if (!codecs.hasOwnProperty(c)) { continue; } - codecSupportRows.push( - formatCodecRow(codecs[c].name, codecs[c].sw, codecs[c].hw) - ); + if (codecs[c].lackOfExtension) { + 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", [ diff --git a/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl b/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl index eeacc7c65b4c..275937e351b1 100644 --- a/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl +++ b/toolkit/locales/en-US/toolkit/about/aboutSupport.ftl @@ -191,6 +191,7 @@ media-codec-support-codec-name = Codec Name media-codec-support-supported = Supported media-codec-support-unsupported = Unsupported media-codec-support-error = Codec support information unavailable. Try again after playing back a media file. +media-codec-support-lack-of-extension = Install extension ## diff --git a/toolkit/themes/shared/aboutSupport.css b/toolkit/themes/shared/aboutSupport.css index 53e766cd94c2..b2fb5ed9b6ae 100644 --- a/toolkit/themes/shared/aboutSupport.css +++ b/toolkit/themes/shared/aboutSupport.css @@ -87,6 +87,10 @@ td.integer { 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 { background-color: var(--codec-bg-unsupported-even); } @@ -103,6 +107,14 @@ td.integer { 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), #profile-row > td:dir(rtl) { /* Overrides info-pages.css to display the buttons in the right order compared to the text */