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
# (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"
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"
+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
</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
<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
#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>
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
#include "MediaPlayerPrivate.h"
#include "Timer.h"
#include <functional>
+#include <wtf/HashSet.h>
#include <wtf/RetainPtr.h>
#include <wtf/WeakPtr.h>
virtual void updateVideoLayerGravity() = 0;
+ static bool isUnsupportedMIMEType(const String&);
+ static const HashSet<String>& staticMIMETypeList();
+
protected:
void updateStates();
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
#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>
}
#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)
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;
}
}
-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 = [] () {