Changeset 241585 in webkit
- Timestamp:
- Feb 15, 2019 6:24:21 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r241567 r241585 1 2019-02-15 Philippe Normand <pnormand@igalia.com> 2 3 [GStreamer] Decoding media-capabilities configuration initial support 4 https://bugs.webkit.org/show_bug.cgi?id=191191 5 6 Reviewed by Xabier Rodriguez-Calvar. 7 8 This patch enables basic platform probing for GStreamer decoders, 9 optionally using Hardware decoding capabilities. The previous code 10 for decoders/demuxers probing partially duplicated between the MSE 11 player and its parent class was moved to a new module called 12 GStreamerRegistryScanner. There is one instance of it for the MSE player 13 and one for the parent class. 14 15 The scanner can check for the presence of the GstElement Hardware 16 metadata classifier in decoders and thus advise the 17 MediaEngineConfigurationFactoryGStreamer that hardware decoding is 18 supported or not. This is only a first step though. The scanner 19 should also probably attempt a NULL->READY transition on decoders 20 to validate specific input caps are supported. As this might 21 require changes in GStreamer, this part of the patch wasn't 22 included. 23 24 This patch is covered by the existing media tests. 25 26 * platform/GStreamer.cmake: New files. 27 * platform/graphics/MediaPlayer.cpp: Add support for converting 28 SupportsType enum to string. 29 (WebCore::convertEnumerationToString): 30 * platform/graphics/MediaPlayer.h: Ditto. 31 * platform/graphics/MediaPlayerEnums.h: Ditto. 32 * platform/graphics/gstreamer/GStreamerCommon.cpp: Move 33 gstRegistryHasElementForMediaType to GStreamerRegistryScanner. 34 * platform/graphics/gstreamer/GStreamerCommon.h: Ditto. 35 * platform/graphics/gstreamer/GStreamerRegistryScanner.cpp: Added. 36 (WebCore::GStreamerRegistryScanner::singleton): 37 (WebCore::GStreamerRegistryScanner::GStreamerRegistryScanner): Initialize 38 supported mime-types and codecs from the GStreamer registry. 39 (WebCore::GStreamerRegistryScanner::~GStreamerRegistryScanner): Free the element factories. 40 (WebCore::GStreamerRegistryScanner::gstRegistryHasElementForMediaType): 41 Check the input caps are supported, optionally using hardware 42 device. 43 (WebCore::GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping): 44 Moved from MediaPlayerPrivateGStreamer{,MSE}. 45 (WebCore::GStreamerRegistryScanner::initialize): Ditto. 46 (WebCore::GStreamerRegistryScanner::supportsCodec const): Ditto. 47 (WebCore::GStreamerRegistryScanner::supportsAllCodecs const): Ditto. 48 (WebCore::GStreamerRegistryScanner::isDecodingSupported const): Check 49 the given configuration is supported. For now hardware support is 50 checked for video configurations only as it is quite uncommon 51 anyway to have hardware-enabled audio decoders. 52 * platform/graphics/gstreamer/GStreamerRegistryScanner.h: Added. 53 (WebCore::GStreamerRegistryScanner::mimeTypeSet): 54 (WebCore::GStreamerRegistryScanner::supportsContainerType const): 55 (WebCore::GStreamerRegistryScanner::RegistryLookupResult::operator bool const): 56 * platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp: Added. 57 (WebCore::createMediaPlayerDecodingConfigurationGStreamer): 58 * platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.h: Added. 59 * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: 60 Rely on new GStreamerRegistryScanner and add some debugging macros. 61 (WebCore::MediaPlayerPrivateGStreamer::getSupportedTypes): 62 (WebCore::MediaPlayerPrivateGStreamer::supportsType): 63 * platform/graphics/gstreamer/mse/AppendPipeline.cpp: Ditto. Also 64 plug qtdemux for AAC containers, this is an explicit consequence 65 of finer-grained codecs probing. 66 (WebCore::AppendPipeline::AppendPipeline): 67 (WebCore::AppendPipeline::parseDemuxerSrcPadCaps): 68 * platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.cpp: Added. 69 (WebCore::GStreamerRegistryScannerMSE::singleton): 70 (WebCore::GStreamerRegistryScannerMSE::GStreamerRegistryScannerMSE): 71 * platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.h: Added. 72 * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp: 73 Rely on new GStreamerRegistryScanner and add some debugging macros. 74 (WebCore::MediaPlayerPrivateGStreamerMSE::getSupportedTypes): 75 (WebCore::MediaPlayerPrivateGStreamerMSE::supportsType): 76 * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h: 77 * platform/mediacapabilities/MediaEngineConfigurationFactory.cpp: 78 (WebCore::factories): GStreamer support. 79 1 80 2019-02-14 Joseph Pecoraro <pecoraro@apple.com> 2 81 -
trunk/Source/WebCore/platform/GStreamer.cmake
r238159 r241585 11 11 platform/graphics/gstreamer/GStreamerCommon.cpp 12 12 platform/graphics/gstreamer/GstAllocatorFastMalloc.cpp 13 platform/graphics/gstreamer/GStreamerRegistryScanner.cpp 13 14 platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp 15 platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp 14 16 platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 15 17 platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp … … 27 29 platform/graphics/gstreamer/mse/AppendPipeline.cpp 28 30 platform/graphics/gstreamer/mse/GStreamerMediaDescription.cpp 31 platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.cpp 29 32 platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 30 33 platform/graphics/gstreamer/mse/MediaSourceClientGStreamerMSE.cpp -
trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp
r241120 r241585 1619 1619 } 1620 1620 1621 } 1622 1623 #endif 1621 String convertEnumerationToString(MediaPlayerEnums::SupportsType enumerationValue) 1622 { 1623 static const NeverDestroyed<String> values[] = { 1624 MAKE_STATIC_STRING_IMPL("IsNotSupported"), 1625 MAKE_STATIC_STRING_IMPL("IsSupported"), 1626 MAKE_STATIC_STRING_IMPL("MayBeSupported"), 1627 }; 1628 static_assert(!static_cast<size_t>(MediaPlayerEnums::IsNotSupported), "MediaPlayerEnums::IsNotSupported is not 0 as expected"); 1629 static_assert(static_cast<size_t>(MediaPlayerEnums::IsSupported) == 1, "MediaPlayerEnums::IsSupported is not 1 as expected"); 1630 static_assert(static_cast<size_t>(MediaPlayerEnums::MayBeSupported) == 2, "MediaPlayerEnums::MayBeSupported is not 2 as expected"); 1631 ASSERT(static_cast<size_t>(enumerationValue) < WTF_ARRAY_LENGTH(values)); 1632 return values[static_cast<size_t>(enumerationValue)]; 1633 } 1634 1635 } 1636 1637 #endif -
trunk/Source/WebCore/platform/graphics/MediaPlayer.h
r241120 r241585 254 254 255 255 // Media engine support. 256 enum SupportsType { IsNotSupported, IsSupported, MayBeSupported };257 static MediaPlayer::SupportsType supportsType(const MediaEngineSupportParameters&);256 using MediaPlayerEnums::SupportsType; 257 static SupportsType supportsType(const MediaEngineSupportParameters&); 258 258 static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&); 259 259 static bool isAvailable(); -
trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h
r226973 r241585 37 37 enum Preload { None, MetaData, Auto }; 38 38 enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill }; 39 enum SupportsType { IsNotSupported, IsSupported, MayBeSupported }; 39 40 enum { 40 41 VideoFullscreenModeNone = 0, … … 48 49 WTF::String convertEnumerationToString(MediaPlayerEnums::NetworkState); 49 50 WTF::String convertEnumerationToString(MediaPlayerEnums::Preload); 51 WTF::String convertEnumerationToString(MediaPlayerEnums::SupportsType); 50 52 51 53 } // namespace WebCore -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp
r241559 r241585 303 303 } 304 304 305 bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString)306 {307 GRefPtr<GstCaps> caps = adoptGRef(gst_caps_from_string(capsString));308 GList* candidates = gst_element_factory_list_filter(elementFactories, caps.get(), GST_PAD_SINK, false);309 bool result = candidates;310 311 gst_plugin_feature_list_free(candidates);312 return result;313 }314 315 305 static void simpleBusMessageCallback(GstBus*, GstMessage* message, GstBin* pipeline) 316 306 { -
trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h
r239921 r241585 217 217 218 218 219 bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);220 219 void connectSimpleBusMessageCallback(GstElement* pipeline); 221 220 void disconnectSimpleBusMessageCallback(GstElement* pipeline); -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
r241559 r241585 30 30 31 31 #include "GStreamerCommon.h" 32 #include "GStreamerRegistryScanner.h" 32 33 #include "HTTPHeaderNames.h" 33 34 #include "MIMETypeRegistry.h" … … 2230 2231 } 2231 2232 2232 static HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeSet()2233 {2234 static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> mimeTypes = []()2235 {2236 initializeGStreamerAndRegisterWebKitElements();2237 HashSet<String, ASCIICaseInsensitiveHash> set;2238 2239 GList* audioDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL);2240 GList* videoDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL);2241 GList* demuxerFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DEMUXER, GST_RANK_MARGINAL);2242 2243 enum ElementType {2244 AudioDecoder = 0,2245 VideoDecoder,2246 Demuxer2247 };2248 struct GstCapsWebKitMapping {2249 ElementType elementType;2250 const char* capsString;2251 Vector<AtomicString> webkitMimeTypes;2252 };2253 2254 Vector<GstCapsWebKitMapping> mapping = {2255 {AudioDecoder, "audio/midi", {"audio/midi", "audio/riff-midi"}},2256 {AudioDecoder, "audio/x-sbc", { }},2257 {AudioDecoder, "audio/x-sid", { }},2258 {AudioDecoder, "audio/x-flac", {"audio/x-flac", "audio/flac"}},2259 {AudioDecoder, "audio/x-wav", {"audio/x-wav", "audio/wav", "audio/vnd.wave"}},2260 {AudioDecoder, "audio/x-wavpack", {"audio/x-wavpack"}},2261 {AudioDecoder, "audio/x-speex", {"audio/speex", "audio/x-speex"}},2262 {AudioDecoder, "audio/x-ac3", { }},2263 {AudioDecoder, "audio/x-eac3", {"audio/x-ac3"}},2264 {AudioDecoder, "audio/x-dts", { }},2265 {VideoDecoder, "video/x-h264, profile=(string)high", {"video/mp4", "video/x-m4v"}},2266 {VideoDecoder, "video/x-msvideocodec", {"video/x-msvideo"}},2267 {VideoDecoder, "video/x-h263", { }},2268 {VideoDecoder, "video/mpegts", { }},2269 {VideoDecoder, "video/mpeg, mpegversion=(int){1,2}, systemstream=(boolean)false", {"video/mpeg"}},2270 {VideoDecoder, "video/x-dirac", { }},2271 {VideoDecoder, "video/x-flash-video", {"video/flv", "video/x-flv"}},2272 {Demuxer, "video/quicktime", { }},2273 {Demuxer, "video/quicktime, variant=(string)3gpp", {"video/3gpp"}},2274 {Demuxer, "application/x-3gp", { }},2275 {Demuxer, "video/x-ms-asf", { }},2276 {Demuxer, "audio/x-aiff", { }},2277 {Demuxer, "application/x-pn-realaudio", { }},2278 {Demuxer, "application/vnd.rn-realmedia", { }},2279 {Demuxer, "audio/x-wav", {"audio/x-wav", "audio/wav", "audio/vnd.wave"}},2280 {Demuxer, "application/x-hls", {"application/vnd.apple.mpegurl", "application/x-mpegurl"}}2281 };2282 2283 for (auto& current : mapping) {2284 GList* factories = demuxerFactories;2285 if (current.elementType == AudioDecoder)2286 factories = audioDecoderFactories;2287 else if (current.elementType == VideoDecoder)2288 factories = videoDecoderFactories;2289 2290 if (gstRegistryHasElementForMediaType(factories, current.capsString)) {2291 if (!current.webkitMimeTypes.isEmpty()) {2292 for (const auto& mimeType : current.webkitMimeTypes)2293 set.add(mimeType);2294 } else2295 set.add(AtomicString(current.capsString));2296 }2297 }2298 2299 bool opusSupported = false;2300 if (gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/x-opus")) {2301 opusSupported = true;2302 set.add(AtomicString("audio/opus"));2303 }2304 2305 bool vorbisSupported = false;2306 if (gstRegistryHasElementForMediaType(demuxerFactories, "application/ogg")) {2307 set.add(AtomicString("application/ogg"));2308 2309 vorbisSupported = gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/x-vorbis");2310 if (vorbisSupported) {2311 set.add(AtomicString("audio/ogg"));2312 set.add(AtomicString("audio/x-vorbis+ogg"));2313 }2314 2315 if (gstRegistryHasElementForMediaType(videoDecoderFactories, "video/x-theora"))2316 set.add(AtomicString("video/ogg"));2317 }2318 2319 bool audioMpegSupported = false;2320 if (gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/mpeg, mpegversion=(int)1, layer=(int)[1, 3]")) {2321 audioMpegSupported = true;2322 set.add(AtomicString("audio/mp1"));2323 set.add(AtomicString("audio/mp3"));2324 set.add(AtomicString("audio/x-mp3"));2325 }2326 2327 if (gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/mpeg, mpegversion=(int){2, 4}")) {2328 audioMpegSupported = true;2329 set.add(AtomicString("audio/aac"));2330 set.add(AtomicString("audio/mp2"));2331 set.add(AtomicString("audio/mp4"));2332 set.add(AtomicString("audio/x-m4a"));2333 }2334 2335 if (audioMpegSupported) {2336 set.add(AtomicString("audio/mpeg"));2337 set.add(AtomicString("audio/x-mpeg"));2338 }2339 2340 if (gstRegistryHasElementForMediaType(demuxerFactories, "video/x-matroska")) {2341 set.add(AtomicString("video/x-matroska"));2342 2343 if (gstRegistryHasElementForMediaType(videoDecoderFactories, "video/x-vp8")2344 || gstRegistryHasElementForMediaType(videoDecoderFactories, "video/x-vp9")2345 || gstRegistryHasElementForMediaType(videoDecoderFactories, "video/x-vp10"))2346 set.add(AtomicString("video/webm"));2347 2348 if (vorbisSupported || opusSupported)2349 set.add(AtomicString("audio/webm"));2350 }2351 2352 gst_plugin_feature_list_free(audioDecoderFactories);2353 gst_plugin_feature_list_free(videoDecoderFactories);2354 gst_plugin_feature_list_free(demuxerFactories);2355 return set;2356 }();2357 return mimeTypes;2358 }2359 2360 2233 void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types) 2361 2234 { 2362 types = mimeTypeSet(); 2235 auto& gstRegistryScanner = GStreamerRegistryScanner::singleton(); 2236 types = gstRegistryScanner.mimeTypeSet(); 2363 2237 } 2364 2238 … … 2380 2254 return result; 2381 2255 2382 // Spec says we should not return "probably" if the codecs string is empty. 2383 if (mimeTypeSet().contains(parameters.type.containerType())) 2384 result = parameters.type.codecs().isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported; 2385 2256 GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data()); 2386 2257 auto containerType = parameters.type.containerType(); 2387 if (containerType == "video/mp4"_s || containerType == "video/webm"_s) { 2388 if (mimeTypeSet().contains(containerType)) { 2389 GList* videoDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 2390 bool av1DecoderFound = gstRegistryHasElementForMediaType(videoDecoderFactories, "video/x-av1"_s); 2391 gst_plugin_feature_list_free(videoDecoderFactories); 2392 for (auto& codec : parameters.type.codecs()) { 2393 if (codec.startsWith("av01"_s)) { 2394 result = av1DecoderFound ? MediaPlayer::IsSupported : MediaPlayer::IsNotSupported; 2395 break; 2396 } 2397 if (codec.startsWith("av1"_s)) { 2398 result = MediaPlayer::IsNotSupported; 2399 break; 2400 } 2401 } 2402 } 2403 } 2404 2405 return extendedSupportsType(parameters, result); 2258 auto& gstRegistryScanner = GStreamerRegistryScanner::singleton(); 2259 if (gstRegistryScanner.isContainerTypeSupported(containerType)) { 2260 // Spec says we should not return "probably" if the codecs string is empty. 2261 Vector<String> codecs = parameters.type.codecs(); 2262 result = codecs.isEmpty() ? MediaPlayer::MayBeSupported : (gstRegistryScanner.areAllCodecsSupported(codecs) ? MediaPlayer::IsSupported : MediaPlayer::IsNotSupported); 2263 } 2264 2265 auto finalResult = extendedSupportsType(parameters, result); 2266 GST_DEBUG("Supported: %s", convertEnumerationToString(finalResult).utf8().data()); 2267 return finalResult; 2406 2268 } 2407 2269 -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp
r241248 r241585 28 28 #include "GStreamerEMEUtilities.h" 29 29 #include "GStreamerMediaDescription.h" 30 #include "GStreamerRegistryScannerMSE.h" 30 31 #include "MediaSampleGStreamer.h" 31 32 #include "InbandTextTrackPrivateGStreamer.h" … … 142 143 143 144 const String& type = m_sourceBufferPrivate->type().containerType(); 144 if (type.endsWith("mp4")) 145 GST_DEBUG("SourceBuffer containerType: %s", type.utf8().data()); 146 if (type.endsWith("mp4") || type.endsWith("aac")) 145 147 m_demux = gst_element_factory_make("qtdemux", nullptr); 146 148 else if (type.endsWith("webm")) … … 380 382 381 383 const char* originalMediaType = capsMediaType(m_demuxerSrcPadCaps.get()); 382 if (!MediaPlayerPrivateGStreamerMSE::supportsCodec(originalMediaType)) { 384 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 385 if (!gstRegistryScanner.isCodecSupported(originalMediaType)) { 383 386 m_presentationSize = WebCore::FloatSize(); 384 387 m_streamType = WebCore::MediaSourceStreamTypeGStreamer::Invalid; -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp
r240148 r241585 32 32 #include "AudioTrackPrivateGStreamer.h" 33 33 #include "GStreamerCommon.h" 34 #include "GStreamerRegistryScannerMSE.h" 34 35 #include "InbandTextTrackPrivateGStreamer.h" 35 36 #include "MIMETypeRegistry.h" … … 42 43 #include "VideoTrackPrivateGStreamer.h" 43 44 44 #include <fnmatch.h>45 45 #include <gst/app/gstappsink.h> 46 46 #include <gst/app/gstappsrc.h> … … 683 683 } 684 684 685 static HashSet<String, ASCIICaseInsensitiveHash>& mimeTypeCache()686 {687 static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> cache = []()688 {689 initializeGStreamerAndRegisterWebKitElements();690 HashSet<String, ASCIICaseInsensitiveHash> set;691 const char* mimeTypes[] = {692 "video/mp4",693 "audio/mp4",694 "video/webm",695 "audio/webm"696 };697 for (auto& type : mimeTypes)698 set.add(type);699 return set;700 }();701 return cache;702 }703 704 void MediaPlayerPrivateGStreamerMSE::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)705 {706 types = mimeTypeCache();707 }708 709 685 void MediaPlayerPrivateGStreamerMSE::trackDetected(RefPtr<AppendPipeline> appendPipeline, RefPtr<WebCore::TrackPrivateBase> newTrack, bool firstTrackDetected) 710 686 { … … 727 703 } 728 704 729 const static HashSet<AtomicString>& codecSet() 730 { 731 static NeverDestroyed<HashSet<AtomicString>> codecTypes = []() 732 { 733 initializeGStreamerAndRegisterWebKitElements(); 734 HashSet<AtomicString> set; 735 736 GList* audioDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_AUDIO, GST_RANK_MARGINAL); 737 GList* videoDecoderFactories = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_DECODER | GST_ELEMENT_FACTORY_TYPE_MEDIA_VIDEO, GST_RANK_MARGINAL); 738 739 enum ElementType { 740 AudioDecoder = 0, 741 VideoDecoder 742 }; 743 struct GstCapsWebKitMapping { 744 ElementType elementType; 745 const char* capsString; 746 Vector<AtomicString> webkitCodecs; 747 }; 748 749 GstCapsWebKitMapping mapping[] = { 750 { VideoDecoder, "video/x-h264, profile=(string){ constrained-baseline, baseline }", { "x-h264", "avc*" } }, 751 { VideoDecoder, "video/mpeg, mpegversion=(int){1,2}, systemstream=(boolean)false", { "mpeg" } }, 752 { VideoDecoder, "video/x-vp8", { "vp8", "x-vp8" } }, 753 { VideoDecoder, "video/x-vp9", { "vp9", "x-vp9" } }, 754 { AudioDecoder, "audio/x-vorbis", { "vorbis", "x-vorbis" } }, 755 { AudioDecoder, "audio/x-opus", { "opus", "x-opus" } } 756 }; 757 758 for (auto& current : mapping) { 759 GList* factories = nullptr; 760 switch (current.elementType) { 761 case AudioDecoder: 762 factories = audioDecoderFactories; 763 break; 764 case VideoDecoder: 765 factories = videoDecoderFactories; 766 break; 767 default: 768 g_assert_not_reached(); 769 break; 770 } 771 772 g_assert_nonnull(factories); 773 774 if (gstRegistryHasElementForMediaType(factories, current.capsString) && factories != nullptr) { 775 if (!current.webkitCodecs.isEmpty()) { 776 for (const auto& mimeType : current.webkitCodecs) 777 set.add(mimeType); 778 } else 779 set.add(AtomicString(current.capsString)); 780 } 781 } 782 783 bool audioMpegSupported = false; 784 if (gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/mpeg, mpegversion=(int)1, layer=(int)[1, 3]")) { 785 audioMpegSupported = true; 786 set.add(AtomicString("audio/mp3")); 787 } 788 789 if (gstRegistryHasElementForMediaType(audioDecoderFactories, "audio/mpeg, mpegversion=(int){2, 4}")) { 790 audioMpegSupported = true; 791 set.add(AtomicString("mp4a*")); 792 } 793 794 if (audioMpegSupported) { 795 set.add(AtomicString("audio/mpeg")); 796 set.add(AtomicString("audio/x-mpeg")); 797 } 798 799 800 gst_plugin_feature_list_free(audioDecoderFactories); 801 gst_plugin_feature_list_free(videoDecoderFactories); 802 803 return set; 804 }(); 805 return codecTypes; 806 } 807 808 bool MediaPlayerPrivateGStreamerMSE::supportsCodec(String codec) 809 { 810 // If the codec is named like a mimetype (eg: video/avc) remove the "video/" part. 811 size_t slashIndex = codec.find('/'); 812 if (slashIndex != WTF::notFound) 813 codec = codec.substring(slashIndex+1); 814 815 for (const auto& pattern : codecSet()) { 816 bool codecMatchesPattern = !fnmatch(pattern.string().utf8().data(), codec.utf8().data(), 0); 817 if (codecMatchesPattern) 818 return true; 819 } 820 821 return false; 822 } 823 824 bool MediaPlayerPrivateGStreamerMSE::supportsAllCodecs(const Vector<String>& codecs) 825 { 826 for (String codec : codecs) { 827 if (!supportsCodec(codec)) 828 return false; 829 } 830 831 return true; 705 void MediaPlayerPrivateGStreamerMSE::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types) 706 { 707 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 708 types = gstRegistryScanner.mimeTypeSet(); 832 709 } 833 710 … … 843 720 if (containerType.isEmpty()) { 844 721 result = MediaPlayer::MayBeSupported; 722 GST_DEBUG("mime-type \"%s\" supported: %s", parameters.type.raw().utf8().data(), convertEnumerationToString(result).utf8().data()); 845 723 return result; 846 724 } 847 725 726 GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data()); 727 auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton(); 848 728 // Spec says we should not return "probably" if the codecs string is empty. 849 if ( mimeTypeCache().contains(containerType)) {729 if (gstRegistryScanner.isContainerTypeSupported(containerType)) { 850 730 Vector<String> codecs = parameters.type.codecs(); 851 if (codecs.isEmpty()) 852 result = MediaPlayer::MayBeSupported; 853 else 854 result = supportsAllCodecs(codecs) ? MediaPlayer::IsSupported : MediaPlayer::IsNotSupported; 855 } 856 857 return extendedSupportsType(parameters, result); 731 result = codecs.isEmpty() ? MediaPlayer::MayBeSupported : (gstRegistryScanner.areAllCodecsSupported(codecs) ? MediaPlayer::IsSupported : MediaPlayer::IsNotSupported); 732 } 733 734 auto finalResult = extendedSupportsType(parameters, result); 735 GST_DEBUG("Supported: %s", convertEnumerationToString(finalResult).utf8().data()); 736 return finalResult; 858 737 } 859 738 -
trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h
r240148 r241585 83 83 void notifySeekNeedsDataForTime(const MediaTime&); 84 84 85 static bool supportsCodec(String codec);86 static bool supportsAllCodecs(const Vector<String>& codecs);87 88 85 private: 89 86 static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&); -
trunk/Source/WebCore/platform/mediacapabilities/MediaEngineConfigurationFactory.cpp
r236094 r241585 40 40 #endif 41 41 42 #if USE(GSTREAMER) 43 #include "MediaEngineConfigurationFactoryGStreamer.h" 44 #endif 45 42 46 namespace WebCore { 43 47 … … 59 63 #if PLATFORM(COCOA) 60 64 { &createMediaPlayerDecodingConfigurationCocoa, nullptr }, 65 #endif 66 #if USE(GSTREAMER) 67 { &createMediaPlayerDecodingConfigurationGStreamer, nullptr }, 61 68 #endif 62 69 }));
Note: See TracChangeset
for help on using the changeset viewer.