Title: [232136] trunk/Source
Revision
232136
Author
eric.carl...@apple.com
Date
2018-05-23 17:00:54 -0700 (Wed, 23 May 2018)

Log Message

Avoid loading AVFoundation to check supported MIME types if possible
https://bugs.webkit.org/show_bug.cgi?id=185839
<rdar://problem/40182010>

Reviewed by Jer Noble.
Source/WebCore:

Avoid loading AVFoundation to call +[AVURLAssetClass audiovisualMIMETypes] as long as possible,
and when they are loaded send the list to the UI process so it can pass it to all extant
and all new web processes so they can won't have call it at all.

* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/ImageDecoder.cpp:
(WebCore::ImageDecoder::create): Don't call ImageDecoderAVFObjC::canDecodeType if
ImageDecoderCG can decode the type so we don't have to load AVFoundation.
(WebCore::ImageDecoder::supportsMediaType): Return as soon as a decoder class says
it supports a media type to avoid calling more than one. Call ImageDecoderAVFObjC last.

* platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.h:
(WebCore::AVFoundationMIMETypeCache::setCacheMIMETypesCallback):
* platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.mm:
(WebCore::AVFoundationMIMETypeCache::singleton): Simplify.
(WebCore::AVFoundationMIMETypeCache::setSupportedTypes): Cache the supplied list of types
so we won't have to load AVFoundation when asked for types later.
(WebCore::AVFoundationMIMETypeCache::types):
(WebCore::AVFoundationMIMETypeCache::supportsContentType): New convenience routine.
(WebCore::AVFoundationMIMETypeCache::canDecodeType): Ditto.
(WebCore::AVFoundationMIMETypeCache::isAvailable const): New, check to see if AVFoundation.framework
is available without actually loading it.
(WebCore::AVFoundationMIMETypeCache::loadMIMETypes): Load types if possible.
(WebCore::AVFoundationMIMETypeCache::AVFoundationMIMETypeCache): Deleted.
(WebCore::AVFoundationMIMETypeCache::loadTypes): Deleted.

* platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
(WebCore::ImageDecoderAVFObjC::create): Use AVFoundationMIMETypeCache::isAvailable instead
of loading the frameworks.
(WebCore::ImageDecoderAVFObjC::supportsMediaType): Ditto.
(WebCore::ImageDecoderAVFObjC::supportsContentType): Use AVFoundationMIMETypeCache::supportsContentType.
(WebCore::ImageDecoderAVFObjC::canDecodeType): Use AVFoundationMIMETypeCache::canDecodeType.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::registerMediaEngine): ASSERT if the
AVFoundationMIMETypeCache is empty, it shouldn't be possible to get here in that state.
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType): Use AVFoundationMIMETypeCache::supportsContentType.
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsKeySystem): Use AVFoundationMIMETypeCache::canDecodeType.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::registerMediaEngine): ASSERT if the
AVFoundationMIMETypeCache is empty, it shouldn't be possible to get here in that state.
(WebCore::MediaPlayerPrivateMediaSourceAVFObjC::supportsType): Use AVFoundationMIMETypeCache::canDecodeType.

* platform/graphics/cg/ImageDecoderCG.cpp:
(WebCore::ImageDecoderCG::canDecodeType): New.
* platform/graphics/cg/ImageDecoderCG.h:

Source/WebKit:

* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode const): Encode mediaMIMETypes.
(WebKit::WebProcessCreationParameters::decode): Decode mediaMIMETypes.
* Shared/WebProcessCreationParameters.h:

* UIProcess/Cocoa/WebProcessProxyCocoa.mm:
(WebKit::mediaTypeCache): Static Vector of media MIME types.
(WebKit::WebProcessProxy::cacheMediaMIMETypes): Cache the type list and pass it to every other
process proxy.
(WebKit::WebProcessProxy::cacheMediaMIMETypesInternal): Cache the type list and pass it to the
web process.
(WebKit::WebProcessProxy::mediaMIMETypes): Return the cached type list.

* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::initializeNewWebProcess): Set parameters.mediaMIMETypes.

* UIProcess/WebProcessProxy.h:
* UIProcess/WebProcessProxy.messages.in: Add CacheMediaMIMETypes.

* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in: Add SetMediaMIMETypes.

* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess): Cache the MIME types if the list isn't
empty, else register with AVFoundationMIMETypeCache to be notified when it loads types.
AVFoundationMIMETypeCache to
(WebKit::WebProcess::platformTerminate): Unregister with AVFoundationMIMETypeCache.
(WebKit::WebProcess::setMediaMIMETypes): Pass list of types to AVFoundationMIMETypeCache.

Source/WTF:

* wtf/cocoa/SoftLinking.h: Add SOFT_LINK_FRAMEWORK_OPTIONAL_PREFLIGHT.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (232135 => 232136)


--- trunk/Source/WTF/ChangeLog	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WTF/ChangeLog	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1,3 +1,13 @@
+2018-05-23  Eric Carlson  <eric.carl...@apple.com>
+
+        Avoid loading AVFoundation to check supported MIME types if possible
+        https://bugs.webkit.org/show_bug.cgi?id=185839
+        <rdar://problem/40182010>
+
+        Reviewed by Jer Noble.
+
+        * wtf/cocoa/SoftLinking.h: Add SOFT_LINK_FRAMEWORK_OPTIONAL_PREFLIGHT.
+
 2018-05-23  Filip Pizlo  <fpi...@apple.com>
 
         Speed up JetStream/base64

Modified: trunk/Source/WTF/wtf/cocoa/SoftLinking.h (232135 => 232136)


--- trunk/Source/WTF/wtf/cocoa/SoftLinking.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WTF/wtf/cocoa/SoftLinking.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -63,6 +63,13 @@
         return frameworkLibrary; \
     }
 
+#define SOFT_LINK_FRAMEWORK_OPTIONAL_PREFLIGHT(framework) \
+    static bool framework##LibraryIsAvailable() \
+    { \
+        static bool frameworkLibraryIsAvailable = dlopen_preflight("/System/Library/Frameworks/" #framework ".framework/" #framework); \
+        return frameworkLibraryIsAvailable; \
+    }
+
 #define SOFT_LINK_FRAMEWORK_OPTIONAL(framework) \
     static void* framework##Library() \
     { \

Modified: trunk/Source/WebCore/ChangeLog (232135 => 232136)


--- trunk/Source/WebCore/ChangeLog	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/ChangeLog	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1,3 +1,59 @@
+2018-05-23  Eric Carlson  <eric.carl...@apple.com>
+
+        Avoid loading AVFoundation to check supported MIME types if possible
+        https://bugs.webkit.org/show_bug.cgi?id=185839
+        <rdar://problem/40182010>
+
+        Reviewed by Jer Noble.
+
+        Avoid loading AVFoundation to call +[AVURLAssetClass audiovisualMIMETypes] as long as possible,
+        and when they are loaded send the list to the UI process so it can pass it to all extant
+        and all new web processes so they can won't have call it at all.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/ImageDecoder.cpp:
+        (WebCore::ImageDecoder::create): Don't call ImageDecoderAVFObjC::canDecodeType if 
+        ImageDecoderCG can decode the type so we don't have to load AVFoundation.
+        (WebCore::ImageDecoder::supportsMediaType): Return as soon as a decoder class says
+        it supports a media type to avoid calling more than one. Call ImageDecoderAVFObjC last.
+
+        * platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.h:
+        (WebCore::AVFoundationMIMETypeCache::setCacheMIMETypesCallback):
+        * platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.mm:
+        (WebCore::AVFoundationMIMETypeCache::singleton): Simplify.
+        (WebCore::AVFoundationMIMETypeCache::setSupportedTypes): Cache the supplied list of types
+        so we won't have to load AVFoundation when asked for types later.
+        (WebCore::AVFoundationMIMETypeCache::types):
+        (WebCore::AVFoundationMIMETypeCache::supportsContentType): New convenience routine.
+        (WebCore::AVFoundationMIMETypeCache::canDecodeType): Ditto.
+        (WebCore::AVFoundationMIMETypeCache::isAvailable const): New, check to see if AVFoundation.framework
+        is available without actually loading it.
+        (WebCore::AVFoundationMIMETypeCache::loadMIMETypes): Load types if possible.
+        (WebCore::AVFoundationMIMETypeCache::AVFoundationMIMETypeCache): Deleted.
+        (WebCore::AVFoundationMIMETypeCache::loadTypes): Deleted.
+
+        * platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm:
+        (WebCore::ImageDecoderAVFObjC::create): Use AVFoundationMIMETypeCache::isAvailable instead
+        of loading the frameworks.
+        (WebCore::ImageDecoderAVFObjC::supportsMediaType): Ditto.
+        (WebCore::ImageDecoderAVFObjC::supportsContentType): Use AVFoundationMIMETypeCache::supportsContentType.
+        (WebCore::ImageDecoderAVFObjC::canDecodeType): Use AVFoundationMIMETypeCache::canDecodeType.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::registerMediaEngine): ASSERT if the 
+        AVFoundationMIMETypeCache is empty, it shouldn't be possible to get here in that state.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsType): Use AVFoundationMIMETypeCache::supportsContentType.
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsKeySystem): Use AVFoundationMIMETypeCache::canDecodeType.
+
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::registerMediaEngine): ASSERT if the 
+        AVFoundationMIMETypeCache is empty, it shouldn't be possible to get here in that state.
+        (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::supportsType): Use AVFoundationMIMETypeCache::canDecodeType.
+
+        * platform/graphics/cg/ImageDecoderCG.cpp:
+        (WebCore::ImageDecoderCG::canDecodeType): New.
+        * platform/graphics/cg/ImageDecoderCG.h:
+
 2018-05-23  Chris Dumez  <cdu...@apple.com>
 
         RenderLayer::scrollRectToVisible() should not propagate a subframe's scroll to its cross-origin parent

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (232135 => 232136)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2018-05-24 00:00:54 UTC (rev 232136)
@@ -219,6 +219,7 @@
 		07EE76EC1BE96DB000F89133 /* MockRealtimeVideoSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 07EE76EA1BE96DB000F89133 /* MockRealtimeVideoSource.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07EE76EF1BEA619800F89133 /* MockRealtimeVideoSourceMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 07EE76ED1BEA619800F89133 /* MockRealtimeVideoSourceMac.h */; };
 		07F04A942006B1E300AE2A0A /* ApplicationStateChangeListener.h in Headers */ = {isa = PBXBuildFile; fileRef = 07F04A92200684BC00AE2A0A /* ApplicationStateChangeListener.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		07F4E93320B3587F002E3803 /* AVFoundationMIMETypeCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 07C8AD121D073D630087C5CE /* AVFoundationMIMETypeCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07F876841AD580F900905849 /* MediaPlaybackTargetContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 07F876831AD4A94500905849 /* MediaPlaybackTargetContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07F944161864D046005D31CB /* PlatformMediaSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CDAE8C081746B95700532D78 /* PlatformMediaSessionManager.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		07FE99DD18807A7D00256648 /* MediaElementSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 07FE99DB18807A7D00256648 /* MediaElementSession.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -27120,6 +27121,7 @@
 				CDC675271EAEA9D400727C84 /* AVAudioSessionCaptureDevice.h in Headers */,
 				CDC675231EAEA9B700727C84 /* AVAudioSessionCaptureDeviceManager.h in Headers */,
 				070363E2181A1CDC00C074A5 /* AVCaptureDeviceManager.h in Headers */,
+				07F4E93320B3587F002E3803 /* AVFoundationMIMETypeCache.h in Headers */,
 				070363E4181A1CDC00C074A5 /* AVMediaCaptureSource.h in Headers */,
 				CD336F6217F9F64700DDDCD0 /* AVTrackPrivateAVFObjCImpl.h in Headers */,
 				070363E6181A1CDC00C074A5 /* AVVideoCaptureSource.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/ImageDecoder.cpp	2018-05-24 00:00:54 UTC (rev 232136)
@@ -42,11 +42,11 @@
 
 RefPtr<ImageDecoder> ImageDecoder::create(SharedBuffer& data, const String& mimeType, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
 {
+    UNUSED_PARAM(mimeType);
+
 #if HAVE(AVASSETREADER)
-    if (ImageDecoderAVFObjC::canDecodeType(mimeType))
+    if (!ImageDecoderCG::canDecodeType(mimeType) && ImageDecoderAVFObjC::canDecodeType(mimeType))
         return ImageDecoderAVFObjC::create(data, mimeType, alphaOption, gammaAndColorProfileOption);
-#else
-    UNUSED_PARAM(mimeType);
 #endif
 
 #if USE(CG)
@@ -60,24 +60,23 @@
 
 bool ImageDecoder::supportsMediaType(MediaType type)
 {
-    bool supports = false;
-#if HAVE(AVASSETREADER)
-    if (ImageDecoderAVFObjC::supportsMediaType(type))
-        supports = true;
-#endif
-
 #if USE(CG)
     if (ImageDecoderCG::supportsMediaType(type))
-        supports = true;
+        return true;
 #elif USE(DIRECT2D)
     if (ImageDecoderDirect2D::supportsMediaType(type))
-        supports = true;
+        return true;
 #else
     if (ScalableImageDecoder::supportsMediaType(type))
-        supports = true;
+        return true;
 #endif
 
-    return supports;
+#if HAVE(AVASSETREADER)
+    if (ImageDecoderAVFObjC::supportsMediaType(type))
+        return true;
+#endif
+
+    return false;
 }
 
 }

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.h (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,10 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  */
 
-#ifndef AVFoundationMIMETypeCache_h
-#define AVFoundationMIMETypeCache_h
+#pragma once
 
-#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+#if PLATFORM(COCOA)
 
 #include <wtf/Forward.h>
 #include <wtf/HashSet.h>
@@ -34,24 +33,34 @@
 
 namespace WebCore {
 
+class ContentType;
+
 class AVFoundationMIMETypeCache {
 public:
-    static AVFoundationMIMETypeCache& singleton();
+    WEBCORE_EXPORT static AVFoundationMIMETypeCache& singleton();
 
-    AVFoundationMIMETypeCache();
+    bool supportsContentType(const ContentType&);
+    bool canDecodeType(const String&);
 
-    void loadTypes();
     const HashSet<String, ASCIICaseInsensitiveHash>& types();
+    bool isEmpty();
+    bool isAvailable() const;
 
+    using CacheMIMETypesCallback = std::function<void(const Vector<String>&)>;
+    void setCacheMIMETypesCallback(CacheMIMETypesCallback&& callback) { m_cacheTypeCallback = WTFMove(callback); }
+
+    WEBCORE_EXPORT void setSupportedTypes(const Vector<String>&);
+
 private:
-    enum MIMETypeLoadStatus { NotLoaded, Loading, Loaded };
+    friend NeverDestroyed<AVFoundationMIMETypeCache>;
+    AVFoundationMIMETypeCache() = default;
 
-    MIMETypeLoadStatus m_status { NotLoaded };
-    dispatch_queue_t m_loaderQueue;
-    Lock m_lock;
-    HashSet<String, ASCIICaseInsensitiveHash> m_cache;
+    void loadMIMETypes();
+
+    std::optional<HashSet<String, ASCIICaseInsensitiveHash>> m_cache;
+    CacheMIMETypesCallback m_cacheTypeCallback;
 };
 
 }
+
 #endif
-#endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.mm (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVFoundationMIMETypeCache.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,72 +26,97 @@
 #import "config.h"
 #import "AVFoundationMIMETypeCache.h"
 
-#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+#if PLATFORM(COCOA)
 
+#import "ContentType.h"
 #import <AVFoundation/AVAsset.h>
 #import <wtf/HashSet.h>
-#import <wtf/Locker.h>
-#import <wtf/NeverDestroyed.h>
 
 #import <pal/cf/CoreMediaSoftLink.h>
 
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+SOFT_LINK_FRAMEWORK_OPTIONAL_PREFLIGHT(AVFoundation)
 SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
 SOFT_LINK_CLASS(AVFoundation, AVURLAsset)
+#endif
 
 namespace WebCore {
 
-using namespace PAL;
+AVFoundationMIMETypeCache& AVFoundationMIMETypeCache::singleton()
+{
+    static NeverDestroyed<AVFoundationMIMETypeCache> cache;
+    return cache.get();
+}
 
-AVFoundationMIMETypeCache::AVFoundationMIMETypeCache()
+void AVFoundationMIMETypeCache::setSupportedTypes(const Vector<String>& types)
 {
-    m_loaderQueue = dispatch_queue_create("WebCoreAudioVisualMIMETypes loader queue", DISPATCH_QUEUE_SERIAL);
+    if (m_cache)
+        return;
+
+    m_cache = HashSet<String, ASCIICaseInsensitiveHash>();
+    for (auto& type : types)
+        m_cache->add(type);
 }
 
-void AVFoundationMIMETypeCache::loadTypes()
+const HashSet<String, ASCIICaseInsensitiveHash>& AVFoundationMIMETypeCache::types()
 {
-    {
-        Locker<Lock> lock(m_lock);
+    if (!m_cache)
+        loadMIMETypes();
 
-        if (m_status != NotLoaded)
-            return;
+    return *m_cache;
+}
 
-        if (!AVFoundationLibrary()) {
-            m_status = Loaded;
-            return;
-        }
+bool AVFoundationMIMETypeCache::supportsContentType(const ContentType& contentType)
+{
+    if (contentType.isEmpty())
+        return false;
 
-        m_status = Loading;
-    }
-
-    dispatch_async(m_loaderQueue, [this] {
-        for (NSString *type in [getAVURLAssetClass() audiovisualMIMETypes])
-            m_cache.add(type);
-        m_lock.lock();
-        m_status = Loaded;
-        m_lock.unlock();
-    });
+    return types().contains(contentType.containerType());
 }
 
-const HashSet<String, ASCIICaseInsensitiveHash>& AVFoundationMIMETypeCache::types()
+bool AVFoundationMIMETypeCache::canDecodeType(const String& mimeType)
 {
-    m_lock.lock();
-    MIMETypeLoadStatus status = m_status;
-    m_lock.unlock();
+    if (mimeType.isEmpty())
+        return false;
 
-    if (status != Loaded) {
-        loadTypes();
-        dispatch_sync(m_loaderQueue, ^{ });
-    }
+    if (!isAvailable() || !types().contains(ContentType { mimeType }.containerType()))
+        return false;
 
-    return m_cache;
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+    return [getAVURLAssetClass() isPlayableExtendedMIMEType:mimeType];
+#endif
+
+    return false;
 }
 
-AVFoundationMIMETypeCache& AVFoundationMIMETypeCache::singleton()
+bool AVFoundationMIMETypeCache::isAvailable() const
 {
-    static NeverDestroyed<AVFoundationMIMETypeCache> cache;
-    return cache.get();
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+    return AVFoundationLibraryIsAvailable();
+#else
+    return false;
+#endif
 }
 
+void AVFoundationMIMETypeCache::loadMIMETypes()
+{
+    m_cache = HashSet<String, ASCIICaseInsensitiveHash>();
+
+#if ENABLE(VIDEO) && USE(AVFOUNDATION)
+    static std::once_flag onceFlag;
+    std::call_once(onceFlag, [this] {
+        if (!AVFoundationLibrary())
+            return;
+
+        for (NSString* type in [getAVURLAssetClass() audiovisualMIMETypes])
+            m_cache->add(type);
+
+        if (m_cacheTypeCallback)
+            m_cacheTypeCallback(copyToVector(*m_cache));
+    });
+#endif
 }
 
+}
+
 #endif

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/ImageDecoderAVFObjC.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -319,7 +319,7 @@
 RefPtr<ImageDecoderAVFObjC> ImageDecoderAVFObjC::create(SharedBuffer& data, const String& mimeType, AlphaOption alphaOption, GammaAndColorProfileOption gammaAndColorProfileOption)
 {
     // AVFoundation may not be available at runtime.
-    if (!getAVURLAssetClass())
+    if (!AVFoundationMIMETypeCache::singleton().isAvailable())
         return nullptr;
 
     if (!canLoad_VideoToolbox_VTCreateCGImageFromCVPixelBuffer())
@@ -350,24 +350,17 @@
 
 bool ImageDecoderAVFObjC::supportsMediaType(MediaType type)
 {
-    if (type == MediaType::Video)
-        return getAVURLAssetClass() && canLoad_VideoToolbox_VTCreateCGImageFromCVPixelBuffer();
-    return false;
+    return type == MediaType::Video && AVFoundationMIMETypeCache::singleton().isAvailable();
 }
 
 bool ImageDecoderAVFObjC::supportsContentType(const ContentType& type)
 {
-    if (getAVURLAssetClass() && canLoad_VideoToolbox_VTCreateCGImageFromCVPixelBuffer())
-        return AVFoundationMIMETypeCache::singleton().types().contains(type.containerType());
-    return false;
+    return AVFoundationMIMETypeCache::singleton().supportsContentType(type);
 }
 
 bool ImageDecoderAVFObjC::canDecodeType(const String& mimeType)
 {
-    if (!supportsMediaType(MediaType::Video))
-        return nullptr;
-
-    return [getAVURLAssetClass() isPlayableExtendedMIMEType:mimeType];
+    return AVFoundationMIMETypeCache::singleton().canDecodeType(mimeType);
 }
 
 AVAssetTrack *ImageDecoderAVFObjC::firstEnabledTrack()

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -397,7 +397,7 @@
 
     registrar([](MediaPlayer* player) { return std::make_unique<MediaPlayerPrivateAVFoundationObjC>(player); },
             getSupportedTypes, supportsType, originsInMediaCache, clearMediaCache, clearMediaCacheForOrigins, supportsKeySystem);
-    AVFoundationMIMETypeCache::singleton().loadTypes();
+    ASSERT(AVFoundationMIMETypeCache::singleton().isAvailable());
 }
 
 static AVAssetCacheType *assetCacheForPath(const String& path)
@@ -1681,7 +1681,7 @@
     if (isUnsupportedMIMEType(containerType))
         return MediaPlayer::IsNotSupported;
 
-    if (!staticMIMETypeList().contains(containerType) && !AVFoundationMIMETypeCache::singleton().types().contains(containerType))
+    if (!staticMIMETypeList().contains(containerType) && !AVFoundationMIMETypeCache::singleton().canDecodeType(containerType))
         return MediaPlayer::IsNotSupported;
 
     // The spec says:
@@ -1710,7 +1710,7 @@
         if (!mimeType.isEmpty() && isUnsupportedMIMEType(mimeType))
             return false;
 
-        if (!mimeType.isEmpty() && !staticMIMETypeList().contains(mimeType) && !AVFoundationMIMETypeCache::singleton().types().contains(mimeType))
+        if (!mimeType.isEmpty() && !staticMIMETypeList().contains(mimeType) && !AVFoundationMIMETypeCache::singleton().canDecodeType(mimeType))
             return false;
 
         return true;

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -191,7 +191,7 @@
 
     registrar([](MediaPlayer* player) { return std::make_unique<MediaPlayerPrivateMediaSourceAVFObjC>(player); },
         getSupportedTypes, supportsType, 0, 0, 0, 0);
-    AVFoundationMIMETypeCache::singleton().loadTypes();
+    ASSERT(AVFoundationMIMETypeCache::singleton().isAvailable());
 }
 
 bool MediaPlayerPrivateMediaSourceAVFObjC::isAvailable()
@@ -219,7 +219,7 @@
         return MediaPlayer::IsNotSupported;
 #endif
 
-    if (parameters.type.isEmpty() || !AVFoundationMIMETypeCache::singleton().types().contains(parameters.type.containerType()))
+    if (parameters.type.isEmpty() || !AVFoundationMIMETypeCache::singleton().canDecodeType(parameters.type.containerType()))
         return MediaPlayer::IsNotSupported;
 
     // The spec says:

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.cpp	2018-05-24 00:00:54 UTC (rev 232136)
@@ -33,6 +33,7 @@
 #include "IntPoint.h"
 #include "IntSize.h"
 #include "Logging.h"
+#include "MIMETypeRegistry.h"
 #include "SharedBuffer.h"
 #include "UTIRegistry.h"
 #include <pal/spi/cg/ImageIOSPI.h>
@@ -480,6 +481,11 @@
 #endif
 }
 
+bool ImageDecoderCG::canDecodeType(const String& mimeType)
+{
+    return MIMETypeRegistry::isSupportedImageMIMEType(mimeType);
 }
 
+}
+
 #endif // USE(CG)

Modified: trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h (232135 => 232136)


--- trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebCore/platform/graphics/cg/ImageDecoderCG.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -40,7 +40,8 @@
     }
 
     static bool supportsMediaType(MediaType type) { return type == MediaType::Image; }
-    
+    static bool canDecodeType(const String&);
+
     size_t bytesDecodedToDetermineProperties() const final;
 
     EncodedDataStatus encodedDataStatus() const final;

Modified: trunk/Source/WebKit/ChangeLog (232135 => 232136)


--- trunk/Source/WebKit/ChangeLog	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/ChangeLog	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1,3 +1,40 @@
+2018-05-23  Eric Carlson  <eric.carl...@apple.com>
+
+        Avoid loading AVFoundation to check supported MIME types if possible
+        https://bugs.webkit.org/show_bug.cgi?id=185839
+        <rdar://problem/40182010>
+
+        Reviewed by Jer Noble.
+        
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode const): Encode mediaMIMETypes.
+        (WebKit::WebProcessCreationParameters::decode): Decode mediaMIMETypes.
+        * Shared/WebProcessCreationParameters.h:
+
+        * UIProcess/Cocoa/WebProcessProxyCocoa.mm:
+        (WebKit::mediaTypeCache): Static Vector of media MIME types.
+        (WebKit::WebProcessProxy::cacheMediaMIMETypes): Cache the type list and pass it to every other
+        process proxy.
+        (WebKit::WebProcessProxy::cacheMediaMIMETypesInternal): Cache the type list and pass it to the
+        web process.
+        (WebKit::WebProcessProxy::mediaMIMETypes): Return the cached type list.
+
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::initializeNewWebProcess): Set parameters.mediaMIMETypes.
+
+        * UIProcess/WebProcessProxy.h:
+        * UIProcess/WebProcessProxy.messages.in: Add CacheMediaMIMETypes.
+
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in: Add SetMediaMIMETypes.
+
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess): Cache the MIME types if the list isn't
+        empty, else register with AVFoundationMIMETypeCache to be notified when it loads types.
+        AVFoundationMIMETypeCache to 
+        (WebKit::WebProcess::platformTerminate): Unregister with AVFoundationMIMETypeCache.
+        (WebKit::WebProcess::setMediaMIMETypes): Pass list of types to AVFoundationMIMETypeCache.
+
 2018-05-23  Brian Burg  <bb...@apple.com>
 
         Web Automation: disable process swap on navigation when an automation session is active

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp (232135 => 232136)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.cpp	2018-05-24 00:00:54 UTC (rev 232136)
@@ -154,6 +154,10 @@
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) && !RELEASE_LOG_DISABLED
     encoder << shouldLogUserInteraction;
 #endif
+
+#if PLATFORM(COCOA)
+    encoder << mediaMIMETypes;
+#endif
 }
 
 bool WebProcessCreationParameters::decode(IPC::Decoder& decoder, WebProcessCreationParameters& parameters)
@@ -401,6 +405,11 @@
         return false;
 #endif
 
+#if PLATFORM(COCOA)
+    if (!decoder.decode(parameters.mediaMIMETypes))
+        return false;
+#endif
+
     return true;
 }
 

Modified: trunk/Source/WebKit/Shared/WebProcessCreationParameters.h (232135 => 232136)


--- trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/Shared/WebProcessCreationParameters.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -185,6 +185,10 @@
     WebCore::SoupNetworkProxySettings proxySettings;
 #endif
 
+#if PLATFORM(COCOA)
+    Vector<String> mediaMIMETypes;
+#endif
+
 #if HAVE(CFNETWORK_STORAGE_PARTITIONING) && !RELEASE_LOG_DISABLED
     bool shouldLogUserInteraction { false };
 #endif

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm (232135 => 232136)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -31,6 +31,8 @@
 #import "WKBrowsingContextControllerInternal.h"
 #import "WKBrowsingContextHandleInternal.h"
 #import "WKTypeRefWrapper.h"
+#import "WebProcessMessages.h"
+#import "WebProcessPool.h"
 #import <sys/sysctl.h>
 #import <wtf/NeverDestroyed.h>
 
@@ -137,4 +139,37 @@
     return info.kp_proc.p_flag & P_TRACED;
 }
 
+static Vector<String>& mediaTypeCache()
+{
+    ASSERT(RunLoop::isMain());
+    static NeverDestroyed<Vector<String>> typeCache;
+    return typeCache;
 }
+
+void WebProcessProxy::cacheMediaMIMETypes(const Vector<String>& types)
+{
+    if (!mediaTypeCache().isEmpty())
+        return;
+
+    mediaTypeCache() = types;
+    for (auto& process : processPool().processes()) {
+        if (process != this)
+            cacheMediaMIMETypesInternal(types);
+    }
+}
+
+void WebProcessProxy::cacheMediaMIMETypesInternal(const Vector<String>& types)
+{
+    if (!mediaTypeCache().isEmpty())
+        return;
+
+    mediaTypeCache() = types;
+    send(Messages::WebProcess::SetMediaMIMETypes(types), 0);
+}
+
+Vector<String> WebProcessProxy::mediaMIMETypes()
+{
+    return mediaTypeCache();
+}
+
+}

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (232135 => 232136)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -1313,6 +1313,10 @@
 
     WebCore::IntRect syncRootViewToScreen(const WebCore::IntRect& viewRect);
 
+#if PLATFORM(COCOA)
+    Vector<String> mediaMIMETypes();
+#endif
+
 private:
     WebPageProxy(PageClient&, WebProcessProxy&, uint64_t pageID, Ref<API::PageConfiguration>&&);
     void platformInitialize();

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (232135 => 232136)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2018-05-24 00:00:54 UTC (rev 232136)
@@ -939,6 +939,10 @@
 
     parameters.presentingApplicationPID = m_configuration->presentingApplicationPID();
 
+#if PLATFORM(COCOA)
+    parameters.mediaMIMETypes = process.mediaMIMETypes();
+#endif
+
     // Add any platform specific parameters
     platformInitializeWebProcess(parameters);
 

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (232135 => 232136)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -221,6 +221,11 @@
     bool isInPrewarmedPool() const { return m_isInPrewarmedPool; }
     void setIsInPrewarmedPool(bool isInPrewarmedPool) { m_isInPrewarmedPool = isInPrewarmedPool; }
 
+#if PLATFORM(COCOA)
+    Vector<String> mediaMIMETypes();
+    void cacheMediaMIMETypes(const Vector<String>&);
+#endif
+
 protected:
     static uint64_t generatePageID();
     WebProcessProxy(WebProcessPool&, WebsiteDataStore&, IsInPrewarmedPool);
@@ -233,6 +238,10 @@
     // ProcessLauncher::Client
     void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
 
+#if PLATFORM(COCOA)
+    void cacheMediaMIMETypesInternal(const Vector<String>&);
+#endif
+
 private:
     // Called when the web process has crashed or we know that it will terminate soon.
     // Will potentially cause the WebProcessProxy object to be freed.

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in (232135 => 232136)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.messages.in	2018-05-24 00:00:54 UTC (rev 232136)
@@ -66,4 +66,8 @@
     CheckRemotePortForActivity(struct WebCore::MessagePortIdentifier port, uint64_t callbackIdentifier)
     DidDeliverMessagePortMessages(uint64_t messageBatchIdentifier)
     DidCheckProcessLocalPortForActivity(uint64_t callbackIdentifier, bool isLocallyReachable)
+
+#if PLATFORM(COCOA)
+    CacheMediaMIMETypes(Vector<String> types)
+#endif
 }

Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (232135 => 232136)


--- trunk/Source/WebKit/WebProcess/WebProcess.h	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h	2018-05-24 00:00:54 UTC (rev 232136)
@@ -240,6 +240,10 @@
     void accessibilityProcessSuspendedNotification(bool);
 #endif
 
+#if PLATFORM(COCOA)
+    void setMediaMIMETypes(const Vector<String>);
+#endif
+
 private:
     WebProcess();
     ~WebProcess();

Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (232135 => 232136)


--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2018-05-24 00:00:54 UTC (rev 232136)
@@ -135,4 +135,8 @@
     ScrollerStylePreferenceChanged(bool useOvelayScrollbars)
 #endif
 #endif
+
+#if PLATFORM(COCOA)
+    SetMediaMIMETypes(Vector<String> types)
+#endif
 }

Modified: trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm (232135 => 232136)


--- trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm	2018-05-23 23:41:43 UTC (rev 232135)
+++ trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm	2018-05-24 00:00:54 UTC (rev 232136)
@@ -48,6 +48,7 @@
 #import "WebsiteDataStoreParameters.h"
 #import <_javascript_Core/ConfigFile.h>
 #import <_javascript_Core/Options.h>
+#import <WebCore/AVFoundationMIMETypeCache.h>
 #import <WebCore/AXObjectCache.h>
 #import <WebCore/CPUMonitor.h>
 #import <WebCore/FileSystem.h>
@@ -181,6 +182,14 @@
     // Priority decay on iOS 9 is impacting page load time so we fix the priority of the WebProcess' main thread (rdar://problem/22003112).
     pthread_set_fixedpriority_self();
 #endif
+
+    if (!parameters.mediaMIMETypes.isEmpty())
+        setMediaMIMETypes(parameters.mediaMIMETypes);
+    else {
+        AVFoundationMIMETypeCache::singleton().setCacheMIMETypesCallback([this](const Vector<String>& types) {
+            parentProcessConnection()->send(Messages::WebProcessProxy::CacheMediaMIMETypes(types), 0);
+        });
+    }
 }
 
 void WebProcess::initializeProcessName(const ChildProcessInitializationParameters& parameters)
@@ -334,6 +343,7 @@
 
 void WebProcess::platformTerminate()
 {
+    AVFoundationMIMETypeCache::singleton().setCacheMIMETypesCallback(nullptr);
 }
 
 RetainPtr<CFDataRef> WebProcess::sourceApplicationAuditData() const
@@ -577,4 +587,9 @@
 }
 #endif    
 
+void WebProcess::setMediaMIMETypes(const Vector<String> types)
+{
+    AVFoundationMIMETypeCache::singleton().setSupportedTypes(types);
+}
+
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to