Title: [271194] trunk/Source
Revision
271194
Author
[email protected]
Date
2021-01-05 23:26:14 -0800 (Tue, 05 Jan 2021)

Log Message

[Cocoa] WebM format reader doesn't work with a url in a <source> element
https://bugs.webkit.org/show_bug.cgi?id=219961
<rdar://problem/72399014>

Reviewed by Andy Estes.

Source/WebCore:

Work around a CoreMedia bug that makes the format reader fail to load when the
AVURLAssetOutOfBandMIMETypeKeyis included in the AVURLAsset options dictionary.
Also include some cleanup:
- Move the code to check for WebM MIME types from MediaPlayerPrivateAVFoundationObjC
  to AVAssetMIMETypeCache.
- Don't use RuntimeEnabledFeatures in MediaPlayerPrivateAVFoundationObjC.
- Register the WebM format reader when creating an AVURLAsset for a WebM url instead
  of when checking the MIME type.
- Cleanup WebM "codecs" parameter parsing.
- It is a layering violation to use RuntimeSettings from inside of /platform.

* platform/audio/PlatformMediaSessionManager.cpp:
(WebCore::PlatformMediaSessionManager::webMFormatReaderEnabled):
(WebCore::PlatformMediaSessionManager::setWebMFormatReaderEnabled):
(WebCore::PlatformMediaSessionManager::vorbisDecoderEnabled):
(WebCore::PlatformMediaSessionManager::setVorbisDecoderEnabled):
* platform/audio/PlatformMediaSessionManager.h:
* platform/graphics/TrackPrivateBase.cpp:
(WebCore::TrackPrivateBase::defaultEnabled const):
* platform/graphics/TrackPrivateBase.h:
* platform/graphics/avfoundation/objc/AVAssetMIMETypeCache.mm:
(WebCore::AVAssetMIMETypeCache::canDecodeExtendedType):
(WebCore::AVAssetMIMETypeCache::initializeCache):
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::registerFormatReaderIfNecessary):
(WebCore::willUseWebMFormatReaderForType):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL):
(WebCore::MediaPlayerPrivateAVFoundationObjC::supportsTypeAndCodecs):
(WebCore::ensureFormatReaderIsRegistered): Deleted.
(WebCore::isFormatReaderAvailable): Deleted.
* platform/graphics/cocoa/AudioTrackPrivateWebM.cpp:
(WebCore::AudioTrackPrivateWebM::defaultEnabled const):
* platform/graphics/cocoa/AudioTrackPrivateWebM.h:
* platform/graphics/cocoa/SourceBufferParserWebM.cpp:
(WebCore::SourceBufferParserWebM::webmMIMETypes):
(WebCore::canLoadFormatReader):
(WebCore::SourceBufferParserWebM::isWebMFormatReaderAvailable):
(WebCore::SourceBufferParserWebM::isContentTypeSupported):
* platform/graphics/cocoa/SourceBufferParserWebM.h:
* platform/graphics/cocoa/VideoTrackPrivateWebM.cpp:
(WebCore::VideoTrackPrivateWebM::defaultEnabled const):
* platform/graphics/cocoa/VideoTrackPrivateWebM.h:
* platform/graphics/cocoa/WebMAudioUtilitiesCocoa.mm:
(WebCore::isVorbisDecoderAvailable):

Source/WebKit:

Only enable a WebM track when the it has FlagEnabled element, or when we see that
it has media samples. This is necessary because there are WebM files with empty tracks,
and CoreMedia won't play a file if any enabled track doesn't have samples.

* Shared/mac/MediaFormatReader/FormatReader.cpp:
(WebKit::FormatReader::didParseTracks):
* Shared/mac/MediaFormatReader/TrackReader.cpp:
(WebKit::TrackReader::create):
(WebKit::TrackReader::TrackReader):
(WebKit::TrackReader::finishParsing):
(WebKit::TrackReader::isEnabled const):
(WebKit::TrackReader::copyProperty):
* Shared/mac/MediaFormatReader/TrackReader.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformInitializeWebProcess):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (271193 => 271194)


--- trunk/Source/WebCore/ChangeLog	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/ChangeLog	2021-01-06 07:26:14 UTC (rev 271194)
@@ -1,3 +1,56 @@
+2021-01-05  Eric Carlson  <[email protected]>
+
+        [Cocoa] WebM format reader doesn't work with a url in a <source> element
+        https://bugs.webkit.org/show_bug.cgi?id=219961
+        <rdar://problem/72399014>
+
+        Reviewed by Andy Estes.
+
+        Work around a CoreMedia bug that makes the format reader fail to load when the
+        AVURLAssetOutOfBandMIMETypeKeyis included in the AVURLAsset options dictionary.
+        Also include some cleanup:
+        - Move the code to check for WebM MIME types from MediaPlayerPrivateAVFoundationObjC
+          to AVAssetMIMETypeCache.
+        - Don't use RuntimeEnabledFeatures in MediaPlayerPrivateAVFoundationObjC.
+        - Register the WebM format reader when creating an AVURLAsset for a WebM url instead
+          of when checking the MIME type.
+        - Cleanup WebM "codecs" parameter parsing.
+        - It is a layering violation to use RuntimeSettings from inside of /platform.
+
+        * platform/audio/PlatformMediaSessionManager.cpp:
+        (WebCore::PlatformMediaSessionManager::webMFormatReaderEnabled):
+        (WebCore::PlatformMediaSessionManager::setWebMFormatReaderEnabled):
+        (WebCore::PlatformMediaSessionManager::vorbisDecoderEnabled):
+        (WebCore::PlatformMediaSessionManager::setVorbisDecoderEnabled):
+        * platform/audio/PlatformMediaSessionManager.h:
+        * platform/graphics/TrackPrivateBase.cpp:
+        (WebCore::TrackPrivateBase::defaultEnabled const):
+        * platform/graphics/TrackPrivateBase.h:
+        * platform/graphics/avfoundation/objc/AVAssetMIMETypeCache.mm:
+        (WebCore::AVAssetMIMETypeCache::canDecodeExtendedType):
+        (WebCore::AVAssetMIMETypeCache::initializeCache):
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::registerFormatReaderIfNecessary):
+        (WebCore::willUseWebMFormatReaderForType):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL):
+        (WebCore::MediaPlayerPrivateAVFoundationObjC::supportsTypeAndCodecs):
+        (WebCore::ensureFormatReaderIsRegistered): Deleted.
+        (WebCore::isFormatReaderAvailable): Deleted.
+        * platform/graphics/cocoa/AudioTrackPrivateWebM.cpp:
+        (WebCore::AudioTrackPrivateWebM::defaultEnabled const):
+        * platform/graphics/cocoa/AudioTrackPrivateWebM.h:
+        * platform/graphics/cocoa/SourceBufferParserWebM.cpp:
+        (WebCore::SourceBufferParserWebM::webmMIMETypes):
+        (WebCore::canLoadFormatReader):
+        (WebCore::SourceBufferParserWebM::isWebMFormatReaderAvailable):
+        (WebCore::SourceBufferParserWebM::isContentTypeSupported):
+        * platform/graphics/cocoa/SourceBufferParserWebM.h:
+        * platform/graphics/cocoa/VideoTrackPrivateWebM.cpp:
+        (WebCore::VideoTrackPrivateWebM::defaultEnabled const):
+        * platform/graphics/cocoa/VideoTrackPrivateWebM.h:
+        * platform/graphics/cocoa/WebMAudioUtilitiesCocoa.mm:
+        (WebCore::isVorbisDecoderAvailable):
+
 2021-01-05  Simon Fraser  <[email protected]>
 
         REGRESSION: animated iframe painted blank

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp (271193 => 271194)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -35,6 +35,14 @@
 
 #if ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
 
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+bool PlatformMediaSessionManager::m_webMFormatReaderEnabled;
+#endif
+
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+bool PlatformMediaSessionManager::m_vorbisDecoderEnabled;
+#endif
+
 static std::unique_ptr<PlatformMediaSessionManager>& sharedPlatformMediaSessionManager()
 {
     static NeverDestroyed<std::unique_ptr<PlatformMediaSessionManager>> platformMediaSessionManager;
@@ -610,6 +618,42 @@
     deactivateAudioSession() = deactivate;
 }
 
+bool PlatformMediaSessionManager::webMFormatReaderEnabled()
+{
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    return m_webMFormatReaderEnabled;
+#else
+    return false;
+#endif
+}
+
+void PlatformMediaSessionManager::setWebMFormatReaderEnabled(bool enabled)
+{
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    m_webMFormatReaderEnabled = enabled;
+#else
+    UNUSED_PARAM(enabled);
+#endif
+}
+
+bool PlatformMediaSessionManager::vorbisDecoderEnabled()
+{
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+    return m_vorbisDecoderEnabled;
+#else
+    return false;
+#endif
+}
+
+void PlatformMediaSessionManager::setVorbisDecoderEnabled(bool enabled)
+{
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+    m_vorbisDecoderEnabled = enabled;
+#else
+    UNUSED_PARAM(enabled);
+#endif
+}
+
 #else // ENABLE(VIDEO) || ENABLE(WEB_AUDIO)
 
 void PlatformMediaSessionManager::updateNowPlayingInfoIfNecessary()

Modified: trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h (271193 => 271194)


--- trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/audio/PlatformMediaSessionManager.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -58,6 +58,11 @@
     WEBCORE_EXPORT static void setShouldDeactivateAudioSession(bool);
     WEBCORE_EXPORT static bool shouldDeactivateAudioSession();
 
+    WEBCORE_EXPORT static void setWebMFormatReaderEnabled(bool);
+    WEBCORE_EXPORT static bool webMFormatReaderEnabled();
+    WEBCORE_EXPORT static void setVorbisDecoderEnabled(bool);
+    WEBCORE_EXPORT static bool vorbisDecoderEnabled();
+
     virtual ~PlatformMediaSessionManager() = default;
 
     virtual void scheduleSessionStatusUpdate() { }
@@ -201,6 +206,13 @@
     WeakHashSet<PlatformMediaSession::AudioCaptureSource> m_audioCaptureSources;
     GenericTaskQueue<Timer> updateSessionStateQueue;
 
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    static bool m_webMFormatReaderEnabled;
+#endif
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+    static bool m_vorbisDecoderEnabled;
+#endif
+
 #if !RELEASE_LOG_DISABLED
     Ref<AggregateLogger> m_logger;
 #endif

Modified: trunk/Source/WebCore/platform/graphics/TrackPrivateBase.cpp (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/TrackPrivateBase.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/TrackPrivateBase.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -38,6 +38,11 @@
     return WTF::nullopt;
 }
 
+Optional<bool> TrackPrivateBase::defaultEnabled() const
+{
+    return WTF::nullopt;
+}
+
 #if !RELEASE_LOG_DISABLED
 
 static uint64_t s_uniqueId = 0;

Modified: trunk/Source/WebCore/platform/graphics/TrackPrivateBase.h (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/TrackPrivateBase.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/TrackPrivateBase.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -64,6 +64,7 @@
 
     virtual int trackIndex() const { return 0; }
     virtual Optional<uint64_t> trackUID() const;
+    virtual Optional<bool> defaultEnabled() const;
 
     virtual MediaTime startTimeVariance() const { return MediaTime::zeroTime(); }
 

Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVAssetMIMETypeCache.mm (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVAssetMIMETypeCache.mm	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/AVAssetMIMETypeCache.mm	2021-01-06 07:26:14 UTC (rev 271194)
@@ -29,6 +29,7 @@
 #if PLATFORM(COCOA)
 
 #import "ContentType.h"
+#import "SourceBufferParserWebM.h"
 #import <pal/cf/CoreMediaSoftLink.h>
 #import <pal/cocoa/AVFoundationSoftLink.h>
 
@@ -63,9 +64,16 @@
 {
 #if ENABLE(VIDEO) && USE(AVFOUNDATION)
     ASSERT(isAvailable());
-    return [PAL::getAVURLAssetClass() isPlayableExtendedMIMEType:type.raw()];
+    if ([PAL::getAVURLAssetClass() isPlayableExtendedMIMEType:type.raw()])
+        return true;
+
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    if (SourceBufferParserWebM::isContentTypeSupported(type) == MediaPlayerEnums::SupportsType::IsSupported)
+        return true;
 #endif
 
+#endif // ENABLE(VIDEO) && USE(AVFOUNDATION)
+
     return false;
 }
 
@@ -148,6 +156,13 @@
     for (NSString* type in [PAL::getAVURLAssetClass() audiovisualMIMETypes])
         cache.add(type);
 
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    if (SourceBufferParserWebM::isWebMFormatReaderAvailable()) {
+        auto webmTypes = SourceBufferParserWebM::webmMIMETypes();
+        cache.add(webmTypes.begin(), webmTypes.end());
+    }
+#endif
+
     if (m_cacheTypeCallback)
         m_cacheTypeCallback(copyToVector(cache));
 #endif

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


--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2021-01-06 07:26:14 UTC (rev 271194)
@@ -56,7 +56,6 @@
 #import "PixelBufferConformerCV.h"
 #import "PlatformTimeRanges.h"
 #import "RuntimeApplicationChecks.h"
-#import "RuntimeEnabledFeatures.h"
 #import "SecurityOrigin.h"
 #import "SerializedPlatformDataCueMac.h"
 #import "SharedBuffer.h"
@@ -100,7 +99,6 @@
 #import <wtf/OSObjectPtr.h>
 #import <wtf/URL.h>
 #import <wtf/cocoa/VectorCocoa.h>
-#import <wtf/spi/darwin/OSVariantSPI.h>
 #import <wtf/text/CString.h>
 #import <wtf/threads/BinarySemaphore.h>
 
@@ -270,6 +268,20 @@
     return globalQueue;
 }
 
+static void registerFormatReaderIfNecessary()
+{
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        // Like we do for other media formats, allow the format reader to run in the WebContent or GPU process
+        // (which is already appropriately sandboxed) rather than in a separate MediaToolbox XPC service.
+        RELEASE_ASSERT(isInGPUProcess() || isInWebProcess());
+        MTRegisterPluginFormatReaderBundleDirectory((__bridge CFURLRef)NSBundle.mainBundle.builtInPlugInsURL);
+        MTPluginFormatReaderDisableSandboxing();
+    });
+#endif
+}
+
 class MediaPlayerPrivateAVFoundationObjC::Factory final : public MediaPlayerFactory {
 private:
     MediaPlayerEnums::MediaEngineIdentifier identifier() const final { return MediaPlayerEnums::MediaEngineIdentifier::AVFoundation; };
@@ -792,6 +804,19 @@
 
 }
 
+static bool willUseWebMFormatReaderForType(const String& type)
+{
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    if (!SourceBufferParserWebM::isWebMFormatReaderAvailable())
+        return false;
+
+    return equalIgnoringASCIICase(type, "video/webm") || equalIgnoringASCIICase(type, "audio/webm");
+#else
+    UNUSED_PARAM(type);
+    return false;
+#endif
+}
+
 void MediaPlayerPrivateAVFoundationObjC::createAVAssetForURL(const URL& url, RetainPtr<NSMutableDictionary> options)
 {
     ALWAYS_LOG(LOGIDENTIFIER);
@@ -833,7 +858,11 @@
 #endif
 
     auto type = player()->contentMIMEType();
-    if (PAL::canLoad_AVFoundation_AVURLAssetOutOfBandMIMETypeKey() && !type.isEmpty() && !player()->contentMIMETypeWasInferredFromExtension()) {
+
+    // Don't advertise WebM MIME types or the format reader won't be loaded until rdar://72405127 is fixed.
+    auto willUseWebMFormatReader = willUseWebMFormatReaderForType(type);
+
+    if (PAL::canLoad_AVFoundation_AVURLAssetOutOfBandMIMETypeKey() && !type.isEmpty() && !player()->contentMIMETypeWasInferredFromExtension() && !willUseWebMFormatReader) {
         auto codecs = player()->contentTypeCodecs();
         if (!codecs.isEmpty()) {
             NSString *typeString = [NSString stringWithFormat:@"%@; codecs=\"%@\"", (NSString *)type, (NSString *)codecs];
@@ -876,6 +905,9 @@
             [options setObject:@NO forKey:AVURLAssetUsesNoPersistentCacheKey];
     }
 
+    if (willUseWebMFormatReader)
+        registerFormatReaderIfNecessary();
+
     NSURL *cocoaURL = canonicalURL(url);
     m_avAsset = adoptNS([PAL::allocAVURLAssetInstance() initWithURL:cocoaURL options:options.get()]);
 
@@ -1667,39 +1699,6 @@
 }
 #endif
 
-#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
-static void ensureFormatReaderIsRegistered()
-{
-    static dispatch_once_t onceToken;
-    dispatch_once(&onceToken, ^{
-        // Like we do for other media formats, allow the format reader to run in the WebContent or GPU process
-        // (which is already appropriately sandboxed) rather than in a separate MediaToolbox XPC service.
-        RELEASE_ASSERT(isInGPUProcess() || isInWebProcess());
-        MTRegisterPluginFormatReaderBundleDirectory((__bridge CFURLRef)NSBundle.mainBundle.builtInPlugInsURL);
-        MTPluginFormatReaderDisableSandboxing();
-    });
-}
-#endif
-
-#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
-static bool isFormatReaderAvailable()
-{
-    if (!RuntimeEnabledFeatures::sharedFeatures().webMFormatReaderEnabled())
-        return false;
-
-#if !USE(APPLE_INTERNAL_SDK)
-    // FIXME (rdar://72320419): If WebKit was built with ad-hoc code-signing,
-    // CoreMedia will only load the format reader plug-in when a user default
-    // is set on Apple internal OSs. That means we cannot currently support WebM
-    // in public SDK builds on customer OSs.
-    if (!os_variant_allows_internal_security_policies("com.apple.WebKit"))
-        return false;
-#endif
-
-    return true;
-}
-#endif
-
 MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationObjC::supportsTypeAndCodecs(const MediaEngineSupportParameters& parameters)
 {
 #if ENABLE(MEDIA_SOURCE)
@@ -1711,19 +1710,6 @@
         return MediaPlayer::SupportsType::IsNotSupported;
 #endif
 
-#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
-    if (isFormatReaderAvailable()) {
-        auto supported = SourceBufferParserWebM::isContentTypeSupported(parameters.type);
-        if (supported != MediaPlayer::SupportsType::IsNotSupported) {
-            ensureFormatReaderIsRegistered();
-            if (supported == MediaPlayer::SupportsType::MayBeSupported)
-                return supported;
-            if (contentTypeMeetsHardwareDecodeRequirements(parameters.type, parameters.contentTypesRequiringHardwareSupport))
-                return MediaPlayer::SupportsType::IsSupported;
-        }
-    }
-#endif
-
     auto supported = AVAssetMIMETypeCache::singleton().canDecodeType(parameters.type.raw());
     if (supported != MediaPlayer::SupportsType::IsSupported)
         return supported;

Modified: trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.cpp (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -58,6 +58,13 @@
     return WTF::nullopt;
 }
 
+Optional<bool> AudioTrackPrivateWebM::defaultEnabled() const
+{
+    if (m_track.is_enabled.is_present())
+        return m_track.is_enabled.value();
+    return WTF::nullopt;
+}
+
 AtomString AudioTrackPrivateWebM::label() const
 {
     if (m_label.isNull())

Modified: trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.h (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/AudioTrackPrivateWebM.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -42,6 +42,7 @@
     AtomString language() const final;
     int trackIndex() const final;
     Optional<uint64_t> trackUID() const final;
+    Optional<bool> defaultEnabled() const final;
 
 private:
     AudioTrackPrivateWebM(webm::TrackEntry&&);

Modified: trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -35,6 +35,7 @@
 #include "MediaDescription.h"
 #include "MediaSampleAVFObjC.h"
 #include "NotImplemented.h"
+#include "PlatformMediaSessionManager.h"
 #include "SharedBuffer.h"
 #include "VP9UtilitiesCocoa.h"
 #include "VideoTrackPrivateWebM.h"
@@ -48,6 +49,7 @@
 #include <wtf/StdList.h>
 #include <wtf/cf/TypeCastsCF.h>
 #include <wtf/darwin/WeakLinking.h>
+#include <wtf/spi/darwin/OSVariantSPI.h>
 
 #include "CoreVideoSoftLink.h"
 #include "VideoToolboxSoftLink.h"
@@ -443,6 +445,46 @@
     webm::TrackEntry m_track;
 };
 
+const HashSet<String, ASCIICaseInsensitiveHash>& SourceBufferParserWebM::webmMIMETypes()
+{
+    static auto types = makeNeverDestroyed([] {
+
+        HashSet<String, ASCIICaseInsensitiveHash> types;
+
+#if ENABLE(VP9)
+        types.add("video/webm");
+#endif
+#if ENABLE(VORBIS) || ENABLE(OPUS)
+        types.add("audio/webm");
+#endif
+
+        return types;
+    }());
+
+    return types;
+}
+
+static bool canLoadFormatReader()
+{
+#if !HAVE(MT_PLUGIN_FORMAT_READER)
+    return false;
+#elif USE(APPLE_INTERNAL_SDK)
+    return true;
+#else
+    // FIXME (rdar://72320419): If WebKit was built with ad-hoc code-signing,
+    // CoreMedia will only load the format reader plug-in when a user default
+    // is set on Apple internal OSs. That means we cannot currently support WebM
+    // in public SDK builds on customer OSs.
+    static bool allowsInternalSecurityPolicies = os_variant_allows_internal_security_policies("com.apple.WebKit");
+    return allowsInternalSecurityPolicies;
+#endif // !USE(APPLE_INTERNAL_SDK)
+}
+
+bool SourceBufferParserWebM::isWebMFormatReaderAvailable()
+{
+    return PlatformMediaSessionManager::webMFormatReaderEnabled() && canLoadFormatReader() && isWebmParserAvailable();
+}
+
 MediaPlayerEnums::SupportsType SourceBufferParserWebM::isContentTypeSupported(const ContentType& type)
 {
 #if ENABLE(VP9) || ENABLE(VORBIS) || ENABLE(OPUS)
@@ -449,8 +491,9 @@
     if (!isWebmParserAvailable())
         return MediaPlayerEnums::SupportsType::IsNotSupported;
 
-    bool isAudioContainerType = WTF::equalIgnoringASCIICase(type.containerType(), "audio/webm");
-    bool isVideoContainerType = WTF::equalIgnoringASCIICase(type.containerType(), "video/webm");
+    auto containerType = type.containerType();
+    bool isAudioContainerType = WTF::equalIgnoringASCIICase(containerType, "audio/webm");
+    bool isVideoContainerType = WTF::equalIgnoringASCIICase(containerType, "video/webm");
     if (!isAudioContainerType && !isVideoContainerType)
         return MediaPlayerEnums::SupportsType::IsNotSupported;
     
@@ -473,22 +516,18 @@
     if (!isAnyCodecAvailable)
         return MediaPlayerEnums::SupportsType::IsNotSupported;
 
-    String codecsParameter = type.parameter(ContentType::codecsParameter());
-    if (!codecsParameter)
+    auto codecs = type.codecs();
+    if (codecs.isEmpty())
         return MediaPlayerEnums::SupportsType::MayBeSupported;
 
-    auto splitResults = StringView(codecsParameter).split(',');
-    if (splitResults.begin() == splitResults.end())
-        return MediaPlayerEnums::SupportsType::MayBeSupported;
-
-    for (auto split : splitResults) {
+    for (auto& codec : codecs) {
 #if ENABLE(VP9)
-        if (split.startsWith("vp09") || split.startsWith("vp08") || equal(split, "vp8") || equal(split, "vp9")) {
+        if (codec.startsWith("vp09") || codec.startsWith("vp08") || equal(codec, "vp8") || equal(codec, "vp9")) {
 
             if (!isVP9DecoderAvailable())
                 return MediaPlayerEnums::SupportsType::IsNotSupported;
 
-            auto codecParameters = parseVPCodecParameters(split);
+            auto codecParameters = parseVPCodecParameters(codec);
             if (!codecParameters)
                 return MediaPlayerEnums::SupportsType::IsNotSupported;
 
@@ -500,7 +539,7 @@
 #endif // ENABLE(VP9)
 
 #if ENABLE(VORBIS)
-        if (split == "vorbis") {
+        if (codec == "vorbis") {
             if (!isVorbisDecoderAvailable())
                 return MediaPlayerEnums::SupportsType::IsNotSupported;
 
@@ -509,7 +548,7 @@
 #endif // ENABLE(VORBIS)
 
 #if ENABLE(OPUS)
-        if (split == "opus") {
+        if (codec == "opus") {
             if (!isOpusDecoderAvailable())
                 return MediaPlayerEnums::SupportsType::IsNotSupported;
 

Modified: trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/SourceBufferParserWebM.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -60,7 +60,9 @@
 public:
     class StreamingVectorReader;
 
+    static bool isWebMFormatReaderAvailable();
     static MediaPlayerEnums::SupportsType isContentTypeSupported(const ContentType&);
+    static const HashSet<String, ASCIICaseInsensitiveHash>& webmMIMETypes();
     static RefPtr<SourceBufferParserWebM> create(const ContentType&);
 
     SourceBufferParserWebM();

Modified: trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.cpp (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -58,6 +58,13 @@
     return WTF::nullopt;
 }
 
+Optional<bool> VideoTrackPrivateWebM::defaultEnabled() const
+{
+    if (m_track.is_enabled.is_present())
+        return m_track.is_enabled.value();
+    return WTF::nullopt;
+}
+
 AtomString VideoTrackPrivateWebM::label() const
 {
     if (m_label.isNull())

Modified: trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.h (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/VideoTrackPrivateWebM.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -42,6 +42,7 @@
     AtomString language() const final;
     int trackIndex() const final;
     Optional<uint64_t> trackUID() const final;
+    Optional<bool> defaultEnabled() const final;
 
 private:
     VideoTrackPrivateWebM(webm::TrackEntry&&);

Modified: trunk/Source/WebCore/platform/graphics/cocoa/WebMAudioUtilitiesCocoa.mm (271193 => 271194)


--- trunk/Source/WebCore/platform/graphics/cocoa/WebMAudioUtilitiesCocoa.mm	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebCore/platform/graphics/cocoa/WebMAudioUtilitiesCocoa.mm	2021-01-06 07:26:14 UTC (rev 271194)
@@ -31,7 +31,7 @@
 #import "CAAudioStreamDescription.h"
 #import "Logging.h"
 #import "MediaUtilities.h"
-#import "RuntimeEnabledFeatures.h"
+#import "PlatformMediaSessionManager.h"
 #import <AudioToolbox/AudioComponent.h>
 #import <AudioToolbox/AudioFormat.h>
 #import <CoreMedia/CMFormatDescription.h>
@@ -177,7 +177,7 @@
     static bool available;
 
 #if ENABLE(VORBIS) && PLATFORM(MAC)
-    if (!RuntimeEnabledFeatures::sharedFeatures().vorbisDecoderEnabled())
+    if (!PlatformMediaSessionManager::vorbisDecoderEnabled())
         return false;
 
     static dispatch_once_t onceToken;

Modified: trunk/Source/WebKit/ChangeLog (271193 => 271194)


--- trunk/Source/WebKit/ChangeLog	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/ChangeLog	2021-01-06 07:26:14 UTC (rev 271194)
@@ -1,3 +1,29 @@
+2021-01-05  Eric Carlson  <[email protected]>
+
+        [Cocoa] WebM format reader doesn't work with a url in a <source> element
+        https://bugs.webkit.org/show_bug.cgi?id=219961
+        <rdar://problem/72399014>
+
+        Reviewed by Andy Estes.
+
+        Only enable a WebM track when the it has FlagEnabled element, or when we see that
+        it has media samples. This is necessary because there are WebM files with empty tracks,
+        and CoreMedia won't play a file if any enabled track doesn't have samples.
+
+        * Shared/mac/MediaFormatReader/FormatReader.cpp:
+        (WebKit::FormatReader::didParseTracks):
+        * Shared/mac/MediaFormatReader/TrackReader.cpp:
+        (WebKit::TrackReader::create):
+        (WebKit::TrackReader::TrackReader):
+        (WebKit::TrackReader::finishParsing):
+        (WebKit::TrackReader::isEnabled const):
+        (WebKit::TrackReader::copyProperty):
+        * Shared/mac/MediaFormatReader/TrackReader.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformInitializeWebProcess):
+
 2021-01-05  Wenson Hsieh  <[email protected]>
 
         Refactor some logic around touch event deferring gesture recognizers

Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/FormatReader.cpp (271193 => 271194)


--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/FormatReader.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/FormatReader.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -144,26 +144,29 @@
     m_duration = WTFMove(segment.duration);
 
     for (auto& videoTrack : segment.videoTracks) {
-        if (auto trackReader = TrackReader::create(allocator(), *this, videoTrack.track.get()))
-            m_trackReaders.append(trackReader.releaseNonNull());
-        // FIXME: How do we know which tracks should be enabled?
-        if (m_trackReaders.size() == 1)
-            m_trackReaders[0]->setEnabled(true);
+        auto track = videoTrack.track.get();
+        auto trackReader = TrackReader::create(allocator(), *this, kCMMediaType_Video, *track->trackUID(), track->defaultEnabled());
+        if (!trackReader)
+            continue;
+
+        m_trackReaders.append(trackReader.releaseNonNull());
     }
 
     for (auto& audioTrack : segment.audioTracks) {
-        if (auto trackReader = TrackReader::create(allocator(), *this, audioTrack.track.get()))
-            m_trackReaders.append(trackReader.releaseNonNull());
-        // FIXME: How do we know which tracks should be enabled?
-        if (m_trackReaders.size() == segment.videoTracks.size() + 1)
-            m_trackReaders[segment.videoTracks.size()]->setEnabled(true);
+        auto track = audioTrack.track.get();
+        auto trackReader = TrackReader::create(allocator(), *this, kCMMediaType_Audio, *track->trackUID(), track->defaultEnabled());
+        if (!trackReader)
+            continue;
+
+        m_trackReaders.append(trackReader.releaseNonNull());
     }
 
     for (auto& textTrack : segment.textTracks) {
-        if (auto trackReader = TrackReader::create(allocator(), *this, textTrack.track.get()))
+        auto track = textTrack.track.get();
+        if (auto trackReader = TrackReader::create(allocator(), *this, kCMMediaType_Text, *track->trackUID(), track->defaultEnabled()))
             m_trackReaders.append(trackReader.releaseNonNull());
     }
-    
+
     m_parseTracksCondition.notifyAll();
 }
 

Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.cpp (271193 => 271194)


--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -144,27 +144,11 @@
     return unwrap(checked_cf_cast<WrapperRef>(object));
 }
 
-RefPtr<TrackReader> TrackReader::create(Allocator&& allocator, const FormatReader& formatReader, const VideoTrackPrivate* track)
+RefPtr<TrackReader> TrackReader::create(Allocator&& allocator, const FormatReader& formatReader, CMMediaType mediaType, uint64_t trackID, Optional<bool> enabled)
 {
-    if (!track)
-        return nullptr;
-    return adoptRef(new (allocator) TrackReader(WTFMove(allocator), formatReader, kCMMediaType_Video, *track->trackUID()));
+    return adoptRef(new (allocator) TrackReader(WTFMove(allocator), formatReader, mediaType, trackID, enabled));
 }
 
-RefPtr<TrackReader> TrackReader::create(Allocator&& allocator, const FormatReader& formatReader, const AudioTrackPrivate* track)
-{
-    if (!track)
-        return nullptr;
-    return adoptRef(new (allocator) TrackReader(WTFMove(allocator), formatReader, kCMMediaType_Audio, *track->trackUID()));
-}
-
-RefPtr<TrackReader> TrackReader::create(Allocator&& allocator, const FormatReader& formatReader, const InbandTextTrackPrivate* track)
-{
-    if (!track)
-        return nullptr;
-    return adoptRef(new (allocator) TrackReader(WTFMove(allocator), formatReader, kCMMediaType_Text, *track->trackUID()));
-}
-
 WorkQueue& TrackReader::storageQueue()
 {
     static auto& queue = WorkQueue::create("WebKit::TrackReader Storage Queue", WorkQueue::Type::Serial).leakRef();
@@ -171,7 +155,7 @@
     return queue;
 }
 
-TrackReader::TrackReader(Allocator&& allocator, const FormatReader& formatReader, CMMediaType mediaType, uint64_t trackID)
+TrackReader::TrackReader(Allocator&& allocator, const FormatReader& formatReader, CMMediaType mediaType, uint64_t trackID, Optional<bool> enabled)
     : CoreMediaWrapped(WTFMove(allocator))
     , m_trackID(trackID)
     , m_mediaType(mediaType)
@@ -178,6 +162,9 @@
     , m_duration(formatReader.duration())
 {
     ASSERT(!isMainThread());
+
+    if (enabled)
+        m_isEnabled = enabled.value() ? Enabled::True : Enabled::False;
 }
 
 void TrackReader::addSample(Ref<MediaSample>&& sample, MTPluginByteSourceRef byteSource)
@@ -216,13 +203,16 @@
     if (!m_sampleStorage)
         m_sampleStorage = makeUnique<SampleStorage>();
     m_sampleStorage->hasAllSamples = true;
+    if (m_isEnabled == Enabled::Unknown)
+        m_isEnabled = m_sampleStorage->sampleMap.empty() ? Enabled::False : Enabled::True;
     m_sampleStorageCondition.notifyAll();
 }
 
 OSStatus TrackReader::copyProperty(CFStringRef key, CFAllocatorRef allocator, void* copiedValue)
 {
-    if (CFEqual(key, PAL::get_MediaToolbox_kMTPluginTrackReaderProperty_Enabled())) {
-        *reinterpret_cast<CFBooleanRef*>(copiedValue) = retainPtr(m_isEnabled ? kCFBooleanTrue : kCFBooleanFalse).leakRef();
+    // Don't block waiting for media if the we know the enabled state.
+    if (CFEqual(key, PAL::get_MediaToolbox_kMTPluginTrackReaderProperty_Enabled()) && m_isEnabled != Enabled::Unknown) {
+        *reinterpret_cast<CFBooleanRef*>(copiedValue) = retainPtr(m_isEnabled == Enabled::True ? kCFBooleanTrue : kCFBooleanFalse).leakRef();
         return noErr;
     }
 
@@ -232,6 +222,15 @@
     });
 
     auto& sampleMap = m_sampleStorage->sampleMap;
+
+    if (CFEqual(key, PAL::get_MediaToolbox_kMTPluginTrackReaderProperty_Enabled())) {
+        if (m_isEnabled == Enabled::Unknown)
+            m_isEnabled = sampleMap.empty() ? Enabled::False : Enabled::True;
+
+        *reinterpret_cast<CFBooleanRef*>(copiedValue) = retainPtr(m_isEnabled == Enabled::True ? kCFBooleanTrue : kCFBooleanFalse).leakRef();
+        return noErr;
+    }
+
     if (sampleMap.empty())
         return kCMBaseObjectError_ValueNotAvailable;
 

Modified: trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.h (271193 => 271194)


--- trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.h	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/Shared/mac/MediaFormatReader/TrackReader.h	2021-01-06 07:26:14 UTC (rev 271194)
@@ -54,19 +54,16 @@
     static constexpr WrapperClass wrapperClass();
     static CMBaseClassID wrapperClassID();
     static CoreMediaWrapped<TrackReader>* unwrap(CMBaseObjectRef);
+    static WTF::WorkQueue& storageQueue();
 
-    static RefPtr<TrackReader> create(Allocator&&, const FormatReader&, const WebCore::VideoTrackPrivate*);
-    static RefPtr<TrackReader> create(Allocator&&, const FormatReader&, const WebCore::AudioTrackPrivate*);
-    static RefPtr<TrackReader> create(Allocator&&, const FormatReader&, const WebCore::InbandTextTrackPrivate*);
+    static RefPtr<TrackReader> create(Allocator&&, const FormatReader&, CMMediaType, uint64_t, Optional<bool>);
 
-    static WTF::WorkQueue& storageQueue();
-
     uint64_t trackID() const { return m_trackID; }
     void addSample(Ref<WebCore::MediaSample>&&, MTPluginByteSourceRef);
     void waitForSample(Function<bool(WebCore::SampleMap&, bool)>&&) const;
 
-    bool isEnabled() const { return m_isEnabled; }
-    void setEnabled(bool enabled) { m_isEnabled = enabled; }
+    void setEnabled(bool enabled) { m_isEnabled = enabled ? Enabled::True : Enabled::False; }
+    CMMediaType mediaType() const { return m_mediaType; }
 
     void finishParsing();
 
@@ -73,7 +70,7 @@
 private:
     using CoreMediaWrapped<TrackReader>::unwrap;
 
-    TrackReader(Allocator&&, const FormatReader&, CMMediaType, uint64_t);
+    TrackReader(Allocator&&, const FormatReader&, CMMediaType, uint64_t, Optional<bool>);
 
     // CMBaseClass
     String debugDescription() const final { return "WebKit::TrackReader"_s; }
@@ -93,10 +90,12 @@
         bool hasAllSamples { false };
     };
 
+    enum Enabled : uint8_t { Unknown, False, True };
+
     const uint64_t m_trackID;
     const CMMediaType m_mediaType;
     const MediaTime m_duration;
-    std::atomic<bool> m_isEnabled { false };
+    std::atomic<Enabled> m_isEnabled { Enabled::Unknown };
     mutable Condition m_sampleStorageCondition;
     mutable Lock m_sampleStorageLock;
     mutable std::unique_ptr<SampleStorage> m_sampleStorage;

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (271193 => 271194)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-01-06 07:26:14 UTC (rev 271194)
@@ -3838,6 +3838,14 @@
             settings.setWebAuthenticationEnabled(true);
     }
 #endif
+
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    PlatformMediaSessionManager::setWebMFormatReaderEnabled(RuntimeEnabledFeatures::sharedFeatures().webMFormatReaderEnabled());
+#endif
+
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+    PlatformMediaSessionManager::setVorbisDecoderEnabled(RuntimeEnabledFeatures::sharedFeatures().vorbisDecoderEnabled());
+#endif
 }
 
 #if ENABLE(DATA_DETECTION)

Modified: trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm (271193 => 271194)


--- trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm	2021-01-06 05:59:24 UTC (rev 271193)
+++ trunk/Source/WebKit/WebProcess/cocoa/WebProcessCocoa.mm	2021-01-06 07:26:14 UTC (rev 271194)
@@ -68,7 +68,9 @@
 #import <WebCore/NSScrollerImpDetails.h>
 #import <WebCore/PerformanceLogging.h>
 #import <WebCore/PictureInPictureSupport.h>
+#import <WebCore/PlatformMediaSessionManager.h>
 #import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/RuntimeEnabledFeatures.h>
 #import <WebCore/SWContextManager.h>
 #import <WebCore/SystemBattery.h>
 #import <WebCore/SystemSoundManager.h>
@@ -328,6 +330,14 @@
     pthread_set_fixedpriority_self();
 #endif
 
+#if ENABLE(MEDIA_SOURCE) && HAVE(MT_PLUGIN_FORMAT_READER)
+    PlatformMediaSessionManager::setWebMFormatReaderEnabled(RuntimeEnabledFeatures::sharedFeatures().webMFormatReaderEnabled());
+#endif
+
+#if ENABLE(VORBIS) && PLATFORM(MAC)
+    PlatformMediaSessionManager::setVorbisDecoderEnabled(RuntimeEnabledFeatures::sharedFeatures().vorbisDecoderEnabled());
+#endif
+
     if (!parameters.mediaMIMETypes.isEmpty())
         setMediaMIMETypes(parameters.mediaMIMETypes);
     else {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to