Changeset 270019 in webkit
- Timestamp:
- Nov 19, 2020 12:54:28 AM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r270018 r270019 1 2020-11-19 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GStreamer] GStreamerRegistryScanner cleanups and improvements 4 https://bugs.webkit.org/show_bug.cgi?id=219078 5 6 Reviewed by Philippe Normand. 7 8 We are creating the factories and keeping them alive forever, because GStreamerRegistryScanner is singleton. We 9 can just delete them after the initialization and then create the factories we need on demand when checking AV1 10 codecs. This patch includes some other minor fixes and cleanups (missing const, avoid using blackList, etc.) 11 12 * platform/graphics/gstreamer/GStreamerRegistryScanner.cpp: 13 (WebCore::GStreamerRegistryScanner::ElementFactories::ElementFactories): Create the factories for the given types. 14 (WebCore::GStreamerRegistryScanner::ElementFactories::~ElementFactories): Destroy the factories. 15 (WebCore::GStreamerRegistryScanner::ElementFactories::elementFactoryTypeToString): Return a string for the given 16 factory type, used for logging. 17 (WebCore::GStreamerRegistryScanner::ElementFactories::factory const): Return the factory for the given type. 18 (WebCore::GStreamerRegistryScanner::ElementFactories::hasElementForMediaType const): Moved here now receiving a 19 factory type instead of the factory itself. 20 (WebCore::GStreamerRegistryScanner::GStreamerRegistryScanner): Create a ElementFactories for all the types and 21 pass it to the initializers. 22 (WebCore::GStreamerRegistryScanner::mimeTypeSet const): Use release assert and remove the return. 23 (WebCore::GStreamerRegistryScanner::isContainerTypeSupported const): Ditto. 24 (WebCore::GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping): It receives a ElementFactories now. 25 (WebCore::GStreamerRegistryScanner::initializeDecoders): Ditto. 26 (WebCore::GStreamerRegistryScanner::initializeEncoders): Ditto. 27 (WebCore::GStreamerRegistryScanner::isCodecSupported const): Make the received code name const. 28 (WebCore::GStreamerRegistryScanner::areAllCodecsSupported const): Use const references to iterate the codecs. 29 (WebCore::GStreamerRegistryScanner::isAVC1CodecSupported const): Create a ElementFactories for the appropriate 30 type and use to check if the given codec is supported. 31 (WebCore::GStreamerRegistryScanner::isConfigurationSupported const): Make mediaConfiguration parameter const. 32 (WebCore::GStreamerRegistryScanner::~GStreamerRegistryScanner): Deleted. 33 (WebCore::GStreamerRegistryScanner::mimeTypeSet): Deleted. 34 (WebCore::GStreamerRegistryScanner::hasElementForMediaType const): Deleted. 35 * platform/graphics/gstreamer/GStreamerRegistryScanner.h: 36 1 37 2020-11-17 Sergio Villar Senin <svillar@igalia.com> 2 38 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp
r269685 r270019 40 40 } 41 41 42 GStreamerRegistryScanner::ElementFactories::ElementFactories(OptionSet<ElementFactories::Type> types) 43 { 44 if (types.contains(Type::AudioDecoder)) 45 audioDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); 46 if (types.contains(Type::AudioParser)) 47 audioParserFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_NONE); 48 if (types.contains(Type::VideoDecoder)) 49 videoDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 50 if (types.contains(Type::VideoParser)) 51 videoParserFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 52 if (types.contains(Type::Demuxer)) 53 demuxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DEMUXER, GST_RANK_MARGINAL); 54 if (types.contains(Type::AudioEncoder)) 55 audioEncoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); 56 if (types.contains(Type::VideoEncoder)) 57 videoEncoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 58 if (types.contains(Type::Muxer)) 59 muxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_MUXER, GST_RANK_MARGINAL); 60 } 61 62 GStreamerRegistryScanner::ElementFactories::~ElementFactories() 63 { 64 gst_plugin_feature_list_free(audioDecoderFactories); 65 gst_plugin_feature_list_free(audioParserFactories); 66 gst_plugin_feature_list_free(videoDecoderFactories); 67 gst_plugin_feature_list_free(videoParserFactories); 68 gst_plugin_feature_list_free(demuxerFactories); 69 gst_plugin_feature_list_free(audioEncoderFactories); 70 gst_plugin_feature_list_free(videoEncoderFactories); 71 gst_plugin_feature_list_free(muxerFactories); 72 } 73 74 const char* GStreamerRegistryScanner::ElementFactories::elementFactoryTypeToString(GStreamerRegistryScanner::ElementFactories::Type factoryType) 75 { 76 switch (factoryType) { 77 case Type::AudioParser: 78 return "audio parser"; 79 case Type::AudioDecoder: 80 return "audio decoder"; 81 case Type::VideoParser: 82 return "video parser"; 83 case Type::VideoDecoder: 84 return "video decoder"; 85 case Type::Demuxer: 86 return "demuxer"; 87 case Type::AudioEncoder: 88 return "audio encoder"; 89 case Type::VideoEncoder: 90 return "video encoder"; 91 case Type::Muxer: 92 return "muxer"; 93 case Type::All: 94 break; 95 } 96 97 RELEASE_ASSERT_NOT_REACHED(); 98 } 99 100 GList* GStreamerRegistryScanner::ElementFactories::factory(GStreamerRegistryScanner::ElementFactories::Type factoryType) const 101 { 102 switch (factoryType) { 103 case GStreamerRegistryScanner::ElementFactories::Type::AudioParser: 104 return audioParserFactories; 105 case GStreamerRegistryScanner::ElementFactories::Type::AudioDecoder: 106 return audioDecoderFactories; 107 case GStreamerRegistryScanner::ElementFactories::Type::VideoParser: 108 return videoParserFactories; 109 case GStreamerRegistryScanner::ElementFactories::Type::VideoDecoder: 110 return videoDecoderFactories; 111 case GStreamerRegistryScanner::ElementFactories::Type::Demuxer: 112 return demuxerFactories; 113 case GStreamerRegistryScanner::ElementFactories::Type::AudioEncoder: 114 return audioEncoderFactories; 115 case GStreamerRegistryScanner::ElementFactories::Type::VideoEncoder: 116 return videoEncoderFactories; 117 case GStreamerRegistryScanner::ElementFactories::Type::Muxer: 118 return muxerFactories; 119 case GStreamerRegistryScanner::ElementFactories::Type::All: 120 break; 121 } 122 123 RELEASE_ASSERT_NOT_REACHED(); 124 } 125 126 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::ElementFactories::hasElementForMediaType(ElementFactories::Type factoryType, const char* capsString, ElementFactories::CheckHardwareClassifier shouldCheckHardwareClassifier, Optional<Vector<String>> disallowedList) const 127 { 128 auto* elementFactories = factory(factoryType); 129 if (!elementFactories) 130 return { }; 131 132 GstPadDirection padDirection = GST_PAD_SINK; 133 if (factoryType == Type::AudioEncoder || factoryType == Type::VideoEncoder || factoryType == Type::Muxer) 134 padDirection = GST_PAD_SRC; 135 136 GRefPtr<GstCaps> caps = adoptGRef(gst_caps_from_string(capsString)); 137 GList* candidates = gst_element_factory_list_filter(elementFactories, caps.get(), padDirection, false); 138 bool isSupported = candidates; 139 bool isUsingHardware = false; 140 141 if (disallowedList.hasValue() && !disallowedList->isEmpty()) { 142 bool hasValidCandidate = false; 143 for (GList* factories = candidates; factories; factories = g_list_next(factories)) { 144 String name = String::fromUTF8(gst_plugin_feature_get_name(GST_PLUGIN_FEATURE_CAST(factories->data))); 145 if (disallowedList->contains(name)) 146 continue; 147 hasValidCandidate = true; 148 break; 149 } 150 if (!hasValidCandidate) { 151 GST_WARNING("All %s elements matching caps %" GST_PTR_FORMAT " are disallowed", elementFactoryTypeToString(factoryType), caps.get()); 152 isSupported = false; 153 shouldCheckHardwareClassifier = CheckHardwareClassifier::No; 154 } 155 } 156 157 if (shouldCheckHardwareClassifier == CheckHardwareClassifier::Yes) { 158 for (GList* factories = candidates; factories; factories = g_list_next(factories)) { 159 auto* factory = reinterpret_cast<GstElementFactory*>(factories->data); 160 String metadata = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS); 161 auto components = metadata.split('/'); 162 if (components.contains("Hardware")) { 163 isUsingHardware = true; 164 break; 165 } 166 } 167 } 168 169 gst_plugin_feature_list_free(candidates); 170 GST_LOG("Lookup result for %s matching caps %" GST_PTR_FORMAT " : isSupported=%s, isUsingHardware=%s", elementFactoryTypeToString(factoryType), caps.get(), boolForPrinting(isSupported), boolForPrinting(isUsingHardware)); 171 return { isSupported, isUsingHardware }; 172 } 173 42 174 GStreamerRegistryScanner::GStreamerRegistryScanner(bool isMediaSource) 43 175 : m_isMediaSource(isMediaSource) 44 176 { 45 177 GST_DEBUG_CATEGORY_INIT(webkit_media_gst_registry_scanner_debug, "webkitregistryscanner", 0, "WebKit GStreamer registry scanner"); 46 m_audioDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); 47 m_audioParserFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_NONE); 48 m_videoDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 49 m_videoParserFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_PARSER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 50 m_demuxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DEMUXER, GST_RANK_MARGINAL); 51 52 m_audioEncoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); 53 m_videoEncoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ENCODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 54 m_muxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_MUXER, GST_RANK_MARGINAL); 55 56 initializeDecoders(); 57 initializeEncoders(); 178 179 ElementFactories factories(ElementFactories::Type::All); 180 initializeDecoders(factories); 181 initializeEncoders(factories); 182 58 183 #ifndef GST_DISABLE_GST_DEBUG 59 184 GST_DEBUG("%s registry scanner initialized", m_isMediaSource ? "MSE" : "Regular playback"); … … 69 194 } 70 195 71 GStreamerRegistryScanner::~GStreamerRegistryScanner() 72 { 73 gst_plugin_feature_list_free(m_audioDecoderFactories); 74 gst_plugin_feature_list_free(m_audioParserFactories); 75 gst_plugin_feature_list_free(m_videoDecoderFactories); 76 gst_plugin_feature_list_free(m_videoParserFactories); 77 gst_plugin_feature_list_free(m_demuxerFactories); 78 gst_plugin_feature_list_free(m_audioEncoderFactories); 79 gst_plugin_feature_list_free(m_videoEncoderFactories); 80 gst_plugin_feature_list_free(m_muxerFactories); 81 } 82 83 const HashSet<String, ASCIICaseInsensitiveHash>& GStreamerRegistryScanner::mimeTypeSet(Configuration configuration) 196 const HashSet<String, ASCIICaseInsensitiveHash>& GStreamerRegistryScanner::mimeTypeSet(Configuration configuration) const 84 197 { 85 198 switch (configuration) { … … 89 202 return m_encoderMimeTypeSet; 90 203 } 91 ASSERT_NOT_REACHED(); 92 return m_decoderMimeTypeSet; 93 } 94 95 bool GStreamerRegistryScanner::isContainerTypeSupported(Configuration configuration, String containerType) const 204 RELEASE_ASSERT_NOT_REACHED(); 205 } 206 207 bool GStreamerRegistryScanner::isContainerTypeSupported(Configuration configuration, const String& containerType) const 96 208 { 97 209 switch (configuration) { … … 101 213 return m_encoderMimeTypeSet.contains(containerType); 102 214 } 103 ASSERT_NOT_REACHED(); 104 return false; 105 } 106 107 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::hasElementForMediaType(GList* elementFactories, const char* capsString, bool shouldCheckHardwareClassifier, Optional<Vector<String>> blackList) const 108 { 109 GstPadDirection padDirection = GST_PAD_SINK; 110 if (elementFactories == m_audioEncoderFactories || elementFactories == m_videoEncoderFactories || elementFactories == m_muxerFactories) 111 padDirection = GST_PAD_SRC; 112 GRefPtr<GstCaps> caps = adoptGRef(gst_caps_from_string(capsString)); 113 GList* candidates = gst_element_factory_list_filter(elementFactories, caps.get(), padDirection, false); 114 bool isSupported = candidates; 115 bool isUsingHardware = false; 116 117 const char* elementType = ""; 118 if (elementFactories == m_audioParserFactories) 119 elementType = "audio parser"; 120 else if (elementFactories == m_audioDecoderFactories) 121 elementType = "audio decoder"; 122 else if (elementFactories == m_videoParserFactories) 123 elementType = "video parser"; 124 else if (elementFactories == m_videoDecoderFactories) 125 elementType = "video decoder"; 126 else if (elementFactories == m_demuxerFactories) 127 elementType = "demuxer"; 128 else if (elementFactories == m_audioEncoderFactories) 129 elementType = "audio encoder"; 130 else if (elementFactories == m_videoEncoderFactories) 131 elementType = "video encoder"; 132 else if (elementFactories == m_muxerFactories) 133 elementType = "muxer"; 134 else 135 ASSERT_NOT_REACHED(); 136 137 if (blackList.hasValue() && !blackList->isEmpty()) { 138 bool hasValidCandidate = false; 139 for (GList* factories = candidates; factories; factories = g_list_next(factories)) { 140 String name(gst_plugin_feature_get_name(GST_PLUGIN_FEATURE_CAST(factories->data))); 141 if (blackList->contains(name)) 142 continue; 143 hasValidCandidate = true; 144 break; 145 } 146 if (!hasValidCandidate) { 147 GST_WARNING("All %s elements matching caps %" GST_PTR_FORMAT " are blacklisted", elementType, caps.get()); 148 isSupported = false; 149 shouldCheckHardwareClassifier = false; 150 } 151 } 152 153 if (shouldCheckHardwareClassifier) { 154 for (GList* factories = candidates; factories; factories = g_list_next(factories)) { 155 auto* factory = reinterpret_cast<GstElementFactory*>(factories->data); 156 String metadata = gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS); 157 auto components = metadata.split('/'); 158 if (components.contains("Hardware")) { 159 isUsingHardware = true; 160 break; 161 } 162 } 163 } 164 165 gst_plugin_feature_list_free(candidates); 166 GST_LOG("Lookup result for %s matching caps %" GST_PTR_FORMAT " : isSupported=%s, isUsingHardware=%s", elementType, caps.get(), boolForPrinting(isSupported), boolForPrinting(isUsingHardware)); 167 return GStreamerRegistryScanner::RegistryLookupResult { isSupported, isUsingHardware }; 168 } 169 170 void GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping(Vector<GstCapsWebKitMapping>& mapping) 171 { 172 for (auto& current : mapping) { 173 GList* factories; 174 switch (current.elementType) { 175 case Demuxer: 176 factories = m_demuxerFactories; 177 break; 178 case AudioDecoder: 179 factories = m_audioDecoderFactories; 180 break; 181 case VideoDecoder: 182 factories = m_videoDecoderFactories; 183 break; 184 } 185 186 if (hasElementForMediaType(factories, current.capsString)) { 215 RELEASE_ASSERT_NOT_REACHED(); 216 } 217 218 void GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping(const GStreamerRegistryScanner::ElementFactories& factories, const Vector<GstCapsWebKitMapping>& mapping) 219 { 220 for (const auto& current : mapping) { 221 if (factories.hasElementForMediaType(current.elementType, current.capsString)) { 187 222 if (!current.webkitCodecPatterns.isEmpty()) { 188 223 for (const auto& pattern : current.webkitCodecPatterns) … … 198 233 } 199 234 200 void GStreamerRegistryScanner::initializeDecoders( )201 { 202 if ( hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)4")) {235 void GStreamerRegistryScanner::initializeDecoders(const GStreamerRegistryScanner::ElementFactories& factories) 236 { 237 if (factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/mpeg, mpegversion=(int)4")) { 203 238 m_decoderMimeTypeSet.add(AtomString("audio/aac")); 204 239 m_decoderMimeTypeSet.add(AtomString("audio/mp4")); … … 208 243 } 209 244 210 auto opusSupported = hasElementForMediaType(m_audioDecoderFactories, "audio/x-opus");211 if (opusSupported && (!m_isMediaSource || hasElementForMediaType(m_audioParserFactories, "audio/x-opus"))) {245 auto opusSupported = factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/x-opus"); 246 if (opusSupported && (!m_isMediaSource || factories.hasElementForMediaType(ElementFactories::Type::AudioParser, "audio/x-opus"))) { 212 247 m_decoderMimeTypeSet.add(AtomString("audio/opus")); 213 248 m_decoderCodecMap.add(AtomString("opus"), false); … … 215 250 } 216 251 217 auto vorbisSupported = hasElementForMediaType(m_audioDecoderFactories, "audio/x-vorbis");218 if (vorbisSupported && (!m_isMediaSource || hasElementForMediaType(m_audioParserFactories, "audio/x-vorbis"))) {252 auto vorbisSupported = factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/x-vorbis"); 253 if (vorbisSupported && (!m_isMediaSource || factories.hasElementForMediaType(ElementFactories::Type::AudioParser, "audio/x-vorbis"))) { 219 254 m_decoderCodecMap.add(AtomString("vorbis"), false); 220 255 m_decoderCodecMap.add(AtomString("x-vorbis"), false); 221 256 } 222 257 223 bool matroskaSupported = hasElementForMediaType(m_demuxerFactories, "video/x-matroska");258 bool matroskaSupported = factories.hasElementForMediaType(ElementFactories::Type::Demuxer, "video/x-matroska"); 224 259 if (matroskaSupported) { 225 auto vp8DecoderAvailable = hasElementForMediaType(m_videoDecoderFactories, "video/x-vp8", true);226 auto vp9DecoderAvailable = hasElementForMediaType(m_videoDecoderFactories, "video/x-vp9", true);260 auto vp8DecoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-vp8", ElementFactories::CheckHardwareClassifier::Yes); 261 auto vp9DecoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-vp9", ElementFactories::CheckHardwareClassifier::Yes); 227 262 228 263 if (vp8DecoderAvailable || vp9DecoderAvailable) … … 244 279 } 245 280 246 auto h264DecoderAvailable = hasElementForMediaType(m_videoDecoderFactories, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", true);247 if (h264DecoderAvailable && (!m_isMediaSource || hasElementForMediaType(m_videoParserFactories, "video/x-h264"))) {281 auto h264DecoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", ElementFactories::CheckHardwareClassifier::Yes); 282 if (h264DecoderAvailable && (!m_isMediaSource || factories.hasElementForMediaType(ElementFactories::Type::VideoParser, "video/x-h264"))) { 248 283 m_decoderMimeTypeSet.add(AtomString("video/mp4")); 249 284 m_decoderMimeTypeSet.add(AtomString("video/x-m4v")); … … 253 288 } 254 289 255 Vector<String> av1Decoders Blacklist { "av1dec"_s };256 if ((matroskaSupported || isContainerTypeSupported(Configuration::Decoding, "video/mp4")) && hasElementForMediaType(m_videoDecoderFactories, "video/x-av1", false, makeOptional(WTFMove(av1DecodersBlacklist)))) {290 Vector<String> av1DecodersDisallowedList { "av1dec"_s }; 291 if ((matroskaSupported || isContainerTypeSupported(Configuration::Decoding, "video/mp4")) && factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-av1", ElementFactories::CheckHardwareClassifier::No, makeOptional(WTFMove(av1DecodersDisallowedList)))) { 257 292 m_decoderCodecMap.add(AtomString("av01*"), false); 258 293 m_decoderCodecMap.add(AtomString("av1"), false); … … 266 301 267 302 Vector<GstCapsWebKitMapping> mapping = { 268 { AudioDecoder, "audio/midi", {"audio/midi", "audio/riff-midi"}, { }},269 { AudioDecoder, "audio/x-ac3", { }, { }},270 { AudioDecoder, "audio/x-dts", { }, { }},271 { AudioDecoder, "audio/x-eac3", {"audio/x-ac3"}, { }},272 { AudioDecoder, "audio/x-flac", {"audio/x-flac", "audio/flac"}, { }},273 { AudioDecoder, "audio/x-sbc", { }, { }},274 { AudioDecoder, "audio/x-sid", { }, { }},275 { AudioDecoder, "audio/x-speex", {"audio/speex", "audio/x-speex"}, { }},276 { AudioDecoder, "audio/x-wavpack", {"audio/x-wavpack"}, { }},277 { VideoDecoder, "video/mpeg, mpegversion=(int){1,2}, systemstream=(boolean)false", {"video/mpeg"}, {"mpeg"}},278 { VideoDecoder, "video/mpegts", { }, { }},279 { VideoDecoder, "video/x-dirac", { }, { }},280 { VideoDecoder, "video/x-flash-video", {"video/flv", "video/x-flv"}, { }},281 { VideoDecoder, "video/x-h263", { }, { }},282 { VideoDecoder, "video/x-msvideocodec", {"video/x-msvideo"}, { }},283 { Demuxer, "application/vnd.rn-realmedia", { }, { }},284 { Demuxer, "application/x-3gp", { }, { }},285 { Demuxer, "application/x-hls", {"application/vnd.apple.mpegurl", "application/x-mpegurl"}, { }},286 { Demuxer, "application/x-pn-realaudio", { }, { }},287 { Demuxer, "audio/x-aiff", { }, { }},288 { Demuxer, "audio/x-wav", {"audio/x-wav", "audio/wav", "audio/vnd.wave"}, {"1"}},289 { Demuxer, "video/quicktime", { }, { }},290 { Demuxer, "video/quicktime, variant=(string)3gpp", {"video/3gpp"}, { }},291 { Demuxer, "video/x-ms-asf", { }, { }},303 { ElementFactories::Type::AudioDecoder, "audio/midi", { "audio/midi", "audio/riff-midi" }, { } }, 304 { ElementFactories::Type::AudioDecoder, "audio/x-ac3", { }, { } }, 305 { ElementFactories::Type::AudioDecoder, "audio/x-dts", { }, { } }, 306 { ElementFactories::Type::AudioDecoder, "audio/x-eac3", { "audio/x-ac3" }, { } }, 307 { ElementFactories::Type::AudioDecoder, "audio/x-flac", { "audio/x-flac", "audio/flac" }, { } }, 308 { ElementFactories::Type::AudioDecoder, "audio/x-sbc", { }, { } }, 309 { ElementFactories::Type::AudioDecoder, "audio/x-sid", { }, { } }, 310 { ElementFactories::Type::AudioDecoder, "audio/x-speex", { "audio/speex", "audio/x-speex" }, { } }, 311 { ElementFactories::Type::AudioDecoder, "audio/x-wavpack", { "audio/x-wavpack" }, { } }, 312 { ElementFactories::Type::VideoDecoder, "video/mpeg, mpegversion=(int){1,2}, systemstream=(boolean)false", { "video/mpeg" }, { "mpeg" } }, 313 { ElementFactories::Type::VideoDecoder, "video/mpegts", { }, { } }, 314 { ElementFactories::Type::VideoDecoder, "video/x-dirac", { }, { } }, 315 { ElementFactories::Type::VideoDecoder, "video/x-flash-video", { "video/flv", "video/x-flv" }, { } }, 316 { ElementFactories::Type::VideoDecoder, "video/x-h263", { }, { } }, 317 { ElementFactories::Type::VideoDecoder, "video/x-msvideocodec", { "video/x-msvideo" }, { } }, 318 { ElementFactories::Type::Demuxer, "application/vnd.rn-realmedia", { }, { } }, 319 { ElementFactories::Type::Demuxer, "application/x-3gp", { }, { } }, 320 { ElementFactories::Type::Demuxer, "application/x-hls", { "application/vnd.apple.mpegurl", "application/x-mpegurl" }, { } }, 321 { ElementFactories::Type::Demuxer, "application/x-pn-realaudio", { }, { } }, 322 { ElementFactories::Type::Demuxer, "audio/x-aiff", { }, { } }, 323 { ElementFactories::Type::Demuxer, "audio/x-wav", { "audio/x-wav", "audio/wav", "audio/vnd.wave" }, { "1" } }, 324 { ElementFactories::Type::Demuxer, "video/quicktime", { }, { } }, 325 { ElementFactories::Type::Demuxer, "video/quicktime, variant=(string)3gpp", { "video/3gpp" }, { } }, 326 { ElementFactories::Type::Demuxer, "video/x-ms-asf", { }, { } }, 292 327 }; 293 fillMimeTypeSetFromCapsMapping( mapping);294 295 if ( hasElementForMediaType(m_demuxerFactories, "application/ogg")) {328 fillMimeTypeSetFromCapsMapping(factories, mapping); 329 330 if (factories.hasElementForMediaType(ElementFactories::Type::Demuxer, "application/ogg")) { 296 331 m_decoderMimeTypeSet.add(AtomString("application/ogg")); 297 332 … … 301 336 } 302 337 303 if ( hasElementForMediaType(m_audioDecoderFactories, "audio/x-speex")) {338 if (factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/x-speex")) { 304 339 m_decoderMimeTypeSet.add(AtomString("audio/ogg")); 305 340 m_decoderCodecMap.add(AtomString("speex"), false); 306 341 } 307 342 308 if ( hasElementForMediaType(m_videoDecoderFactories, "video/x-theora")) {343 if (factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-theora")) { 309 344 m_decoderMimeTypeSet.add(AtomString("video/ogg")); 310 345 m_decoderCodecMap.add(AtomString("theora"), false); … … 313 348 314 349 bool audioMpegSupported = false; 315 if ( hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)1, layer=(int)[1, 3]")) {350 if (factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/mpeg, mpegversion=(int)1, layer=(int)[1, 3]")) { 316 351 audioMpegSupported = true; 317 352 m_decoderMimeTypeSet.add(AtomString("audio/mp1")); … … 322 357 } 323 358 324 if ( hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)2")) {359 if (factories.hasElementForMediaType(ElementFactories::Type::AudioDecoder, "audio/mpeg, mpegversion=(int)2")) { 325 360 audioMpegSupported = true; 326 361 m_decoderMimeTypeSet.add(AtomString("audio/mp2")); … … 336 371 m_decoderMimeTypeSet.add(AtomString("video/x-matroska")); 337 372 338 if ( hasElementForMediaType(m_videoDecoderFactories, "video/x-vp10"))373 if (factories.hasElementForMediaType(ElementFactories::Type::VideoDecoder, "video/x-vp10")) 339 374 m_decoderMimeTypeSet.add(AtomString("video/webm")); 340 375 } 341 376 } 342 377 343 void GStreamerRegistryScanner::initializeEncoders( )378 void GStreamerRegistryScanner::initializeEncoders(const GStreamerRegistryScanner::ElementFactories& factories) 344 379 { 345 380 // MSE is about playback, which means decoding. No need to check for encoders then. … … 347 382 return; 348 383 349 auto aacSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/mpeg, mpegversion=(int)4");350 if ( hasElementForMediaType(m_audioEncoderFactories, "audio/mpeg, mpegversion=(int)4")) {384 auto aacSupported = factories.hasElementForMediaType(ElementFactories::Type::AudioEncoder, "audio/mpeg, mpegversion=(int)4"); 385 if (factories.hasElementForMediaType(ElementFactories::Type::AudioEncoder, "audio/mpeg, mpegversion=(int)4")) { 351 386 m_encoderCodecMap.add(AtomString("mpeg"), false); 352 387 m_encoderCodecMap.add(AtomString("mp4a*"), false); 353 388 } 354 389 355 auto opusSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/x-opus");390 auto opusSupported = factories.hasElementForMediaType(ElementFactories::Type::AudioEncoder, "audio/x-opus"); 356 391 if (opusSupported) { 357 392 m_encoderCodecMap.add(AtomString("opus"), false); … … 359 394 } 360 395 361 auto vorbisSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/x-vorbis");396 auto vorbisSupported = factories.hasElementForMediaType(ElementFactories::Type::AudioEncoder, "audio/x-vorbis"); 362 397 if (vorbisSupported) { 363 398 m_encoderCodecMap.add(AtomString("vorbis"), false); … … 365 400 } 366 401 367 Vector<String> av1Encoders Blacklist { "av1enc"_s };368 auto av1EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-av1", true, makeOptional(WTFMove(av1EncodersBlacklist)));402 Vector<String> av1EncodersDisallowedList { "av1enc"_s }; 403 auto av1EncoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoEncoder, "video/x-av1", ElementFactories::CheckHardwareClassifier::Yes, makeOptional(WTFMove(av1EncodersDisallowedList))); 369 404 if (av1EncoderAvailable) { 370 405 m_encoderCodecMap.add(AtomString("av01*"), false); … … 373 408 } 374 409 375 auto vp8EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-vp8", true);410 auto vp8EncoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoEncoder, "video/x-vp8", ElementFactories::CheckHardwareClassifier::Yes); 376 411 if (vp8EncoderAvailable) { 377 412 m_encoderCodecMap.add(AtomString("vp8"), vp8EncoderAvailable.isUsingHardware); … … 380 415 } 381 416 382 auto vp9EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-vp9", true);417 auto vp9EncoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoEncoder, "video/x-vp9", ElementFactories::CheckHardwareClassifier::Yes); 383 418 if (vp9EncoderAvailable) { 384 419 m_encoderCodecMap.add(AtomString("vp9"), vp9EncoderAvailable.isUsingHardware); … … 388 423 } 389 424 390 if ( hasElementForMediaType(m_muxerFactories, "video/webm") && (vp8EncoderAvailable || vp9EncoderAvailable || av1EncoderAvailable))425 if (factories.hasElementForMediaType(ElementFactories::Type::Muxer, "video/webm") && (vp8EncoderAvailable || vp9EncoderAvailable || av1EncoderAvailable)) 391 426 m_encoderMimeTypeSet.add(AtomString("video/webm")); 392 427 393 if ( hasElementForMediaType(m_muxerFactories, "audio/webm")) {428 if (factories.hasElementForMediaType(ElementFactories::Type::Muxer, "audio/webm")) { 394 429 if (opusSupported) 395 430 m_encoderMimeTypeSet.add(AtomString("audio/opus")); … … 397 432 } 398 433 399 if ( hasElementForMediaType(m_muxerFactories, "audio/ogg") && (vorbisSupported || opusSupported))434 if (factories.hasElementForMediaType(ElementFactories::Type::Muxer, "audio/ogg") && (vorbisSupported || opusSupported)) 400 435 m_encoderMimeTypeSet.add(AtomString("audio/ogg")); 401 436 402 auto h264EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", true);437 auto h264EncoderAvailable = factories.hasElementForMediaType(ElementFactories::Type::VideoEncoder, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", ElementFactories::CheckHardwareClassifier::Yes); 403 438 if (h264EncoderAvailable) { 404 439 m_encoderCodecMap.add(AtomString("x-h264"), h264EncoderAvailable.isUsingHardware); … … 407 442 } 408 443 409 if ( hasElementForMediaType(m_muxerFactories, "video/quicktime")) {444 if (factories.hasElementForMediaType(ElementFactories::Type::Muxer, "video/quicktime")) { 410 445 if (opusSupported) 411 446 m_encoderMimeTypeSet.add(AtomString("audio/opus")); … … 422 457 } 423 458 424 bool GStreamerRegistryScanner::isCodecSupported(Configuration configuration, Stringcodec, bool shouldCheckForHardwareUse) const459 bool GStreamerRegistryScanner::isCodecSupported(Configuration configuration, const String& codec, bool shouldCheckForHardwareUse) const 425 460 { 426 461 // If the codec is named like a mimetype (eg: video/avc) remove the "video/" part. 427 462 size_t slashIndex = codec.find('/'); 428 if (slashIndex != WTF::notFound) 429 codec = codec.substring(slashIndex + 1); 463 String codecName = slashIndex != WTF::notFound ? codec.substring(slashIndex + 1) : codec; 430 464 431 465 bool supported = false; 432 if (codec .startsWith("avc1"))433 supported = isAVC1CodecSupported(configuration, codec , shouldCheckForHardwareUse);466 if (codecName.startsWith("avc1")) 467 supported = isAVC1CodecSupported(configuration, codecName, shouldCheckForHardwareUse); 434 468 else { 435 469 auto& codecMap = configuration == Configuration::Decoding ? m_decoderCodecMap : m_encoderCodecMap; 436 470 for (const auto& item : codecMap) { 437 if (!fnmatch(item.key.string().utf8().data(), codec .utf8().data(), 0)) {471 if (!fnmatch(item.key.string().utf8().data(), codecName.utf8().data(), 0)) { 438 472 supported = shouldCheckForHardwareUse ? item.value : true; 439 473 if (supported) … … 444 478 445 479 const char* configLogString = configurationNameForLogging(configuration); 446 GST_LOG("Checked %s %s codec \"%s\" supported %s", shouldCheckForHardwareUse ? "hardware" : "software", configLogString, codec .utf8().data(), boolForPrinting(supported));480 GST_LOG("Checked %s %s codec \"%s\" supported %s", shouldCheckForHardwareUse ? "hardware" : "software", configLogString, codecName.utf8().data(), boolForPrinting(supported)); 447 481 return supported; 448 482 } … … 484 518 bool GStreamerRegistryScanner::areAllCodecsSupported(Configuration configuration, const Vector<String>& codecs, bool shouldCheckForHardwareUse) const 485 519 { 486 for ( Stringcodec : codecs) {520 for (const auto& codec : codecs) { 487 521 if (!isCodecSupported(configuration, codec, shouldCheckForHardwareUse)) 488 522 return false; … … 495 529 { 496 530 auto checkH264Caps = [&](const char* capsString) { 497 bool supported = false; 498 RegistryLookupResult lookupResult; 531 OptionSet<ElementFactories::Type> factoryTypes; 499 532 switch (configuration) { 500 533 case Configuration::Decoding: 501 lookupResult = hasElementForMediaType(m_videoDecoderFactories, capsString, true);534 factoryTypes.add(ElementFactories::Type::VideoDecoder); 502 535 break; 503 536 case Configuration::Encoding: 504 lookupResult = hasElementForMediaType(m_videoEncoderFactories, capsString, true);537 factoryTypes.add(ElementFactories::Type::VideoEncoder); 505 538 break; 506 539 } 507 supported = lookupResult; 508 if (shouldCheckForHardwareUse) 509 supported = lookupResult.isUsingHardware; 540 auto lookupResult = ElementFactories(factoryTypes).hasElementForMediaType(factoryTypes.toSingleValue().value(), capsString, ElementFactories::CheckHardwareClassifier::Yes); 541 bool supported = lookupResult && shouldCheckForHardwareUse ? lookupResult.isUsingHardware : true; 510 542 GST_DEBUG("%s decoding supported for codec %s: %s", shouldCheckForHardwareUse ? "Hardware" : "Software", codec.utf8().data(), boolForPrinting(supported)); 511 543 return supported; … … 590 622 } 591 623 592 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::isConfigurationSupported(Configuration configuration, MediaConfiguration& mediaConfiguration) const624 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::isConfigurationSupported(Configuration configuration, const MediaConfiguration& mediaConfiguration) const 593 625 { 594 626 bool isSupported = false; … … 619 651 } 620 652 621 return GStreamerRegistryScanner::RegistryLookupResult{ isSupported, isUsingHardware };653 return { isSupported, isUsingHardware }; 622 654 } 623 655 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.h
r268590 r270019 28 28 #include <wtf/HashMap.h> 29 29 #include <wtf/HashSet.h> 30 #include <wtf/OptionSet.h> 30 31 #include <wtf/text/AtomString.h> 31 32 #include <wtf/text/AtomStringHash.h> … … 45 46 }; 46 47 47 const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeSet(Configuration) ;48 bool isContainerTypeSupported(Configuration, StringcontainerType) const;48 const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeSet(Configuration) const; 49 bool isContainerTypeSupported(Configuration, const String& containerType) const; 49 50 50 51 struct RegistryLookupResult { 51 bool isSupported ;52 bool isUsingHardware ;52 bool isSupported { false }; 53 bool isUsingHardware { false }; 53 54 54 55 operator bool() const { return isSupported; } … … 57 58 RegistryLookupResult isEncodingSupported(MediaConfiguration& mediaConfiguration) const { return isConfigurationSupported(Configuration::Encoding, mediaConfiguration); } 58 59 59 bool isCodecSupported(Configuration, Stringcodec, bool usingHardware = false) const;60 bool isCodecSupported(Configuration, const String& codec, bool usingHardware = false) const; 60 61 MediaPlayerEnums::SupportsType isContentTypeSupported(Configuration, const ContentType&, const Vector<ContentType>& contentTypesRequiringHardwareSupport) const; 61 62 bool areAllCodecsSupported(Configuration, const Vector<String>& codecs, bool shouldCheckForHardwareUse = false) const; … … 63 64 protected: 64 65 GStreamerRegistryScanner(bool isMediaSource = false); 65 ~GStreamerRegistryScanner() ;66 ~GStreamerRegistryScanner() = default; 66 67 67 void initializeDecoders(); 68 void initializeEncoders(); 68 struct ElementFactories { 69 enum class Type { 70 AudioParser = 1 << 0, 71 AudioDecoder = 1 << 1, 72 VideoParser = 1 << 2, 73 VideoDecoder = 1 << 3, 74 Demuxer = 1 << 4, 75 AudioEncoder = 1 << 5, 76 VideoEncoder = 1 << 6, 77 Muxer = 1 << 7, 78 All = (1 << 8) - 1 79 }; 69 80 70 RegistryLookupResult isConfigurationSupported(Configuration, MediaConfiguration&) const; 81 explicit ElementFactories(OptionSet<Type>); 82 ~ElementFactories(); 71 83 72 enum ElementType { 73 AudioDecoder = 0, 74 VideoDecoder, 75 Demuxer 84 static const char* elementFactoryTypeToString(Type); 85 GList* factory(Type) const; 86 87 enum class CheckHardwareClassifier { No, Yes }; 88 RegistryLookupResult hasElementForMediaType(Type, const char* capsString, CheckHardwareClassifier = CheckHardwareClassifier::No, Optional<Vector<String>> disallowedList = WTF::nullopt) const; 89 90 GList* audioDecoderFactories { nullptr }; 91 GList* audioParserFactories { nullptr }; 92 GList* videoDecoderFactories { nullptr }; 93 GList* videoParserFactories { nullptr }; 94 GList* demuxerFactories { nullptr }; 95 GList* audioEncoderFactories { nullptr }; 96 GList* videoEncoderFactories { nullptr }; 97 GList* muxerFactories { nullptr }; 76 98 }; 77 99 100 void initializeDecoders(const ElementFactories&); 101 void initializeEncoders(const ElementFactories&); 102 103 RegistryLookupResult isConfigurationSupported(Configuration, const MediaConfiguration&) const; 104 78 105 struct GstCapsWebKitMapping { 79 Element Type elementType;106 ElementFactories::Type elementType; 80 107 const char* capsString; 81 108 Vector<AtomString> webkitMimeTypes; 82 109 Vector<AtomString> webkitCodecPatterns; 83 110 }; 84 void fillMimeTypeSetFromCapsMapping(Vector<GstCapsWebKitMapping>&); 85 86 RegistryLookupResult hasElementForMediaType(GList* elementFactories, const char* capsString, bool shouldCheckHardwareClassifier = false, Optional<Vector<String>> blackList = WTF::nullopt) const; 111 void fillMimeTypeSetFromCapsMapping(const ElementFactories&, const Vector<GstCapsWebKitMapping>&); 87 112 88 113 bool isAVC1CodecSupported(Configuration, const String& codec, bool shouldCheckForHardwareUse) const; … … 91 116 const char* configurationNameForLogging(Configuration) const; 92 117 93 bool m_isMediaSource; 94 GList* m_audioDecoderFactories; 95 GList* m_audioParserFactories; 96 GList* m_videoDecoderFactories; 97 GList* m_videoParserFactories; 98 GList* m_demuxerFactories; 99 GList* m_audioEncoderFactories; 100 GList* m_videoEncoderFactories; 101 GList* m_muxerFactories; 118 bool m_isMediaSource { false }; 102 119 HashSet<String, ASCIICaseInsensitiveHash> m_decoderMimeTypeSet; 103 120 HashMap<AtomString, bool> m_decoderCodecMap;
Note: See TracChangeset
for help on using the changeset viewer.