tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaCodecsSupport.h (9356B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 #ifndef DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_
      7 #define DOM_MEDIA_PLATFORMS_MEDIACODECSSUPPORT_H_
      8 #include <array>
      9 
     10 #include "mozilla/ClearOnShutdown.h"
     11 #include "mozilla/EnumSet.h"
     12 #include "mozilla/StaticMutex.h"
     13 #include "nsString.h"
     14 #include "nsTHashMap.h"
     15 #include "nsThreadUtils.h"
     16 
     17 namespace mozilla::media {
     18 // List of codecs we support, used in the below macros
     19 // to generate MediaCodec and MediaCodecSupports enums.
     20 #define CODEC_LIST \
     21  X(H264)          \
     22  X(VP8)           \
     23  X(VP9)           \
     24  X(AV1)           \
     25  X(HEVC)          \
     26  X(AAC)           \
     27  X(FLAC)          \
     28  X(MP3)           \
     29  X(Opus)          \
     30  X(Vorbis)        \
     31  X(Wave)
     32 
     33 // Generate MediaCodec enum with the names of each codec we support.
     34 // Example: MediaCodec::H264
     35 enum class MediaCodec : int {
     36 #define X(name) name,
     37  CODEC_LIST
     38 #undef X
     39      SENTINEL
     40 };
     41 using MediaCodecSet = EnumSet<MediaCodec, uint64_t>;
     42 
     43 // Helper macros used to create codec-specific SW/HW de/encode enums below.
     44 #define SW_DECODE(codec) codec##SoftwareDecode
     45 #define HW_DECODE(codec) codec##HardwareDecode
     46 #define SW_ENCODE(codec) codec##SoftwareEncode
     47 #define HW_ENCODE(codec) codec##HardwareEncode
     48 
     49 // For codec which we can do hardware de/encoding once user installs the free
     50 // platform extension, eg. AV1 on Windows
     51 #define LACK_HW_EXTENSION(codec) codec##LackOfExtension
     52 
     53 // Generate the MediaCodecsSupport enum, containing
     54 // codec-specific SW/HW decode/encode information.
     55 // Entries for HW audio decode/encode should never be set as we
     56 // don't support HW audio decode/encode, but they are included
     57 // for debug purposes / check for erroneous PDM return values.
     58 // Example: MediaCodecsSupport::AACSoftwareDecode
     59 enum class MediaCodecsSupport : int {
     60 #define X(name)                                                       \
     61  SW_DECODE(name), HW_DECODE(name), SW_ENCODE(name), HW_ENCODE(name), \
     62      LACK_HW_EXTENSION(name),
     63  CODEC_LIST
     64 #undef X
     65      SENTINEL
     66 };
     67 #undef SW_DECODE
     68 #undef HW_DECODE
     69 #undef SW_ENCODE
     70 #undef HW_ENCODE
     71 #undef CODEC_LIST  // end of macros!
     72 
     73 // Enumset containing per-codec SW/HW support
     74 using MediaCodecsSupported = EnumSet<MediaCodecsSupport, uint64_t>;
     75 
     76 // Codec-agnostic SW/HW decode support information.
     77 enum class DecodeSupport : int {
     78  SoftwareDecode,
     79  HardwareDecode,
     80  UnsureDueToLackOfExtension,
     81 };
     82 using DecodeSupportSet = EnumSet<DecodeSupport, uint64_t>;
     83 
     84 // Codec-agnostic SW/HW decode support information.
     85 enum class EncodeSupport : int {
     86  SoftwareEncode,
     87  HardwareEncode,
     88  UnsureDueToLackOfExtension,
     89 };
     90 using EncodeSupportSet = EnumSet<EncodeSupport, uint64_t>;
     91 
     92 // CodecDefinition stores information needed to convert / index
     93 // codec support information between types. See: GetAllCodecDefinitions()
     94 struct CodecDefinition {
     95  MediaCodec codec = MediaCodec::SENTINEL;
     96  const char* commonName = "Undefined codec name";
     97  const char* mimeTypeString = "Undefined MIME type string";
     98  MediaCodecsSupport swDecodeSupport = MediaCodecsSupport::SENTINEL;
     99  MediaCodecsSupport hwDecodeSupport = MediaCodecsSupport::SENTINEL;
    100  MediaCodecsSupport swEncodeSupport = MediaCodecsSupport::SENTINEL;
    101  MediaCodecsSupport hwEncodeSupport = MediaCodecsSupport::SENTINEL;
    102  MediaCodecsSupport lackOfHWExtenstion = MediaCodecsSupport::SENTINEL;
    103 };
    104 
    105 // Singleton class used to collect, manage, and report codec support data.
    106 class MCSInfo final {
    107 public:
    108  // Gets the codec support from current PDMFactory and PEMFactory
    109  // configuration.
    110  static MediaCodecsSupported GetSupportFromFactory(bool aForceRefresh = false);
    111 
    112  // Add codec support information to our aggregated list of supported codecs.
    113  // Incoming support info is merged with the current support info.
    114  // This is because different PDMs may report different codec support
    115  // information, so merging their results allows us to maintain a
    116  // cumulative support list without overwriting any existing data.
    117  static void AddSupport(const MediaCodecsSupported& aSupport);
    118 
    119  // Return a cumulative list of codec support information.
    120  // Each call to AddSupport adds to or updates this list.
    121  // This support information can be used to create user-readable strings
    122  // to report codec support information in about:support.
    123  static MediaCodecsSupported GetSupport();
    124 
    125  // Reset codec support information saved from calls to AddSupport().
    126  static void ResetSupport();
    127 
    128  // Query a MediaCodecsSupported EnumSet for codec-specific SW/HW support enums
    129  // and return general support information as stored in a DecodeSupportSet.
    130  //
    131  // Example input:
    132  //
    133  //   aCodec: MediaCodec::H264
    134  //   aDecode: MediaCodecsSupport {
    135  //     MediaCodecsSupport::AACSoftwareDecode
    136  //     MediaCodecsSupport::H264HardwareDecode,
    137  //     MediaCodecsSupport::H264SoftwareDecode,
    138  //     MediaCodecsSupport::VP8SoftwareDecode,
    139  //   }
    140  //
    141  // Example output:
    142  //
    143  //   DecodeSupportSet {
    144  //     DecodeSupport::SoftwareDecode,
    145  //     DecodeSupport::HardwareDecode
    146  //   }
    147  //
    148  static DecodeSupportSet GetDecodeSupportSet(
    149      const MediaCodec& aCodec, const MediaCodecsSupported& aSupported);
    150  static EncodeSupportSet GetEncodeSupportSet(
    151      const MediaCodec& aCodec, const MediaCodecsSupported& aSupported);
    152 
    153  // Return codec-specific SW/HW support enums for a given codec.
    154  // The DecodeSupportSet argument is used which codec-specific SW/HW
    155  // support values are returned, if any.
    156  //
    157  // Example input:
    158  //   aCodec: MediaCodec::VP8
    159  //   aSupportSet: DecodeSupportSet {DecodeSupport::SoftwareDecode}
    160  //
    161  // Example output:
    162  //   MediaCodecsSupported {MediaCodecsSupport::VP8SoftwareDecode}
    163  //
    164  static MediaCodecsSupported GetDecodeMediaCodecsSupported(
    165      const MediaCodec& aCodec, const DecodeSupportSet& aSupportSet);
    166  static MediaCodecsSupported GetEncodeMediaCodecsSupported(
    167      const MediaCodec& aCodec, const EncodeSupportSet& aSupportSet);
    168 
    169  // Generate a plaintext description for the SW/HW support information
    170  // contained in a MediaCodecsSupported EnumSet.
    171  //
    172  // Example input:
    173  //   MediaCodecsSupported {
    174  //     MediaCodecsSupport::H264SoftwareDecode,
    175  //     MediaCodecsSupport::H264HardwareDecode,
    176  //     MediaCodecsSupport::VP8SoftwareDecode
    177  //   }
    178  //
    179  // Example output (returned via argument aCodecString)
    180  //
    181  //   "SW H264 decode\n
    182  //   HW H264 decode\n
    183  //   SW VP8 decode"_ns
    184  //
    185  static void GetMediaCodecsSupportedString(
    186      nsCString& aSupportString, const MediaCodecsSupported& aSupportedCodecs);
    187 
    188  // Returns a MediaCodec enum representing the given MIME type string.
    189  //
    190  // Example input:
    191  //   "audio/flac"_ns
    192  //
    193  // Example output:
    194  //   MediaCodec::FLAC
    195  //
    196  static MediaCodec GetMediaCodecFromMimeType(const nsACString& aMimeType);
    197 
    198  // Returns array of hardcoded codec definitions.
    199  static std::array<CodecDefinition, 13> GetAllCodecDefinitions();
    200 
    201  // Parses an array of MIME type strings and returns a MediaCodecSet.
    202  static MediaCodecSet GetMediaCodecSetFromMimeTypes(
    203      const nsTArray<nsCString>& aCodecStrings);
    204 
    205  // Returns a MediaCodecsSupport enum corresponding to the provided
    206  // codec type and decode support level requested.
    207  static MediaCodecsSupport GetMediaCodecsSupportEnum(
    208      const MediaCodec& aCodec, const DecodeSupport& aSupport);
    209  static MediaCodecsSupport GetMediaCodecsSupportEnum(
    210      const MediaCodec& aCodec, const EncodeSupport& aSupport);
    211 
    212  // Returns true if SW/HW decode enum for a given codec is present in the args.
    213  static bool SupportsSoftwareDecode(
    214      const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
    215  static bool SupportsHardwareDecode(
    216      const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
    217 
    218  // Returns true if SW/HW encode enum for a given codec is present in the args.
    219  static bool SupportsSoftwareEncode(
    220      const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
    221  static bool SupportsHardwareEncode(
    222      const MediaCodecsSupported& aSupportedCodecs, const MediaCodec& aCodec);
    223 
    224  MCSInfo(MCSInfo const&) = delete;
    225  void operator=(MCSInfo const&) = delete;
    226  ~MCSInfo() = default;
    227 
    228 private:
    229  MCSInfo();
    230  static MCSInfo* GetInstance();
    231 
    232  // Returns a codec definition by MIME type name ("media/vp9")
    233  // or "common" name ("VP9")
    234  static CodecDefinition GetCodecDefinition(const MediaCodec& aCodec);
    235 
    236  UniquePtr<nsTHashMap<MediaCodecsSupport, CodecDefinition>> mHashTableMCS;
    237  UniquePtr<nsTHashMap<const char*, CodecDefinition>> mHashTableString;
    238  UniquePtr<nsTHashMap<MediaCodec, CodecDefinition>> mHashTableCodec;
    239  MediaCodecsSupported mSupport;
    240 };
    241 }  // namespace mozilla::media
    242 
    243 namespace mozilla {
    244 // Used for IPDL serialization.
    245 // The 'value' has to be the biggest enum from MediaCodecsSupport.
    246 template <typename T>
    247 struct MaxEnumValue;
    248 template <>
    249 struct MaxEnumValue<media::MediaCodecsSupport> {
    250  static constexpr unsigned int value =
    251      static_cast<unsigned int>(media::MediaCodecsSupport::SENTINEL);
    252 };
    253 }  // namespace mozilla
    254 
    255 #endif /* MediaCodecsSupport_h_ */