diff options
Diffstat (limited to 'dom/media/platforms/MediaCodecsSupport.h')
-rw-r--r-- | dom/media/platforms/MediaCodecsSupport.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/dom/media/platforms/MediaCodecsSupport.h b/dom/media/platforms/MediaCodecsSupport.h new file mode 100644 index 0000000000..ae2fdd63a8 --- /dev/null +++ b/dom/media/platforms/MediaCodecsSupport.h @@ -0,0 +1,194 @@ +/* -*- 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 <array> + +#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<MediaCodecsSupport, uint64_t>; + +// Codec-agnostic SW/HW decode support information. +enum class DecodeSupport : int { + Unsupported = 0, + SoftwareDecode, + HardwareDecode, +}; +using DecodeSupportSet = EnumSet<DecodeSupport, uint64_t>; + +// 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<CodecDefinition, 12> 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<nsTHashMap<MediaCodecsSupport, CodecDefinition>> mHashTableMCS; + UniquePtr<nsTHashMap<const char*, CodecDefinition>> mHashTableString; + UniquePtr<nsTHashMap<MediaCodec, CodecDefinition>> mHashTableCodec; + MediaCodecsSupported mSupport; +}; +} // namespace mozilla::media + +namespace mozilla { +// Used for IPDL serialization. +// The 'value' has to be the biggest enum from MediaCodecsSupport. +template <typename T> +struct MaxEnumValue; +template <> +struct MaxEnumValue<media::MediaCodecsSupport> { + static constexpr unsigned int value = + static_cast<unsigned int>(media::MediaCodecsSupport::SENTINEL); +}; +} // namespace mozilla + +#endif /* MediaCodecsSupport_h_ */ |