Changeset 268576 in webkit
- Timestamp:
- Oct 16, 2020 1:52:38 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r268574 r268576 1 2020-10-16 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] Encoder probing support for the registry scanner 4 https://bugs.webkit.org/show_bug.cgi?id=217750 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 * platform/glib/media/mediacapabilities-types-expected.txt: Renamed from LayoutTests/platform/gtk/media/mediacapabilities/mediacapabilities-types-expected.txt. 9 1 10 2020-10-16 Diego Pino Garcia <dpino@igalia.com> 2 11 -
trunk/LayoutTests/platform/glib/media/mediacapabilities-types-expected.txt
r268575 r268576 43 43 return navigator.mediaCapabilities.decodingInfo({ type: 'invalid', video: { contentType: 'video/mp4; codecs="avc1"', width: 640, height: 480, bitrate: 1000, framerate: 24 } }); 44 44 } rejected promise with TypeError: Type error. 45 FAIL() => {45 PASS () => { 46 46 return navigator.mediaCapabilities.encodingInfo({ type: 'record' }); 47 } should not throw exception. Threw exception TypeError: navigator.mediaCapabilities.encodingInfo is not a function. (In 'navigator.mediaCapabilities.encodingInfo({ type: 'record' })', 'navigator.mediaCapabilities.encodingInfo' is undefined).48 FAIL() => {47 } rejected promise with TypeError: Type error. 48 PASS () => { 49 49 return navigator.mediaCapabilities.encodingInfo({ type: 'record', audio: { } }); 50 } should not throw exception. Threw exception TypeError: navigator.mediaCapabilities.encodingInfo is not a function. (In 'navigator.mediaCapabilities.encodingInfo({ type: 'record', audio: { } })', 'navigator.mediaCapabilities.encodingInfo' is undefined).50 } rejected promise with TypeError: Member AudioConfiguration.contentType is required and must be an instance of DOMString. 51 51 PASS () => { 52 52 return navigator.mediaCapabilities.decodingInfo({ type: 'record', audio: { } }); -
trunk/Source/WebCore/ChangeLog
r268566 r268576 1 2020-10-16 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] Encoder probing support for the registry scanner 4 https://bugs.webkit.org/show_bug.cgi?id=217750 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 The scanner is now able to probe for platform encoders for the most common formats: avc1, 9 av1, ogg, theora, aac and opus. The muxers for webm and mp4 are also checked. 10 11 No new tests, existing mediacapabilities test cover this change. 12 13 * platform/graphics/gstreamer/GStreamerRegistryScanner.cpp: 14 (WebCore::GStreamerRegistryScanner::GStreamerRegistryScanner): 15 (WebCore::GStreamerRegistryScanner::~GStreamerRegistryScanner): 16 (WebCore::GStreamerRegistryScanner::mimeTypeSet): 17 (WebCore::GStreamerRegistryScanner::isContainerTypeSupported const): 18 (WebCore::GStreamerRegistryScanner::hasElementForMediaType const): 19 (WebCore::GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping): 20 (WebCore::GStreamerRegistryScanner::initializeDecoders): 21 (WebCore::GStreamerRegistryScanner::initializeEncoders): 22 (WebCore::GStreamerRegistryScanner::isCodecSupported const): 23 (WebCore::GStreamerRegistryScanner::isContentTypeSupported const): 24 (WebCore::GStreamerRegistryScanner::areAllCodecsSupported const): 25 (WebCore::GStreamerRegistryScanner::isAVC1CodecSupported const): 26 (WebCore::GStreamerRegistryScanner::configurationNameForLogging const): 27 (WebCore::GStreamerRegistryScanner::isConfigurationSupported const): 28 * platform/graphics/gstreamer/GStreamerRegistryScanner.h: 29 (WebCore::GStreamerRegistryScanner::isDecodingSupported const): 30 (WebCore::GStreamerRegistryScanner::isEncodingSupported const): 31 * platform/graphics/gstreamer/ImageDecoderGStreamer.cpp: 32 (WebCore::ImageDecoderGStreamer::supportsContainerType): 33 (WebCore::ImageDecoderGStreamer::canDecodeType): 34 * platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp: 35 (WebCore::createMediaPlayerEncodingConfigurationGStreamer): 36 * platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.h: 37 * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: 38 (WebCore::MediaPlayerPrivateGStreamer::getSupportedTypes): 39 (WebCore::MediaPlayerPrivateGStreamer::supportsType): 40 * platform/graphics/gstreamer/mse/AppendPipeline.cpp: 41 (WebCore::AppendPipeline::parseDemuxerSrcPadCaps): 42 * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: 43 (WebCore::MediaPlayerPrivateGStreamerMSE::getSupportedTypes): 44 (WebCore::MediaPlayerPrivateGStreamerMSE::supportsType): 45 * platform/mediacapabilities/MediaEngineConfigurationFactory.cpp: 46 (WebCore::factories): 47 1 48 2020-10-15 Keith Rollin <krollin@apple.com> 2 49 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.cpp
r268392 r268576 27 27 #include <gst/pbutils/codec-utils.h> 28 28 #include <wtf/PrintStream.h> 29 #include <wtf/WeakPtr.h> 29 30 30 31 namespace WebCore { … … 49 50 m_demuxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DEMUXER, GST_RANK_MARGINAL); 50 51 51 initialize(); 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(); 52 58 #ifndef GST_DISABLE_GST_DEBUG 53 59 GST_DEBUG("%s registry scanner initialized", m_isMediaSource ? "MSE" : "Regular playback"); 54 for (auto& mimeType : m_mimeTypeSet) 55 GST_DEBUG("Mime-type registered: %s", mimeType.utf8().data()); 56 for (auto& item : m_codecMap) 57 GST_DEBUG("%s codec pattern registered: %s", item.value ? "Hardware" : "Software", item.key.string().utf8().data()); 60 for (auto& mimeType : m_decoderMimeTypeSet) 61 GST_DEBUG("Decoder mime-type registered: %s", mimeType.utf8().data()); 62 for (auto& item : m_decoderCodecMap) 63 GST_DEBUG("%s decoder codec pattern registered: %s", item.value ? "Hardware" : "Software", item.key.string().utf8().data()); 64 for (auto& mimeType : m_encoderMimeTypeSet) 65 GST_DEBUG("Encoder mime-type registered: %s", mimeType.utf8().data()); 66 for (auto& item : m_encoderCodecMap) 67 GST_DEBUG("%s encoder codec pattern registered: %s", item.value ? "Hardware" : "Software", item.key.string().utf8().data()); 58 68 #endif 59 69 } … … 66 76 gst_plugin_feature_list_free(m_videoParserFactories); 67 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) 84 { 85 switch (configuration) { 86 case Configuration::Decoding: 87 return m_decoderMimeTypeSet; 88 case Configuration::Encoding: 89 return m_encoderMimeTypeSet; 90 } 91 ASSERT_NOT_REACHED(); 92 return m_decoderMimeTypeSet; 93 } 94 95 bool GStreamerRegistryScanner::isContainerTypeSupported(Configuration configuration, String containerType) const 96 { 97 switch (configuration) { 98 case Configuration::Decoding: 99 return m_decoderMimeTypeSet.contains(containerType); 100 case Configuration::Encoding: 101 return m_encoderMimeTypeSet.contains(containerType); 102 } 103 ASSERT_NOT_REACHED(); 104 return false; 68 105 } 69 106 70 107 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::hasElementForMediaType(GList* elementFactories, const char* capsString, bool shouldCheckHardwareClassifier, Optional<Vector<String>> blackList) const 71 108 { 109 GstPadDirection padDirection = GST_PAD_SINK; 110 if (elementFactories == m_audioEncoderFactories || elementFactories == m_videoEncoderFactories || elementFactories == m_muxerFactories) 111 padDirection = GST_PAD_SRC; 72 112 GRefPtr<GstCaps> caps = adoptGRef(gst_caps_from_string(capsString)); 73 GList* candidates = gst_element_factory_list_filter(elementFactories, caps.get(), GST_PAD_SINK, false);113 GList* candidates = gst_element_factory_list_filter(elementFactories, caps.get(), padDirection, false); 74 114 bool isSupported = candidates; 75 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(); 76 136 77 137 if (blackList.hasValue() && !blackList->isEmpty()) { … … 85 145 } 86 146 if (!hasValidCandidate) { 87 GST_WARNING("All elements for caps %" GST_PTR_FORMAT " are blacklisted", caps.get());147 GST_WARNING("All %s elements matching caps %" GST_PTR_FORMAT " are blacklisted", elementType, caps.get()); 88 148 isSupported = false; 89 149 shouldCheckHardwareClassifier = false; … … 104 164 105 165 gst_plugin_feature_list_free(candidates); 106 #ifndef GST_DISABLE_GST_DEBUG 107 const char* elementType = ""; 108 if (elementFactories == m_audioParserFactories) 109 elementType = "Audio parser"; 110 else if (elementFactories == m_audioDecoderFactories) 111 elementType = "Audio decoder"; 112 else if (elementFactories == m_videoParserFactories) 113 elementType = "Video parser"; 114 else if (elementFactories == m_videoDecoderFactories) 115 elementType = "Video decoder"; 116 else if (elementFactories == m_demuxerFactories) 117 elementType = "Demuxer"; 118 else 119 ASSERT_NOT_REACHED(); 120 GST_LOG("%s lookup result for caps %" GST_PTR_FORMAT " : isSupported=%s, isUsingHardware=%s", elementType, caps.get(), boolForPrinting(isSupported), boolForPrinting(isUsingHardware)); 121 #endif 166 GST_LOG("Lookup result for %s matching caps %" GST_PTR_FORMAT " : isSupported=%s, isUsingHardware=%s", elementType, caps.get(), boolForPrinting(isSupported), boolForPrinting(isUsingHardware)); 122 167 return GStreamerRegistryScanner::RegistryLookupResult { isSupported, isUsingHardware }; 123 168 } … … 127 172 for (auto& current : mapping) { 128 173 GList* factories; 174 HashSet<String, ASCIICaseInsensitiveHash> mimeTypeSet; 175 HashMap<AtomString, bool> codecMap; 129 176 switch (current.elementType) { 130 177 case Demuxer: 131 178 factories = m_demuxerFactories; 179 codecMap = m_decoderCodecMap; 180 mimeTypeSet = m_decoderMimeTypeSet; 132 181 break; 133 182 case AudioDecoder: 134 183 factories = m_audioDecoderFactories; 184 codecMap = m_decoderCodecMap; 185 mimeTypeSet = m_decoderMimeTypeSet; 135 186 break; 136 187 case VideoDecoder: 137 188 factories = m_videoDecoderFactories; 189 codecMap = m_decoderCodecMap; 190 mimeTypeSet = m_decoderMimeTypeSet; 191 break; 192 case Muxer: 193 factories = m_muxerFactories; 194 codecMap = m_encoderCodecMap; 195 mimeTypeSet = m_encoderMimeTypeSet; 196 break; 197 case AudioEncoder: 198 factories = m_audioEncoderFactories; 199 codecMap = m_encoderCodecMap; 200 mimeTypeSet = m_encoderMimeTypeSet; 201 break; 202 case VideoEncoder: 203 factories = m_videoEncoderFactories; 204 codecMap = m_encoderCodecMap; 205 mimeTypeSet = m_encoderMimeTypeSet; 138 206 break; 139 207 } … … 142 210 if (!current.webkitCodecPatterns.isEmpty()) { 143 211 for (const auto& pattern : current.webkitCodecPatterns) 144 m_codecMap.add(pattern, false);212 codecMap.add(pattern, false); 145 213 } 146 214 if (!current.webkitMimeTypes.isEmpty()) { 147 215 for (const auto& mimeType : current.webkitMimeTypes) 148 m _mimeTypeSet.add(mimeType);216 mimeTypeSet.add(mimeType); 149 217 } else 150 m _mimeTypeSet.add(AtomString(current.capsString));151 } 152 } 153 } 154 155 void GStreamerRegistryScanner::initialize ()218 mimeTypeSet.add(AtomString(current.capsString)); 219 } 220 } 221 } 222 223 void GStreamerRegistryScanner::initializeDecoders() 156 224 { 157 225 if (hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)4")) { 158 m_ mimeTypeSet.add(AtomString("audio/aac"));159 m_ mimeTypeSet.add(AtomString("audio/mp4"));160 m_ mimeTypeSet.add(AtomString("audio/x-m4a"));161 m_ codecMap.add(AtomString("mpeg"), false);162 m_ codecMap.add(AtomString("mp4a*"), false);226 m_decoderMimeTypeSet.add(AtomString("audio/aac")); 227 m_decoderMimeTypeSet.add(AtomString("audio/mp4")); 228 m_decoderMimeTypeSet.add(AtomString("audio/x-m4a")); 229 m_decoderCodecMap.add(AtomString("mpeg"), false); 230 m_decoderCodecMap.add(AtomString("mp4a*"), false); 163 231 } 164 232 165 233 auto opusSupported = hasElementForMediaType(m_audioDecoderFactories, "audio/x-opus"); 166 234 if (opusSupported && (!m_isMediaSource || hasElementForMediaType(m_audioParserFactories, "audio/x-opus"))) { 167 m_ mimeTypeSet.add(AtomString("audio/opus"));168 m_ codecMap.add(AtomString("opus"), false);169 m_ codecMap.add(AtomString("x-opus"), false);235 m_decoderMimeTypeSet.add(AtomString("audio/opus")); 236 m_decoderCodecMap.add(AtomString("opus"), false); 237 m_decoderCodecMap.add(AtomString("x-opus"), false); 170 238 } 171 239 172 240 auto vorbisSupported = hasElementForMediaType(m_audioDecoderFactories, "audio/x-vorbis"); 173 241 if (vorbisSupported && (!m_isMediaSource || hasElementForMediaType(m_audioParserFactories, "audio/x-vorbis"))) { 174 m_ codecMap.add(AtomString("vorbis"), false);175 m_ codecMap.add(AtomString("x-vorbis"), false);242 m_decoderCodecMap.add(AtomString("vorbis"), false); 243 m_decoderCodecMap.add(AtomString("x-vorbis"), false); 176 244 } 177 245 … … 182 250 183 251 if (vp8DecoderAvailable || vp9DecoderAvailable) 184 m_ mimeTypeSet.add(AtomString("video/webm"));252 m_decoderMimeTypeSet.add(AtomString("video/webm")); 185 253 186 254 if (vp8DecoderAvailable) { 187 m_ codecMap.add(AtomString("vp8"), vp8DecoderAvailable.isUsingHardware);188 m_ codecMap.add(AtomString("x-vp8"), vp8DecoderAvailable.isUsingHardware);189 m_ codecMap.add(AtomString("vp8.0"), vp8DecoderAvailable.isUsingHardware);255 m_decoderCodecMap.add(AtomString("vp8"), vp8DecoderAvailable.isUsingHardware); 256 m_decoderCodecMap.add(AtomString("x-vp8"), vp8DecoderAvailable.isUsingHardware); 257 m_decoderCodecMap.add(AtomString("vp8.0"), vp8DecoderAvailable.isUsingHardware); 190 258 } 191 259 if (vp9DecoderAvailable) { 192 m_ codecMap.add(AtomString("vp9"), vp9DecoderAvailable.isUsingHardware);193 m_ codecMap.add(AtomString("x-vp9"), vp9DecoderAvailable.isUsingHardware);194 m_ codecMap.add(AtomString("vp9.0"), vp9DecoderAvailable.isUsingHardware);195 m_ codecMap.add(AtomString("vp09*"), vp9DecoderAvailable.isUsingHardware);260 m_decoderCodecMap.add(AtomString("vp9"), vp9DecoderAvailable.isUsingHardware); 261 m_decoderCodecMap.add(AtomString("x-vp9"), vp9DecoderAvailable.isUsingHardware); 262 m_decoderCodecMap.add(AtomString("vp9.0"), vp9DecoderAvailable.isUsingHardware); 263 m_decoderCodecMap.add(AtomString("vp09*"), vp9DecoderAvailable.isUsingHardware); 196 264 } 197 265 if (opusSupported) 198 m_ mimeTypeSet.add(AtomString("audio/webm"));266 m_decoderMimeTypeSet.add(AtomString("audio/webm")); 199 267 } 200 268 201 269 auto h264DecoderAvailable = hasElementForMediaType(m_videoDecoderFactories, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", true); 202 270 if (h264DecoderAvailable && (!m_isMediaSource || hasElementForMediaType(m_videoParserFactories, "video/x-h264"))) { 203 m_ mimeTypeSet.add(AtomString("video/mp4"));204 m_ mimeTypeSet.add(AtomString("video/x-m4v"));205 m_ codecMap.add(AtomString("x-h264"), h264DecoderAvailable.isUsingHardware);206 m_ codecMap.add(AtomString("avc*"), h264DecoderAvailable.isUsingHardware);207 m_ codecMap.add(AtomString("mp4v*"), h264DecoderAvailable.isUsingHardware);271 m_decoderMimeTypeSet.add(AtomString("video/mp4")); 272 m_decoderMimeTypeSet.add(AtomString("video/x-m4v")); 273 m_decoderCodecMap.add(AtomString("x-h264"), h264DecoderAvailable.isUsingHardware); 274 m_decoderCodecMap.add(AtomString("avc*"), h264DecoderAvailable.isUsingHardware); 275 m_decoderCodecMap.add(AtomString("mp4v*"), h264DecoderAvailable.isUsingHardware); 208 276 } 209 277 210 278 Vector<String> av1DecodersBlacklist { "av1dec"_s }; 211 if ((matroskaSupported || isContainerTypeSupported( "video/mp4")) && hasElementForMediaType(m_videoDecoderFactories, "video/x-av1", false, makeOptional(WTFMove(av1DecodersBlacklist)))) {212 m_ codecMap.add(AtomString("av01*"), false);213 m_ codecMap.add(AtomString("av1"), false);214 m_ codecMap.add(AtomString("x-av1"), false);279 if ((matroskaSupported || isContainerTypeSupported(Configuration::Decoding, "video/mp4")) && hasElementForMediaType(m_videoDecoderFactories, "video/x-av1", false, makeOptional(WTFMove(av1DecodersBlacklist)))) { 280 m_decoderCodecMap.add(AtomString("av01*"), false); 281 m_decoderCodecMap.add(AtomString("av1"), false); 282 m_decoderCodecMap.add(AtomString("x-av1"), false); 215 283 } 216 284 … … 249 317 250 318 if (hasElementForMediaType(m_demuxerFactories, "application/ogg")) { 251 m_ mimeTypeSet.add(AtomString("application/ogg"));319 m_decoderMimeTypeSet.add(AtomString("application/ogg")); 252 320 253 321 if (vorbisSupported) { 254 m_ mimeTypeSet.add(AtomString("audio/ogg"));255 m_ mimeTypeSet.add(AtomString("audio/x-vorbis+ogg"));322 m_decoderMimeTypeSet.add(AtomString("audio/ogg")); 323 m_decoderMimeTypeSet.add(AtomString("audio/x-vorbis+ogg")); 256 324 } 257 325 258 326 if (hasElementForMediaType(m_audioDecoderFactories, "audio/x-speex")) { 259 m_ mimeTypeSet.add(AtomString("audio/ogg"));260 m_ codecMap.add(AtomString("speex"), false);327 m_decoderMimeTypeSet.add(AtomString("audio/ogg")); 328 m_decoderCodecMap.add(AtomString("speex"), false); 261 329 } 262 330 263 331 if (hasElementForMediaType(m_videoDecoderFactories, "video/x-theora")) { 264 m_ mimeTypeSet.add(AtomString("video/ogg"));265 m_ codecMap.add(AtomString("theora"), false);332 m_decoderMimeTypeSet.add(AtomString("video/ogg")); 333 m_decoderCodecMap.add(AtomString("theora"), false); 266 334 } 267 335 } … … 270 338 if (hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)1, layer=(int)[1, 3]")) { 271 339 audioMpegSupported = true; 272 m_ mimeTypeSet.add(AtomString("audio/mp1"));273 m_ mimeTypeSet.add(AtomString("audio/mp3"));274 m_ mimeTypeSet.add(AtomString("audio/x-mp3"));275 m_ codecMap.add(AtomString("audio/mp3"), false);276 m_ codecMap.add(AtomString("mp3"), false);340 m_decoderMimeTypeSet.add(AtomString("audio/mp1")); 341 m_decoderMimeTypeSet.add(AtomString("audio/mp3")); 342 m_decoderMimeTypeSet.add(AtomString("audio/x-mp3")); 343 m_decoderCodecMap.add(AtomString("audio/mp3"), false); 344 m_decoderCodecMap.add(AtomString("mp3"), false); 277 345 } 278 346 279 347 if (hasElementForMediaType(m_audioDecoderFactories, "audio/mpeg, mpegversion=(int)2")) { 280 348 audioMpegSupported = true; 281 m_ mimeTypeSet.add(AtomString("audio/mp2"));282 } 283 284 audioMpegSupported |= isContainerTypeSupported( "audio/mp4");349 m_decoderMimeTypeSet.add(AtomString("audio/mp2")); 350 } 351 352 audioMpegSupported |= isContainerTypeSupported(Configuration::Decoding, "audio/mp4"); 285 353 if (audioMpegSupported) { 286 m_ mimeTypeSet.add(AtomString("audio/mpeg"));287 m_ mimeTypeSet.add(AtomString("audio/x-mpeg"));354 m_decoderMimeTypeSet.add(AtomString("audio/mpeg")); 355 m_decoderMimeTypeSet.add(AtomString("audio/x-mpeg")); 288 356 } 289 357 290 358 if (matroskaSupported) { 291 m_ mimeTypeSet.add(AtomString("video/x-matroska"));359 m_decoderMimeTypeSet.add(AtomString("video/x-matroska")); 292 360 293 361 if (hasElementForMediaType(m_videoDecoderFactories, "video/x-vp10")) 294 m_mimeTypeSet.add(AtomString("video/webm")); 295 } 296 } 297 298 bool GStreamerRegistryScanner::isCodecSupported(String codec, bool shouldCheckForHardwareUse) const 362 m_decoderMimeTypeSet.add(AtomString("video/webm")); 363 } 364 } 365 366 void GStreamerRegistryScanner::initializeEncoders() 367 { 368 // MSE is about playback, which means decoding. No need to check for encoders then. 369 if (m_isMediaSource) 370 return; 371 372 auto aacSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/mpeg, mpegversion=(int)4"); 373 if (hasElementForMediaType(m_audioEncoderFactories, "audio/mpeg, mpegversion=(int)4")) { 374 m_encoderCodecMap.add(AtomString("mpeg"), false); 375 m_encoderCodecMap.add(AtomString("mp4a*"), false); 376 } 377 378 auto opusSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/x-opus"); 379 if (opusSupported) { 380 m_encoderCodecMap.add(AtomString("opus"), false); 381 m_encoderCodecMap.add(AtomString("x-opus"), false); 382 } 383 384 auto vorbisSupported = hasElementForMediaType(m_audioEncoderFactories, "audio/x-vorbis"); 385 if (vorbisSupported) { 386 m_encoderCodecMap.add(AtomString("vorbis"), false); 387 m_encoderCodecMap.add(AtomString("x-vorbis"), false); 388 } 389 390 Vector<String> av1EncodersBlacklist { "av1enc"_s }; 391 auto av1EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-av1", true, makeOptional(WTFMove(av1EncodersBlacklist))); 392 if (av1EncoderAvailable) { 393 m_encoderCodecMap.add(AtomString("av01*"), false); 394 m_encoderCodecMap.add(AtomString("av1"), false); 395 m_encoderCodecMap.add(AtomString("x-av1"), false); 396 } 397 398 auto vp8EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-vp8", true); 399 if (vp8EncoderAvailable) { 400 m_encoderCodecMap.add(AtomString("vp8"), vp8EncoderAvailable.isUsingHardware); 401 m_encoderCodecMap.add(AtomString("x-vp8"), vp8EncoderAvailable.isUsingHardware); 402 m_encoderCodecMap.add(AtomString("vp8.0"), vp8EncoderAvailable.isUsingHardware); 403 } 404 405 auto vp9EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-vp9", true); 406 if (vp9EncoderAvailable) { 407 m_encoderCodecMap.add(AtomString("vp9"), vp9EncoderAvailable.isUsingHardware); 408 m_encoderCodecMap.add(AtomString("x-vp9"), vp9EncoderAvailable.isUsingHardware); 409 m_encoderCodecMap.add(AtomString("vp9.0"), vp9EncoderAvailable.isUsingHardware); 410 m_encoderCodecMap.add(AtomString("vp09*"), vp9EncoderAvailable.isUsingHardware); 411 } 412 413 if (hasElementForMediaType(m_muxerFactories, "video/webm") && (vp8EncoderAvailable || vp9EncoderAvailable || av1EncoderAvailable)) 414 m_encoderMimeTypeSet.add(AtomString("video/webm")); 415 416 if (hasElementForMediaType(m_muxerFactories, "audio/webm")) { 417 if (opusSupported) 418 m_encoderMimeTypeSet.add(AtomString("audio/opus")); 419 m_encoderMimeTypeSet.add(AtomString("audio/webm")); 420 } 421 422 if (hasElementForMediaType(m_muxerFactories, "audio/ogg") && (vorbisSupported || opusSupported)) 423 m_encoderMimeTypeSet.add(AtomString("audio/ogg")); 424 425 auto h264EncoderAvailable = hasElementForMediaType(m_videoEncoderFactories, "video/x-h264, profile=(string){ constrained-baseline, baseline, high }", true); 426 if (h264EncoderAvailable) { 427 m_encoderCodecMap.add(AtomString("x-h264"), h264EncoderAvailable.isUsingHardware); 428 m_encoderCodecMap.add(AtomString("avc*"), h264EncoderAvailable.isUsingHardware); 429 m_encoderCodecMap.add(AtomString("mp4v*"), h264EncoderAvailable.isUsingHardware); 430 } 431 432 if (hasElementForMediaType(m_muxerFactories, "video/quicktime")) { 433 if (opusSupported) 434 m_encoderMimeTypeSet.add(AtomString("audio/opus")); 435 if (aacSupported) { 436 m_encoderMimeTypeSet.add(AtomString("audio/aac")); 437 m_encoderMimeTypeSet.add(AtomString("audio/mp4")); 438 m_encoderMimeTypeSet.add(AtomString("audio/x-m4a")); 439 } 440 if (h264EncoderAvailable) { 441 m_encoderMimeTypeSet.add(AtomString("video/mp4")); 442 m_encoderMimeTypeSet.add(AtomString("video/x-m4v")); 443 } 444 } 445 } 446 447 bool GStreamerRegistryScanner::isCodecSupported(Configuration configuration, String codec, bool shouldCheckForHardwareUse) const 299 448 { 300 449 // If the codec is named like a mimetype (eg: video/avc) remove the "video/" part. … … 305 454 bool supported = false; 306 455 if (codec.startsWith("avc1")) 307 supported = isAVC1CodecSupported(co dec, shouldCheckForHardwareUse);456 supported = isAVC1CodecSupported(configuration, codec, shouldCheckForHardwareUse); 308 457 else { 309 for (const auto& item : m_codecMap) { 458 auto& codecMap = configuration == Configuration::Decoding ? m_decoderCodecMap : m_encoderCodecMap; 459 for (const auto& item : codecMap) { 310 460 if (!fnmatch(item.key.string().utf8().data(), codec.utf8().data(), 0)) { 311 461 supported = shouldCheckForHardwareUse ? item.value : true; … … 316 466 } 317 467 318 GST_LOG("Checked %s codec \"%s\" supported %s", shouldCheckForHardwareUse ? "hardware" : "software", codec.utf8().data(), boolForPrinting(supported)); 468 const char* configLogString = configurationNameForLogging(configuration); 469 GST_LOG("Checked %s %s codec \"%s\" supported %s", shouldCheckForHardwareUse ? "hardware" : "software", configLogString, codec.utf8().data(), boolForPrinting(supported)); 319 470 return supported; 320 471 } 321 472 322 MediaPlayerEnums::SupportsType GStreamerRegistryScanner::isContentTypeSupported( const ContentType& contentType, const Vector<ContentType>& contentTypesRequiringHardwareSupport) const473 MediaPlayerEnums::SupportsType GStreamerRegistryScanner::isContentTypeSupported(Configuration configuration, const ContentType& contentType, const Vector<ContentType>& contentTypesRequiringHardwareSupport) const 323 474 { 324 475 using SupportsType = MediaPlayerEnums::SupportsType; 325 476 326 const auto& containerType = contentType.containerType() ;327 if (!isContainerTypeSupported(con tainerType))477 const auto& containerType = contentType.containerType().convertToASCIILowercase(); 478 if (!isContainerTypeSupported(configuration, containerType)) 328 479 return SupportsType::IsNotSupported; 329 480 … … 334 485 return SupportsType::MayBeSupported; 335 486 336 for (const auto& codec : codecs) { 487 for (const auto& item : codecs) { 488 auto codec = item.convertToASCIILowercase(); 337 489 bool requiresHardwareSupport = contentTypesRequiringHardwareSupport 338 490 .findMatching([containerType, codec](auto& hardwareContentType) -> bool { … … 347 499 }) != notFound; 348 500 }) != notFound; 349 if (!isCodecSupported(co dec, requiresHardwareSupport))501 if (!isCodecSupported(configuration, codec, requiresHardwareSupport)) 350 502 return SupportsType::IsNotSupported; 351 503 } … … 353 505 } 354 506 355 bool GStreamerRegistryScanner::areAllCodecsSupported( const Vector<String>& codecs, bool shouldCheckForHardwareUse) const507 bool GStreamerRegistryScanner::areAllCodecsSupported(Configuration configuration, const Vector<String>& codecs, bool shouldCheckForHardwareUse) const 356 508 { 357 509 for (String codec : codecs) { 358 if (!isCodecSupported(co dec, shouldCheckForHardwareUse))510 if (!isCodecSupported(configuration, codec, shouldCheckForHardwareUse)) 359 511 return false; 360 512 } … … 363 515 } 364 516 365 bool GStreamerRegistryScanner::isAVC1CodecSupported( const String& codec, bool shouldCheckForHardwareUse) const517 bool GStreamerRegistryScanner::isAVC1CodecSupported(Configuration configuration, const String& codec, bool shouldCheckForHardwareUse) const 366 518 { 367 519 auto checkH264Caps = [&](const char* capsString) { 368 520 bool supported = false; 369 auto lookupResult = hasElementForMediaType(m_videoDecoderFactories, capsString, true); 521 RegistryLookupResult lookupResult; 522 switch (configuration) { 523 case Configuration::Decoding: 524 lookupResult = hasElementForMediaType(m_videoDecoderFactories, capsString, true); 525 break; 526 case Configuration::Encoding: 527 lookupResult = hasElementForMediaType(m_videoEncoderFactories, capsString, true); 528 break; 529 } 370 530 supported = lookupResult; 371 531 if (shouldCheckForHardwareUse) … … 438 598 } 439 599 440 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::isDecodingSupported(MediaConfiguration& configuration) const 600 const char* GStreamerRegistryScanner::configurationNameForLogging(Configuration configuration) const 601 { 602 const char* configLogString = ""; 603 604 switch (configuration) { 605 case Configuration::Encoding: 606 configLogString = "encoding"; 607 break; 608 case Configuration::Decoding: 609 configLogString = "decoding"; 610 break; 611 } 612 return configLogString; 613 } 614 615 GStreamerRegistryScanner::RegistryLookupResult GStreamerRegistryScanner::isConfigurationSupported(Configuration configuration, MediaConfiguration& mediaConfiguration) const 441 616 { 442 617 bool isSupported = false; 443 618 bool isUsingHardware = false; 444 445 if (configuration.video) { 446 auto& videoConfiguration = configuration.video.value(); 447 GST_DEBUG("Checking support for video configuration: \"%s\" size: %ux%u bitrate: %" G_GUINT64_FORMAT " framerate: %f", 619 const char* configLogString = configurationNameForLogging(configuration); 620 621 if (mediaConfiguration.video) { 622 auto& videoConfiguration = mediaConfiguration.video.value(); 623 GST_DEBUG("Checking %s support for video configuration: \"%s\" size: %ux%u bitrate: %" G_GUINT64_FORMAT " framerate: %f", configLogString, 448 624 videoConfiguration.contentType.utf8().data(), 449 625 videoConfiguration.width, videoConfiguration.height, … … 451 627 452 628 auto contentType = ContentType(videoConfiguration.contentType); 453 isSupported = isContainerTypeSupported(con tentType.containerType());629 isSupported = isContainerTypeSupported(configuration, contentType.containerType()); 454 630 auto codecs = contentType.codecs(); 455 631 if (!codecs.isEmpty()) 456 isUsingHardware = areAllCodecsSupported(co decs, true);457 } 458 459 if ( configuration.audio) {460 auto& audioConfiguration = configuration.audio.value();461 GST_DEBUG("Checking support for audio configuration: \"%s\" %s channels, bitrate: %" G_GUINT64_FORMAT " samplerate: %u",632 isUsingHardware = areAllCodecsSupported(configuration, codecs, true); 633 } 634 635 if (mediaConfiguration.audio) { 636 auto& audioConfiguration = mediaConfiguration.audio.value(); 637 GST_DEBUG("Checking %s support for audio configuration: \"%s\" %s channels, bitrate: %" G_GUINT64_FORMAT " samplerate: %u", configLogString, 462 638 audioConfiguration.contentType.utf8().data(), audioConfiguration.channels.utf8().data(), 463 639 audioConfiguration.bitrate, audioConfiguration.samplerate); 464 640 auto contentType = ContentType(audioConfiguration.contentType); 465 isSupported = isContainerTypeSupported(con tentType.containerType());641 isSupported = isContainerTypeSupported(configuration, contentType.containerType()); 466 642 } 467 643 -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerRegistryScanner.h
r264162 r268576 40 40 static GStreamerRegistryScanner& singleton(); 41 41 42 HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeSet() { return m_mimeTypeSet; } 42 enum Configuration { 43 Decoding = 0, 44 Encoding 45 }; 43 46 44 bool isContainerTypeSupported(String containerType) const { return m_mimeTypeSet.contains(containerType); } 47 const HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeSet(Configuration); 48 bool isContainerTypeSupported(Configuration, String containerType) const; 45 49 46 50 struct RegistryLookupResult { … … 50 54 operator bool() const { return isSupported; } 51 55 }; 52 RegistryLookupResult isDecodingSupported(MediaConfiguration&) const; 56 RegistryLookupResult isDecodingSupported(MediaConfiguration& mediaConfiguration) const { return isConfigurationSupported(Configuration::Decoding, mediaConfiguration); }; 57 RegistryLookupResult isEncodingSupported(MediaConfiguration& mediaConfiguration) const { return isConfigurationSupported(Configuration::Encoding, mediaConfiguration); } 53 58 54 bool isCodecSupported( String codec, bool usingHardware = false) const;55 MediaPlayerEnums::SupportsType isContentTypeSupported( const ContentType&, const Vector<ContentType>& contentTypesRequiringHardwareSupport) const;56 bool areAllCodecsSupported( const Vector<String>& codecs, bool shouldCheckForHardwareUse = false) const;59 bool isCodecSupported(Configuration, String codec, bool usingHardware = false) const; 60 MediaPlayerEnums::SupportsType isContentTypeSupported(Configuration, const ContentType&, const Vector<ContentType>& contentTypesRequiringHardwareSupport) const; 61 bool areAllCodecsSupported(Configuration, const Vector<String>& codecs, bool shouldCheckForHardwareUse = false) const; 57 62 58 63 protected: … … 60 65 ~GStreamerRegistryScanner(); 61 66 62 void initialize(); 67 void initializeDecoders(); 68 void initializeEncoders(); 69 70 RegistryLookupResult isConfigurationSupported(Configuration, MediaConfiguration&) const; 63 71 64 72 enum ElementType { 65 73 AudioDecoder = 0, 66 74 VideoDecoder, 67 Demuxer 75 Demuxer, 76 AudioEncoder, 77 VideoEncoder, 78 Muxer 68 79 }; 69 80 struct GstCapsWebKitMapping { … … 77 88 RegistryLookupResult hasElementForMediaType(GList* elementFactories, const char* capsString, bool shouldCheckHardwareClassifier = false, Optional<Vector<String>> blackList = WTF::nullopt) const; 78 89 79 bool isAVC1CodecSupported( const String& codec, bool shouldCheckForHardwareUse) const;90 bool isAVC1CodecSupported(Configuration, const String& codec, bool shouldCheckForHardwareUse) const; 80 91 81 92 private: 93 const char* configurationNameForLogging(Configuration) const; 94 82 95 bool m_isMediaSource; 83 96 GList* m_audioDecoderFactories; … … 86 99 GList* m_videoParserFactories; 87 100 GList* m_demuxerFactories; 88 HashSet<String, ASCIICaseInsensitiveHash> m_mimeTypeSet; 89 HashMap<AtomString, bool> m_codecMap; 101 GList* m_audioEncoderFactories; 102 GList* m_videoEncoderFactories; 103 GList* m_muxerFactories; 104 HashSet<String, ASCIICaseInsensitiveHash> m_decoderMimeTypeSet; 105 HashMap<AtomString, bool> m_decoderCodecMap; 106 HashSet<String, ASCIICaseInsensitiveHash> m_encoderMimeTypeSet; 107 HashMap<AtomString, bool> m_encoderCodecMap; 90 108 }; 91 109 -
trunk/Source/WebCore/platform/graphics/gstreamer/ImageDecoderGStreamer.cpp
r264595 r268576 99 99 bool ImageDecoderGStreamer::supportsContainerType(const String& type) 100 100 { 101 return GStreamerRegistryScanner::singleton().isContainerTypeSupported( type);101 return GStreamerRegistryScanner::singleton().isContainerTypeSupported(GStreamerRegistryScanner::Configuration::Decoding, type); 102 102 } 103 103 … … 107 107 return false; 108 108 109 return GStreamerRegistryScanner::singleton().isContainerTypeSupported( mimeType);109 return GStreamerRegistryScanner::singleton().isContainerTypeSupported(GStreamerRegistryScanner::Configuration::Decoding, mimeType); 110 110 } 111 111 -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp
r243014 r268576 33 33 #include "GStreamerRegistryScanner.h" 34 34 #include "MediaCapabilitiesDecodingInfo.h" 35 #include "MediaCapabilitiesEncodingInfo.h" 35 36 #include "MediaDecodingConfiguration.h" 37 #include "MediaEncodingConfiguration.h" 36 38 #include "MediaPlayer.h" 37 39 #include <wtf/Function.h> … … 64 66 } 65 67 68 void createMediaPlayerEncodingConfigurationGStreamer(MediaEncodingConfiguration&& configuration, WTF::Function<void(MediaCapabilitiesEncodingInfo&&)>&& callback) 69 { 70 auto& scanner = GStreamerRegistryScanner::singleton(); 71 auto lookupResult = scanner.isEncodingSupported(configuration); 72 MediaCapabilitiesEncodingInfo info; 73 info.supported = lookupResult.isSupported; 74 info.powerEfficient = lookupResult.isUsingHardware; 75 info.supportedConfiguration = WTFMove(configuration); 76 77 callback(WTFMove(info)); 78 } 66 79 } 67 80 #endif -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.h
r243014 r268576 35 35 36 36 struct MediaCapabilitiesDecodingInfo; 37 struct MediaCapabilitiesEncodingInfo; 37 38 struct MediaDecodingConfiguration; 39 struct MediaEncodingConfiguration; 38 40 39 41 extern void createMediaPlayerDecodingConfigurationGStreamer(MediaDecodingConfiguration&&, WTF::Function<void(MediaCapabilitiesDecodingInfo&&)>&&); 40 42 extern void createMediaPlayerEncodingConfigurationGStreamer(MediaEncodingConfiguration&&, WTF::Function<void(MediaCapabilitiesEncodingInfo&&)>&&); 41 43 } 42 44 -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
r268453 r268576 2664 2664 { 2665 2665 auto& gstRegistryScanner = GStreamerRegistryScanner::singleton(); 2666 types = gstRegistryScanner.mimeTypeSet( );2666 types = gstRegistryScanner.mimeTypeSet(GStreamerRegistryScanner::Configuration::Decoding); 2667 2667 } 2668 2668 … … 2686 2686 GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data()); 2687 2687 auto& gstRegistryScanner = GStreamerRegistryScanner::singleton(); 2688 result = gstRegistryScanner.isContentTypeSupported( parameters.type, parameters.contentTypesRequiringHardwareSupport);2688 result = gstRegistryScanner.isContentTypeSupported(GStreamerRegistryScanner::Configuration::Decoding, parameters.type, parameters.contentTypesRequiringHardwareSupport); 2689 2689 2690 2690 auto finalResult = extendedSupportsType(parameters, result); -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp
r266820 r268576 398 398 const char* originalMediaType = capsMediaType(m_demuxerSrcPadCaps.get()); 399 399 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 400 if (!gstRegistryScanner.isCodecSupported( originalMediaType)) {400 if (!gstRegistryScanner.isCodecSupported(GStreamerRegistryScanner::Configuration::Decoding, originalMediaType)) { 401 401 m_presentationSize = WebCore::FloatSize(); 402 402 m_streamType = WebCore::MediaSourceStreamTypeGStreamer::Invalid; -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp
r264392 r268576 712 712 { 713 713 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 714 types = gstRegistryScanner.mimeTypeSet( );714 types = gstRegistryScanner.mimeTypeSet(GStreamerRegistryScanner::Configuration::Decoding); 715 715 } 716 716 … … 732 732 GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data()); 733 733 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 734 result = gstRegistryScanner.isContentTypeSupported( parameters.type, parameters.contentTypesRequiringHardwareSupport);734 result = gstRegistryScanner.isContentTypeSupported(GStreamerRegistryScanner::Configuration::Decoding, parameters.type, parameters.contentTypesRequiringHardwareSupport); 735 735 736 736 auto finalResult = extendedSupportsType(parameters, result); -
trunk/Source/WebCore/platform/mediacapabilities/MediaEngineConfigurationFactory.cpp
r245636 r268576 67 67 #endif 68 68 #if USE(GSTREAMER) 69 { &createMediaPlayerDecodingConfigurationGStreamer, nullptr },69 { &createMediaPlayerDecodingConfigurationGStreamer, &createMediaPlayerEncodingConfigurationGStreamer }, 70 70 #endif 71 71 }));
Note: See TracChangeset
for help on using the changeset viewer.