Changeset 241585 in webkit


Ignore:
Timestamp:
Feb 15, 2019 6:24:21 AM (5 years ago)
Author:
Philippe Normand
Message:

Decoding media-capabilities configuration initial support https://bugs.webkit.org/show_bug.cgi?id=191191

Reviewed by Xabier Rodriguez-Calvar.

This patch enables basic platform probing for GStreamer decoders,
optionally using Hardware decoding capabilities. The previous code
for decoders/demuxers probing partially duplicated between the MSE
player and its parent class was moved to a new module called
GStreamerRegistryScanner. There is one instance of it for the MSE player
and one for the parent class.

The scanner can check for the presence of the GstElement Hardware
metadata classifier in decoders and thus advise the
MediaEngineConfigurationFactoryGStreamer that hardware decoding is
supported or not. This is only a first step though. The scanner
should also probably attempt a NULL->READY transition on decoders
to validate specific input caps are supported. As this might
require changes in GStreamer, this part of the patch wasn't
included.

This patch is covered by the existing media tests.

  • platform/GStreamer.cmake: New files.
  • platform/graphics/MediaPlayer.cpp: Add support for converting

SupportsType enum to string.
(WebCore::convertEnumerationToString):

  • platform/graphics/MediaPlayer.h: Ditto.
  • platform/graphics/MediaPlayerEnums.h: Ditto.
  • platform/graphics/gstreamer/GStreamerCommon.cpp: Move

gstRegistryHasElementForMediaType to GStreamerRegistryScanner.

  • platform/graphics/gstreamer/GStreamerCommon.h: Ditto.
  • platform/graphics/gstreamer/GStreamerRegistryScanner.cpp: Added.

(WebCore::GStreamerRegistryScanner::singleton):
(WebCore::GStreamerRegistryScanner::GStreamerRegistryScanner): Initialize
supported mime-types and codecs from the GStreamer registry.
(WebCore::GStreamerRegistryScanner::~GStreamerRegistryScanner): Free the element factories.
(WebCore::GStreamerRegistryScanner::gstRegistryHasElementForMediaType):
Check the input caps are supported, optionally using hardware
device.
(WebCore::GStreamerRegistryScanner::fillMimeTypeSetFromCapsMapping):
Moved from MediaPlayerPrivateGStreamer{,MSE}.
(WebCore::GStreamerRegistryScanner::initialize): Ditto.
(WebCore::GStreamerRegistryScanner::supportsCodec const): Ditto.
(WebCore::GStreamerRegistryScanner::supportsAllCodecs const): Ditto.
(WebCore::GStreamerRegistryScanner::isDecodingSupported const): Check
the given configuration is supported. For now hardware support is
checked for video configurations only as it is quite uncommon
anyway to have hardware-enabled audio decoders.

  • platform/graphics/gstreamer/GStreamerRegistryScanner.h: Added.

(WebCore::GStreamerRegistryScanner::mimeTypeSet):
(WebCore::GStreamerRegistryScanner::supportsContainerType const):
(WebCore::GStreamerRegistryScanner::RegistryLookupResult::operator bool const):

  • platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp: Added.

(WebCore::createMediaPlayerDecodingConfigurationGStreamer):

  • platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.h: Added.
  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

Rely on new GStreamerRegistryScanner and add some debugging macros.
(WebCore::MediaPlayerPrivateGStreamer::getSupportedTypes):
(WebCore::MediaPlayerPrivateGStreamer::supportsType):

  • platform/graphics/gstreamer/mse/AppendPipeline.cpp: Ditto. Also

plug qtdemux for AAC containers, this is an explicit consequence
of finer-grained codecs probing.
(WebCore::AppendPipeline::AppendPipeline):
(WebCore::AppendPipeline::parseDemuxerSrcPadCaps):

  • platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.cpp: Added.

(WebCore::GStreamerRegistryScannerMSE::singleton):
(WebCore::GStreamerRegistryScannerMSE::GStreamerRegistryScannerMSE):

  • platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.h: Added.
  • platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:

Rely on new GStreamerRegistryScanner and add some debugging macros.
(WebCore::MediaPlayerPrivateGStreamerMSE::getSupportedTypes):
(WebCore::MediaPlayerPrivateGStreamerMSE::supportsType):

  • platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h:
  • platform/mediacapabilities/MediaEngineConfigurationFactory.cpp:

(WebCore::factories): GStreamer support.

Location:
trunk/Source/WebCore
Files:
6 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r241567 r241585  
     12019-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
    1802019-02-14  Joseph Pecoraro  <pecoraro@apple.com>
    281
  • trunk/Source/WebCore/platform/GStreamer.cmake

    r238159 r241585  
    1111        platform/graphics/gstreamer/GStreamerCommon.cpp
    1212        platform/graphics/gstreamer/GstAllocatorFastMalloc.cpp
     13        platform/graphics/gstreamer/GStreamerRegistryScanner.cpp
    1314        platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp
     15        platform/graphics/gstreamer/MediaEngineConfigurationFactoryGStreamer.cpp
    1416        platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
    1517        platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp
     
    2729        platform/graphics/gstreamer/mse/AppendPipeline.cpp
    2830        platform/graphics/gstreamer/mse/GStreamerMediaDescription.cpp
     31        platform/graphics/gstreamer/mse/GStreamerRegistryScannerMSE.cpp
    2932        platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp
    3033        platform/graphics/gstreamer/mse/MediaSourceClientGStreamerMSE.cpp
  • trunk/Source/WebCore/platform/graphics/MediaPlayer.cpp

    r241120 r241585  
    16191619}
    16201620
    1621 }
    1622 
    1623 #endif
     1621String 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  
    254254
    255255    // 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&);
    258258    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&);
    259259    static bool isAvailable();
  • trunk/Source/WebCore/platform/graphics/MediaPlayerEnums.h

    r226973 r241585  
    3737    enum Preload { None, MetaData, Auto };
    3838    enum VideoGravity { VideoGravityResize, VideoGravityResizeAspect, VideoGravityResizeAspectFill };
     39    enum SupportsType { IsNotSupported, IsSupported, MayBeSupported };
    3940    enum {
    4041        VideoFullscreenModeNone = 0,
     
    4849WTF::String convertEnumerationToString(MediaPlayerEnums::NetworkState);
    4950WTF::String convertEnumerationToString(MediaPlayerEnums::Preload);
     51WTF::String convertEnumerationToString(MediaPlayerEnums::SupportsType);
    5052
    5153} // namespace WebCore
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.cpp

    r241559 r241585  
    303303}
    304304
    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 
    315305static void simpleBusMessageCallback(GstBus*, GstMessage* message, GstBin* pipeline)
    316306{
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerCommon.h

    r239921 r241585  
    217217
    218218
    219 bool gstRegistryHasElementForMediaType(GList* elementFactories, const char* capsString);
    220219void connectSimpleBusMessageCallback(GstElement* pipeline);
    221220void disconnectSimpleBusMessageCallback(GstElement* pipeline);
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r241559 r241585  
    3030
    3131#include "GStreamerCommon.h"
     32#include "GStreamerRegistryScanner.h"
    3233#include "HTTPHeaderNames.h"
    3334#include "MIMETypeRegistry.h"
     
    22302231}
    22312232
    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             Demuxer
    2247         };
    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                 } else
    2295                     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 
    23602233void MediaPlayerPrivateGStreamer::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
    23612234{
    2362     types = mimeTypeSet();
     2235    auto& gstRegistryScanner = GStreamerRegistryScanner::singleton();
     2236    types = gstRegistryScanner.mimeTypeSet();
    23632237}
    23642238
     
    23802254        return result;
    23812255
    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());
    23862257    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;
    24062268}
    24072269
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp

    r241248 r241585  
    2828#include "GStreamerEMEUtilities.h"
    2929#include "GStreamerMediaDescription.h"
     30#include "GStreamerRegistryScannerMSE.h"
    3031#include "MediaSampleGStreamer.h"
    3132#include "InbandTextTrackPrivateGStreamer.h"
     
    142143
    143144    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"))
    145147        m_demux = gst_element_factory_make("qtdemux", nullptr);
    146148    else if (type.endsWith("webm"))
     
    380382
    381383    const char* originalMediaType = capsMediaType(m_demuxerSrcPadCaps.get());
    382     if (!MediaPlayerPrivateGStreamerMSE::supportsCodec(originalMediaType)) {
     384    auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton();
     385    if (!gstRegistryScanner.isCodecSupported(originalMediaType)) {
    383386            m_presentationSize = WebCore::FloatSize();
    384387            m_streamType = WebCore::MediaSourceStreamTypeGStreamer::Invalid;
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp

    r240148 r241585  
    3232#include "AudioTrackPrivateGStreamer.h"
    3333#include "GStreamerCommon.h"
     34#include "GStreamerRegistryScannerMSE.h"
    3435#include "InbandTextTrackPrivateGStreamer.h"
    3536#include "MIMETypeRegistry.h"
     
    4243#include "VideoTrackPrivateGStreamer.h"
    4344
    44 #include <fnmatch.h>
    4545#include <gst/app/gstappsink.h>
    4646#include <gst/app/gstappsrc.h>
     
    683683}
    684684
    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 
    709685void MediaPlayerPrivateGStreamerMSE::trackDetected(RefPtr<AppendPipeline> appendPipeline, RefPtr<WebCore::TrackPrivateBase> newTrack, bool firstTrackDetected)
    710686{
     
    727703}
    728704
    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;
     705void MediaPlayerPrivateGStreamerMSE::getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>& types)
     706{
     707    auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton();
     708    types = gstRegistryScanner.mimeTypeSet();
    832709}
    833710
     
    843720    if (containerType.isEmpty()) {
    844721        result = MediaPlayer::MayBeSupported;
     722        GST_DEBUG("mime-type \"%s\" supported: %s", parameters.type.raw().utf8().data(), convertEnumerationToString(result).utf8().data());
    845723        return result;
    846724    }
    847725
     726    GST_DEBUG("Checking mime-type \"%s\"", parameters.type.raw().utf8().data());
     727    auto& gstRegistryScanner = GStreamerRegistryScannerMSE::singleton();
    848728    // Spec says we should not return "probably" if the codecs string is empty.
    849     if (mimeTypeCache().contains(containerType)) {
     729    if (gstRegistryScanner.isContainerTypeSupported(containerType)) {
    850730        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;
    858737}
    859738
  • trunk/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.h

    r240148 r241585  
    8383    void notifySeekNeedsDataForTime(const MediaTime&);
    8484
    85     static bool supportsCodec(String codec);
    86     static bool supportsAllCodecs(const Vector<String>& codecs);
    87 
    8885private:
    8986    static void getSupportedTypes(HashSet<String, ASCIICaseInsensitiveHash>&);
  • trunk/Source/WebCore/platform/mediacapabilities/MediaEngineConfigurationFactory.cpp

    r236094 r241585  
    4040#endif
    4141
     42#if USE(GSTREAMER)
     43#include "MediaEngineConfigurationFactoryGStreamer.h"
     44#endif
     45
    4246namespace WebCore {
    4347
     
    5963#if PLATFORM(COCOA)
    6064        { &createMediaPlayerDecodingConfigurationCocoa, nullptr },
     65#endif
     66#if USE(GSTREAMER)
     67        { &createMediaPlayerDecodingConfigurationGStreamer, nullptr },
    6168#endif
    6269    }));
Note: See TracChangeset for help on using the changeset viewer.