[Win] Update MediaPlayerPrivateAVFoundationCF::supportsType
authorbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2015 19:37:43 +0000 (19:37 +0000)
committerbfulgham@apple.com <bfulgham@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Jun 2015 19:37:43 +0000 (19:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146302
<rdar://problem/19726553>

Reviewed by Eric Carlson.

Tested by existing media tests.

Update the AVFoundationCF version of 'supportsType' to more closely match the AVFoundation
version. Use this new code when the necessary AVFoundationCF functions are present.

* AVFoundationSupport.py: Check for presence of AVCFURLAssetIsPlayableExtendedMIMEType.
(fileContains): Added helper function.
* WebCore.vcxproj/WebCoreGenerated.vcxproj: Add AVFoundationSupport.py to project file to make
maintenance easier.
* WebCore.vcxproj/WebCoreGenerated.vcxproj.filters: Ditto.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
(WebCore::MediaPlayerPrivateAVFoundation::isUnsupportedMIMEType): Moved from ObjC version.
(WebCore::MediaPlayerPrivateAVFoundation::staticMIMETypeList): Ditto.
* platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
* platform/graphics/avfoundation/cf/AVFoundationCFSoftLinking.h: Add missing declaration.
* platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
(WebCore::avfMIMETypes): Added CF version of AVFoundation code.
(WebCore::MediaPlayerPrivateAVFoundationCF::supportsType): Update to use new AVCF
method if it is available.
(WebCore::MediaPlayerPrivateAVFoundationCF::languageOfPrimaryAudioTrack): Handle case of a
null language locale. This is a drive-by fix of a bug found during testing.
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::isUnsupportedMIMEType): Deleted.
(WebCore::staticMIMETypeList): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185958 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/AVFoundationSupport.py
Source/WebCore/ChangeLog
Source/WebCore/WebCore.vcxproj/WebCoreGenerated.vcxproj
Source/WebCore/WebCore.vcxproj/WebCoreGenerated.vcxproj.filters
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp
Source/WebCore/platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h
Source/WebCore/platform/graphics/avfoundation/cf/AVFoundationCFSoftLinking.h
Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm

index 41a2159..9cdbe5a 100644 (file)
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import re
 import sys
 import os
 
-
 def lookFor(relativePath):
     return os.path.isfile(os.environ['WEBKIT_LIBRARIES'] + relativePath)
 
+
+def fileContains(relativePath, regexp):
+    with open(os.environ['WEBKIT_LIBRARIES'] + relativePath) as file:
+        for line in file:
+            if regexp.search(line):
+                return True
+    return False
+
+
 print "/* Identifying AVFoundation Support */"
 if lookFor("/include/AVFoundationCF/AVCFBase.h"):
     print "#define HAVE_AVCF 1"
@@ -40,3 +49,7 @@ if lookFor("/include/AVFoundationCF/AVCFPlayerItemLegibleOutput.h"):
     print "#define HAVE_AVCF_LEGIBLE_OUTPUT 1"
 if lookFor("/include/AVFoundationCF/AVCFAssetResourceLoader.h"):
     print "#define HAVE_AVFOUNDATION_LOADER_DELEGATE 1"
+if lookFor("/include/AVFoundationCF/AVCFAsset.h"):
+    regexp = re.compile("AVCFURLAssetIsPlayableExtendedMIMEType")
+    if fileContains("/include/AVFoundationCF/AVCFAsset.h", regexp):
+        print "#define HAVE_AVCFURL_PLAYABLE_MIMETYPE 1"
index 9f7d28f..e28a778 100644 (file)
@@ -1,3 +1,36 @@
+2015-06-25  Brent Fulgham  <bfulgham@apple.com>
+
+        [Win] Update MediaPlayerPrivateAVFoundationCF::supportsType
+        https://bugs.webkit.org/show_bug.cgi?id=146302
+        <rdar://problem/19726553>
+
+        Reviewed by Eric Carlson.
+
+        Tested by existing media tests.
+
+        Update the AVFoundationCF version of 'supportsType' to more closely match the AVFoundation
+        version. Use this new code when the necessary AVFoundationCF functions are present.
+
+        * AVFoundationSupport.py: Check for presence of AVCFURLAssetIsPlayableExtendedMIMEType.
+        (fileContains): Added helper function.
+        * WebCore.vcxproj/WebCoreGenerated.vcxproj: Add AVFoundationSupport.py to project file to make
+        maintenance easier.
+        * WebCore.vcxproj/WebCoreGenerated.vcxproj.filters: Ditto.
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.cpp:
+        (WebCore::MediaPlayerPrivateAVFoundation::isUnsupportedMIMEType): Moved from ObjC version.
+        (WebCore::MediaPlayerPrivateAVFoundation::staticMIMETypeList): Ditto.
+        * platform/graphics/avfoundation/MediaPlayerPrivateAVFoundation.h:
+        * platform/graphics/avfoundation/cf/AVFoundationCFSoftLinking.h: Add missing declaration.
+        * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp:
+        (WebCore::avfMIMETypes): Added CF version of AVFoundation code.
+        (WebCore::MediaPlayerPrivateAVFoundationCF::supportsType): Update to use new AVCF
+        method if it is available.
+        (WebCore::MediaPlayerPrivateAVFoundationCF::languageOfPrimaryAudioTrack): Handle case of a
+        null language locale. This is a drive-by fix of a bug found during testing.
+        * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+        (WebCore::isUnsupportedMIMEType): Deleted.
+        (WebCore::staticMIMETypeList): Deleted.
+
 2015-06-25  Matthew Daiter  <mdaiter@apple.com>
 
         Enabling MEDIA_STREAM
index 7d0def0..d706bfb 100644 (file)
@@ -51,6 +51,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <ItemGroup>
+    <None Include="..\AVFoundationSupport.py" />
     <None Include="..\DerivedSources.make" />
     <None Include="build-generated-files.pl" />
     <None Include="copyForwardingHeaders.cmd" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index c66c30c..263cd2e 100644 (file)
@@ -8,5 +8,6 @@
     <None Include="..\DerivedSources.make" />
     <None Include="build-generated-files.pl" />
     <None Include="migrate-scripts.pl" />
+    <None Include="..\AVFoundationSupport.py" />
   </ItemGroup>
 </Project>
\ No newline at end of file
index b2a7c1b..c5df5e9 100644 (file)
@@ -44,6 +44,7 @@
 #include <runtime/DataView.h>
 #include <runtime/Uint16Array.h>
 #include <wtf/MainThread.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/CString.h>
 #include <wtf/StringPrintStream.h>
 
@@ -1077,6 +1078,77 @@ bool MediaPlayerPrivateAVFoundation::canSaveMediaData() const
     return true;
 }
 
+bool MediaPlayerPrivateAVFoundation::isUnsupportedMIMEType(const String& type)
+{
+    String lowerCaseType = type.convertToASCIILowercase();
+
+    // AVFoundation will return non-video MIME types which it claims to support, but which we
+    // do not support in the <video> element. Reject all non video/, audio/, and application/ types.
+    if (!lowerCaseType.startsWith("video/") && !lowerCaseType.startsWith("audio/") && !lowerCaseType.startsWith("application/"))
+        return true;
+
+    // Reject types we know AVFoundation does not support that sites commonly ask about.
+    if (lowerCaseType == "video/webm" || lowerCaseType == "audio/webm" || lowerCaseType == "video/x-webm")
+        return true;
+
+    if (lowerCaseType == "video/x-flv")
+        return true;
+
+    if (lowerCaseType == "audio/ogg" || lowerCaseType == "video/ogg" || lowerCaseType == "application/ogg")
+        return true;
+
+    if (lowerCaseType == "video/h264")
+        return true;
+
+    return false;
+}
+
+const HashSet<String>& MediaPlayerPrivateAVFoundation::staticMIMETypeList()
+{
+    static NeverDestroyed<HashSet<String>> cache = []() {
+        HashSet<String> types;
+
+        static const char* typeNames[] = {
+            "application/vnd.apple.mpegurl",
+            "application/x-mpegurl",
+            "audio/3gpp",
+            "audio/aac",
+            "audio/aacp",
+            "audio/aiff",
+            "audio/basic",
+            "audio/mp3",
+            "audio/mp4",
+            "audio/mpeg",
+            "audio/mpeg3",
+            "audio/mpegurl",
+            "audio/mpg",
+            "audio/wav",
+            "audio/wave",
+            "audio/x-aac",
+            "audio/x-aiff",
+            "audio/x-m4a",
+            "audio/x-mpegurl",
+            "audio/x-wav",
+            "video/3gpp",
+            "video/3gpp2",
+            "video/mp4",
+            "video/mpeg",
+            "video/mpeg2",
+            "video/mpg",
+            "video/quicktime",
+            "video/x-m4v",
+            "video/x-mpeg",
+            "video/x-mpg",
+        };
+        for (size_t i = 0; i < WTF_ARRAY_LENGTH(typeNames); ++i)
+            types.add(typeNames[i]);
+
+        return types;
+    }();
+
+    return cache;
+}
+
 } // namespace WebCore
 
 #endif
index 6d8572e..7a28afd 100644 (file)
@@ -33,6 +33,7 @@
 #include "MediaPlayerPrivate.h"
 #include "Timer.h"
 #include <functional>
+#include <wtf/HashSet.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/WeakPtr.h>
 
@@ -256,6 +257,9 @@ protected:
 
     virtual void updateVideoLayerGravity() = 0;
 
+    static bool isUnsupportedMIMEType(const String&);
+    static const HashSet<String>& staticMIMETypeList();
+
 protected:
     void updateStates();
 
index a7ce21e..624c697 100644 (file)
@@ -305,6 +305,8 @@ SOFT_LINK_DLL_IMPORT(AVFoundationCF, AVCFAssetResourceLoadingRequestGetURLReques
 SOFT_LINK_DLL_IMPORT(AVFoundationCF, AVCFAssetResourceLoadingRequestFinishLoadingWithResponse, void, __cdecl, (AVCFAssetResourceLoadingRequestRef loadingRequest, CFURLResponseRef response, CFDataRef data, CFURLRequestRef redirect), (loadingRequest, response, data, redirect))
 #define AVCFAssetResourceLoadingRequestFinishLoadingWithResponse  softLink_AVCFAssetResourceLoadingRequestFinishLoadingWithResponse 
 
+SOFT_LINK_DLL_IMPORT(AVFoundationCF, AVCFURLAssetIsPlayableExtendedMIMEType, Boolean, __cdecl, (CFStringRef extendedMIMEType), (extendedMIMEType))
+#define AVCFURLAssetIsPlayableExtendedMIMEType  softLink_AVCFURLAssetIsPlayableExtendedMIMEType 
 #endif
 
 // Variables
index e4addce..72897dc 100644 (file)
@@ -65,6 +65,7 @@
 #include <runtime/Uint16Array.h>
 #endif
 #include <wtf/HashMap.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/Threading.h>
 #include <wtf/text/CString.h>
 #include <wtf/text/StringView.h>
@@ -906,14 +907,45 @@ static bool keySystemIsSupported(const String& keySystem)
 }
 #endif
 
+static const HashSet<String>& avfMIMETypes()
+{
+    static NeverDestroyed<HashSet<String>> cache = []() {
+        HashSet<String> types;
+        RetainPtr<CFArrayRef> avTypes = AVCFURLAssetCopyAudiovisualMIMETypes();
+
+        CFIndex typeCount = CFArrayGetCount(avTypes.get());
+        for (CFIndex i = 0; i < typeCount; ++i) {
+            String mimeType = (CFStringRef)(CFArrayGetValueAtIndex(avTypes.get(), i));
+            types.add(mimeType.lower());
+        }
+
+        return types;
+    }();
+
+    return cache;
+}
+
 MediaPlayer::SupportsType MediaPlayerPrivateAVFoundationCF::supportsType(const MediaEngineSupportParameters& parameters)
 {
-    // Only return "IsSupported" if there is no codecs parameter for now as there is no way to ask if it supports an
-    // extended MIME type until rdar://8721715 is fixed.
+    if (isUnsupportedMIMEType(parameters.type))
+        return MediaPlayer::IsNotSupported;
+
+    if (!staticMIMETypeList().contains(parameters.type) && !avfMIMETypes().contains(parameters.type))
+        return MediaPlayer::IsNotSupported;
+
+#if HAVE(AVCFURL_PLAYABLE_MIMETYPE)
+    // The spec says:
+    // "Implementors are encouraged to return "maybe" unless the type can be confidently established as being supported or not."
+    if (parameters.codecs.isEmpty())
+        return MediaPlayer::MayBeSupported;
+
+    String typeString = parameters.type + "; codecs=\"" + parameters.codecs + "\"";
+    return AVCFURLAssetIsPlayableExtendedMIMEType(typeString.createCFString().get()) ? MediaPlayer::IsSupported : MediaPlayer::MayBeSupported;
+#else
     if (mimeTypeCache().contains(parameters.type))
         return parameters.codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported;
-
     return MediaPlayer::IsNotSupported;
+#endif
 }
 
 bool MediaPlayerPrivateAVFoundationCF::supportsKeySystem(const String& keySystem, const String& mimeType)
@@ -1273,7 +1305,11 @@ String MediaPlayerPrivateAVFoundationCF::languageOfPrimaryAudioTrack() const
     AVCFMediaSelectionOptionRef currentlySelectedAudibleOption = AVCFPlayerItemGetSelectedMediaOptionInMediaSelectionGroup(avPlayerItem(m_avfWrapper), audibleGroup);
     if (currentlySelectedAudibleOption) {
         RetainPtr<CFLocaleRef> audibleOptionLocale = adoptCF(AVCFMediaSelectionOptionCopyLocale(currentlySelectedAudibleOption));
-        m_languageOfPrimaryAudioTrack = CFLocaleGetIdentifier(audibleOptionLocale.get());
+        if (audibleOptionLocale)
+            m_languageOfPrimaryAudioTrack = CFLocaleGetIdentifier(audibleOptionLocale.get());
+        else
+            m_languageOfPrimaryAudioTrack = emptyString();
+
         LOG(Media, "MediaPlayerPrivateAVFoundationCF::languageOfPrimaryAudioTrack(%p) - returning language of selected audible option: %s", this, m_languageOfPrimaryAudioTrack.utf8().data());
 
         return m_languageOfPrimaryAudioTrack;
index 8f3d33a..5b7da08 100644 (file)
@@ -1532,77 +1532,6 @@ void MediaPlayerPrivateAVFoundationObjC::paintWithImageGenerator(GraphicsContext
     }
 }
 
-static bool isUnsupportedMIMEType(const String& type)
-{
-    String lowerCaseType = type.convertToASCIILowercase();
-
-    // AVFoundation will return non-video MIME types which it claims to support, but which we
-    // do not support in the <video> element. Reject all non video/, audio/, and application/ types.
-    if (!lowerCaseType.startsWith("video/") && !lowerCaseType.startsWith("audio/") && !lowerCaseType.startsWith("application/"))
-        return true;
-
-    // Reject types we know AVFoundation does not support that sites commonly ask about.
-    if (lowerCaseType == "video/webm" || lowerCaseType == "audio/webm" || lowerCaseType == "video/x-webm")
-        return true;
-
-    if (lowerCaseType == "video/x-flv")
-        return true;
-
-    if (lowerCaseType == "audio/ogg" || lowerCaseType == "video/ogg" || lowerCaseType == "application/ogg")
-        return true;
-
-    if (lowerCaseType == "video/h264")
-        return true;
-
-    return false;
-}
-
-static const HashSet<String>& staticMIMETypeList()
-{
-    static NeverDestroyed<HashSet<String>> cache = [] () {
-        HashSet<String> types;
-
-        static const char* typeNames[] = {
-            "application/vnd.apple.mpegurl",
-            "application/x-mpegurl",
-            "audio/3gpp",
-            "audio/aac",
-            "audio/aacp",
-            "audio/aiff",
-            "audio/basic",
-            "audio/mp3",
-            "audio/mp4",
-            "audio/mpeg",
-            "audio/mpeg3",
-            "audio/mpegurl",
-            "audio/mpg",
-            "audio/wav",
-            "audio/wave",
-            "audio/x-aac",
-            "audio/x-aiff",
-            "audio/x-m4a",
-            "audio/x-mpegurl",
-            "audio/x-wav",
-            "video/3gpp",
-            "video/3gpp2",
-            "video/mp4",
-            "video/mpeg",
-            "video/mpeg2",
-            "video/mpg",
-            "video/quicktime",
-            "video/x-m4v",
-            "video/x-mpeg",
-            "video/x-mpg",
-        };
-        for (size_t i = 0; i < WTF_ARRAY_LENGTH(typeNames); ++i)
-            types.add(typeNames[i]);
-
-        return types;
-    }();
-
-    return cache;
-}
-
 static const HashSet<String>& avfMIMETypes()
 {
     static NeverDestroyed<HashSet<String>> cache = [] () {