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 }