/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim:set ts=2 sw=2 sts=2 et cindent: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_ #define DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_ #include #include "mozilla/Atomics.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/EnumSet.h" #include "mozilla/StaticMutex.h" #include "nsString.h" #include "nsTHashMap.h" #include "nsThreadUtils.h" namespace mozilla::media { // List of codecs we support, used in the below macros // to generate MediaCodec and MediaCodecSupports enums. #define CODEC_LIST \ X(H264) \ X(VP8) \ X(VP9) \ X(AV1) \ X(Theora) \ X(AAC) \ X(FLAC) \ X(MP3) \ X(Opus) \ X(Vorbis) \ X(Wave) // Generate MediaCodec enum with the names of each codec we support. // Example: MediaCodec::H264 enum class MediaCodec : int { #define X(name) name, CODEC_LIST #undef X SENTINEL }; // Helper macros used to create codec-specific SW/HW decode enums below. #define SW_DECODE(codec) codec##SoftwareDecode #define HW_DECODE(codec) codec##HardwareDecode // Generate the MediaCodecsSupport enum, containing // codec-specific SW/HW decode/encode information. // Entries for HW audio decode/encode should never be set as we // don't support HW audio decode/encode, but they are included // 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), CODEC_LIST #undef X SENTINEL }; #undef SW_DECODE #undef HW_DECODE #undef CODEC_LIST // end of macros! // Enumset containing per-codec SW/HW support using MediaCodecsSupported = EnumSet; // Codec-agnostic SW/HW decode support information. enum class DecodeSupport : int { Unsupported = 0, SoftwareDecode, HardwareDecode, }; using DecodeSupportSet = EnumSet; // CodecDefinition stores information needed to convert / index // codec support information between types. See: GetAllCodecDefinitions() struct CodecDefinition { MediaCodec codec = MediaCodec::SENTINEL; const char* commonName = "Undefined codec name"; const char* mimeTypeString = "Undefined MIME type string"; MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL; MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL; }; // Singleton class used to collect, manage, and report codec support data. class MCSInfo final { public: // Add codec support information to our aggregated list of supported codecs. // Incoming support info is merged with the current support info. // This is because different PDMs may report different codec support // information, so merging their results allows us to maintain a // cumulative support list without overwriting any existing data. static void AddSupport(const MediaCodecsSupported& aSupport); // Return a cumulative list of codec support information. // Each call to AddSupport adds to or updates this list. // This support information can be used to create user-readable strings // to report codec support information in about:support. static MediaCodecsSupported GetSupport(); // Reset codec support information saved from calls to AddSupport(). static void ResetSupport(); // Query a MediaCodecsSupported EnumSet for codec-specific SW/HW support enums // and return general support information as stored in a DecodeSupportSet. // // Example input: // // aCodec: MediaCodec::H264 // aDecode: MediaCodecsSupport { // MediaCodecsSupport::AACSoftwareDecode // MediaCodecsSupport::H264HardwareDecode, // MediaCodecsSupport::H264SoftwareDecode, // MediaCodecsSupport::VP8SoftwareDecode, // } // // Example output: // // DecodeSupportSet { // DecodeSupport::SoftwareDecode, // DecodeSupport::HardwareDecode // } // static DecodeSupportSet GetDecodeSupportSet( const MediaCodec& aCodec, const MediaCodecsSupported& aSupported); // Return codec-specific SW/HW support enums for a given codec. // The DecodeSupportSet argument is used which codec-specific SW/HW // support values are returned, if any. // // Example input: // aCodec: MediaCodec::VP8 // aSupportSet: DecodeSupportSet {DecodeSupport::SoftwareDecode} // // Example output: // MediaCodecsSupported {MediaCodecsSupport::VP8SoftwareDecode} // static MediaCodecsSupported GetDecodeMediaCodecsSupported( const MediaCodec& aCodec, const DecodeSupportSet& aSupportSet); // Generate a plaintext description for the SW/HW support information // contained in a MediaCodecsSupported EnumSet. // // Example input: // MediaCodecsSupported { // MediaCodecsSupport::H264SoftwareDecode, // MediaCodecsSupport::H264HardwareDecode, // MediaCodecsSupport::VP8SoftwareDecode // } // // Example output (returned via argument aCodecString) // // "SW H264 decode\n // HW H264 decode\n // SW VP8 decode"_ns // static void GetMediaCodecsSupportedString( nsCString& aSupportString, const MediaCodecsSupported& aSupportedCodecs); // Returns array of hardcoded codec definitions used to generate hashtables // that convert between types static std::array GetAllCodecDefinitions(); MCSInfo(MCSInfo const&) = delete; void operator=(MCSInfo const&) = delete; ~MCSInfo() = default; private: MCSInfo(); static MCSInfo* GetInstance(); // Returns a codec definition by MIME type name ("media/vp9") // or "common" name ("VP9") static CodecDefinition GetCodecDefinition(const MediaCodec& aCodec); UniquePtr> mHashTableMCS; UniquePtr> mHashTableString; UniquePtr> mHashTableCodec; MediaCodecsSupported mSupport; }; } // namespace mozilla::media namespace mozilla { // Used for IPDL serialization. // The 'value' has to be the biggest enum from MediaCodecsSupport. template struct MaxEnumValue; template <> struct MaxEnumValue { static constexpr unsigned int value = static_cast(media::MediaCodecsSupport::SENTINEL); }; } // namespace mozilla #endif /* MediaCodecsSupport_h_ */