tor-browser

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

TestMediaCodecsSupport.cpp (9480B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      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 
      7 #include "MediaCodecsSupport.h"
      8 #include "gtest/gtest.h"
      9 
     10 using namespace mozilla;
     11 using namespace media;
     12 
     13 TEST(MediaCodecsSupport, BasicDecodeSupportSet)
     14 {
     15  DecodeSupportSet support{};
     16  EXPECT_TRUE(support != DecodeSupport::SoftwareDecode);
     17  EXPECT_TRUE(support != DecodeSupport::HardwareDecode);
     18  EXPECT_TRUE(!support.contains(DecodeSupport::SoftwareDecode));
     19  EXPECT_TRUE(!support.contains(DecodeSupport::HardwareDecode));
     20  EXPECT_TRUE(support.isEmpty());
     21 
     22  support += DecodeSupport::SoftwareDecode;
     23  EXPECT_TRUE(support == DecodeSupport::SoftwareDecode);
     24  EXPECT_TRUE(support != DecodeSupport::HardwareDecode);
     25  EXPECT_TRUE(support.contains(DecodeSupport::SoftwareDecode));
     26  EXPECT_TRUE(!support.contains(DecodeSupport::HardwareDecode));
     27  EXPECT_TRUE(!support.isEmpty());
     28 
     29  support += DecodeSupport::HardwareDecode;
     30  EXPECT_TRUE(support != DecodeSupport::SoftwareDecode);
     31  EXPECT_TRUE(support != DecodeSupport::HardwareDecode);
     32  EXPECT_TRUE(support.contains(DecodeSupport::SoftwareDecode));
     33  EXPECT_TRUE(support.contains(DecodeSupport::HardwareDecode));
     34  EXPECT_TRUE(!support.isEmpty());
     35 }
     36 
     37 // Test MCSInfo::GetDecodeSupportSet function.
     38 // This function is used to retrieve SW/HW support information for a
     39 // given codec from a MediaCodecsSupported EnumSet.
     40 // We validate that SW, HW, SW+HW, or lack of support information is
     41 // properly returned.
     42 TEST(MediaCodecsSupport, GetDecodeSupportSet)
     43 {
     44  // Mock VP8 SW support, VP9 HW support, H264 SW+HW support
     45  MediaCodecsSupported supported{MediaCodecsSupport::VP8SoftwareDecode,
     46                                 MediaCodecsSupport::VP9HardwareDecode,
     47                                 MediaCodecsSupport::H264SoftwareDecode,
     48                                 MediaCodecsSupport::H264HardwareDecode};
     49 
     50  MediaCodec codec;     // Codec used to generate + filter results
     51  DecodeSupportSet RV;  // Return value to check for validity
     52 
     53  // Check only SW support returned for VP8
     54  codec = MediaCodec::VP8;
     55  RV = MCSInfo::GetDecodeSupportSet(codec, supported);
     56  EXPECT_TRUE(RV.contains(DecodeSupport::SoftwareDecode));
     57  EXPECT_TRUE(RV.size() == 1);
     58 
     59  // Check only HW support returned for VP9
     60  codec = MediaCodec::VP9;
     61  RV = MCSInfo::GetDecodeSupportSet(codec, supported);
     62  EXPECT_TRUE(RV.contains(DecodeSupport::HardwareDecode));
     63  EXPECT_TRUE(RV.size() == 1);
     64 
     65  // Check for both SW/HW support returned for H264
     66  codec = MediaCodec::H264;
     67  RV = MCSInfo::GetDecodeSupportSet(codec, supported);
     68  EXPECT_TRUE(RV.contains(DecodeSupport::SoftwareDecode));
     69  EXPECT_TRUE(RV.contains(DecodeSupport::HardwareDecode));
     70  EXPECT_TRUE(RV.size() == 2);
     71 
     72  // Check empty return if codec not in list of codecs
     73  codec = MediaCodec::AV1;
     74  RV = MCSInfo::GetDecodeSupportSet(codec, supported);
     75  EXPECT_TRUE(RV.size() == 0);
     76 }
     77 
     78 // Test MCSInfo::GetDecodeMediaCodecsSupported function.
     79 // This function is used to generate codec-specific SW/HW
     80 // support information from a generic codec identifier enum and
     81 // generic SW/HW support information.
     82 // We validate that SW, HW, SW+HW, or lack of support information is
     83 // properly returned.
     84 TEST(MediaCodecsSupport, GetDecodeMediaCodecsSupported)
     85 {
     86  MediaCodec codec;         // Codec used to generate / filter results
     87  MediaCodecsSupported RV;  // Return value to check for validity
     88  DecodeSupportSet dss;     // Non codec-specific SW / HW support information
     89 
     90  // Check SW support returned for VP8
     91  codec = MediaCodec::VP8;
     92  dss = DecodeSupportSet{DecodeSupport::SoftwareDecode};
     93  RV = MCSInfo::GetDecodeMediaCodecsSupported(codec, dss);
     94  EXPECT_TRUE(RV.contains(MediaCodecsSupport::VP8SoftwareDecode));
     95  EXPECT_TRUE(RV.size() == 1);
     96 
     97  // Check HW support returned for AV1
     98  codec = MediaCodec::AV1;
     99  dss = DecodeSupportSet{DecodeSupport::HardwareDecode};
    100  RV = MCSInfo::GetDecodeMediaCodecsSupported(codec, dss);
    101  EXPECT_TRUE(RV.contains(MediaCodecsSupport::AV1HardwareDecode));
    102  EXPECT_TRUE(RV.size() == 1);
    103 
    104  // Check SW + HW support returned for VP9
    105  codec = MediaCodec::VP9;
    106  dss = DecodeSupportSet{DecodeSupport::SoftwareDecode,
    107                         DecodeSupport::HardwareDecode};
    108  RV = MCSInfo::GetDecodeMediaCodecsSupported(codec, dss);
    109  EXPECT_TRUE(RV.contains(MediaCodecsSupport::VP9SoftwareDecode));
    110  EXPECT_TRUE(RV.contains(MediaCodecsSupport::VP9HardwareDecode));
    111  EXPECT_TRUE(RV.size() == 2);
    112 
    113  // Check empty return if codec not supported
    114  codec = MediaCodec::AV1;
    115  dss = DecodeSupportSet{};
    116  RV = MCSInfo::GetDecodeMediaCodecsSupported(codec, dss);
    117  EXPECT_TRUE(RV.size() == 0);
    118 }
    119 
    120 // Test MCSInfo::AddSupport function.
    121 // This function is used to store codec support data.
    122 // Incoming support data will be merged with any data that
    123 // has already been stored.
    124 TEST(MediaCodecsSupport, AddSupport)
    125 {
    126  // Make sure we're not storing any existing support information.
    127  MCSInfo::ResetSupport();
    128  EXPECT_TRUE(MCSInfo::GetSupport().size() == 0);
    129 
    130  // Add codec support one at a time via individual calls
    131  MCSInfo::AddSupport(MediaCodecsSupport::AACSoftwareDecode);
    132  MCSInfo::AddSupport(MediaCodecsSupport::VP9SoftwareDecode);
    133  MCSInfo::AddSupport(MediaCodecsSupport::AV1HardwareDecode);
    134 
    135  // Add multiple codec support via MediaCodecsSupported EnumSet
    136  MCSInfo::AddSupport(
    137      MediaCodecsSupported{MediaCodecsSupport::H264SoftwareDecode,
    138                           MediaCodecsSupport::H264HardwareDecode});
    139 
    140  // Query MCSInfo for supported codecs
    141  MediaCodecsSupported supported = MCSInfo::GetSupport();
    142  DecodeSupportSet dss;
    143 
    144  // AAC should only report software decode support
    145  dss = MCSInfo::GetDecodeSupportSet(MediaCodec::AAC, supported);
    146  EXPECT_TRUE(dss.size() == 1);
    147  EXPECT_TRUE(dss.contains(DecodeSupport::SoftwareDecode));
    148 
    149  // AV1 should only report hardware decode support
    150  dss = MCSInfo::GetDecodeSupportSet(MediaCodec::AV1, supported);
    151  EXPECT_TRUE(dss.size() == 1);
    152  EXPECT_TRUE(dss.contains(DecodeSupport::HardwareDecode));
    153 
    154  // H264 should report both SW + HW decode support
    155  dss = MCSInfo::GetDecodeSupportSet(MediaCodec::H264, supported);
    156  EXPECT_TRUE(dss.size() == 2);
    157  EXPECT_TRUE(dss.contains(DecodeSupport::SoftwareDecode));
    158  EXPECT_TRUE(dss.contains(DecodeSupport::HardwareDecode));
    159 
    160  // Vorbis should report no decode support
    161  dss = MCSInfo::GetDecodeSupportSet(MediaCodec::Vorbis, supported);
    162  EXPECT_TRUE(dss.size() == 0);
    163 }
    164 
    165 // Test MCSInfo::GetMediaCodecsSupportedString function.
    166 // This function returns a human-readable string containing codec
    167 // names and SW/HW playback support information.
    168 TEST(MediaCodecsSupport, GetMediaCodecsSupportedString)
    169 {
    170  // Make sure we're not storing any existing support information.
    171  MCSInfo::ResetSupport();
    172  EXPECT_TRUE(MCSInfo::GetSupport().size() == 0);
    173 
    174  // Add H264 SW/HW support + VP8 Software decode support.
    175  MCSInfo::AddSupport({MediaCodecsSupport::H264SoftwareDecode,
    176                       MediaCodecsSupport::H264HardwareDecode,
    177                       MediaCodecsSupport::VP8SoftwareDecode,
    178                       MediaCodecsSupport::VP9HardwareDecode});
    179 
    180  nsCString supportString;
    181  nsCString targetString;
    182  MCSInfo::GetMediaCodecsSupportedString(supportString, MCSInfo::GetSupport());
    183 
    184  // MCSInfo should return support text for all possible codecs
    185  for (const auto& it : MCSInfo::GetAllCodecDefinitions()) {
    186    if (it.codec == MediaCodec::SENTINEL) {
    187      break;
    188    }
    189    nsCString cn(it.commonName);
    190    // H264/VP8/VP9 support text should reflect args to MCSInfo::AddSupport
    191    if (cn == "H264"_ns) {
    192      targetString += "H264 SWDEC HWDEC"_ns;
    193    } else if (cn.Equals("VP8"_ns)) {
    194      targetString += "VP8 SWDEC"_ns;
    195    } else if (cn.Equals("VP9"_ns)) {
    196      targetString += "VP9 HWDEC"_ns;
    197    } else {
    198      targetString += nsCString(it.commonName) + " NONE"_ns;
    199    }
    200    targetString += "\n"_ns;
    201  }
    202  // MCSInfo support string should not have a trailing newline
    203  if (!targetString.IsEmpty()) {
    204    targetString.Truncate(targetString.Length() - 1);
    205  }
    206  EXPECT_TRUE(supportString.Equals(targetString));
    207 }
    208 
    209 // Test MCSInfo::GetMediaCodecFromMimeType function.
    210 // This function returns a MediaCodec enum for a given MIME type string.
    211 TEST(MediaCodecsSupport, GetMediaCodecFromMimeType)
    212 {
    213  std::vector<std::pair<nsCString, MediaCodec>> testPairs = {
    214 // Video codecs
    215 #ifdef MOZ_AV1
    216      {"video/av1"_ns, MediaCodec::AV1},
    217 #endif
    218      {"video/avc"_ns, MediaCodec::H264},
    219      {"video/mp4"_ns, MediaCodec::H264},
    220      {"video/vp8"_ns, MediaCodec::VP8},
    221      {"video/vp9"_ns, MediaCodec::VP9},
    222      // Audio codecs
    223      {"audio/mp4a-latm"_ns, MediaCodec::AAC},
    224      {"audio/flac"_ns, MediaCodec::FLAC},
    225      {"audio/mpeg"_ns, MediaCodec::MP3},
    226      {"audio/opus"_ns, MediaCodec::Opus},
    227      {"audio/vorbis"_ns, MediaCodec::Vorbis},
    228      {"audio/x-wav"_ns, MediaCodec::Wave},
    229      // Non-existant codecs that should fail
    230      {"audio/jukebox"_ns, MediaCodec::SENTINEL},
    231      {"video/stopmotion"_ns, MediaCodec::SENTINEL},
    232      {"漢字"_ns, MediaCodec::SENTINEL},
    233      {"/"_ns, MediaCodec::SENTINEL},
    234      {""_ns, MediaCodec::SENTINEL},
    235  };
    236  for (auto& p : testPairs) {
    237    EXPECT_TRUE(MCSInfo::GetMediaCodecFromMimeType(p.first) == p.second);
    238  }
    239 }