be47667ccd372fbad6aee0ed58eb8436752db887
[WebKit-https.git] / Source / WebCore / platform / graphics / avfoundation / objc / AVFoundationMIMETypeCache.mm
1 /*
2  * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #import "config.h"
27 #import "AVFoundationMIMETypeCache.h"
28
29 #if PLATFORM(COCOA)
30
31 #import "ContentType.h"
32 #import <wtf/HashSet.h>
33
34 #import <pal/cf/CoreMediaSoftLink.h>
35 #import <pal/cocoa/AVFoundationSoftLink.h>
36
37 #if !PLATFORM(IOSMAC)
38 SOFT_LINK_FRAMEWORK_OPTIONAL_PREFLIGHT(AVFoundation)
39 #endif
40
41 namespace WebCore {
42
43 AVFoundationMIMETypeCache& AVFoundationMIMETypeCache::singleton()
44 {
45     static NeverDestroyed<AVFoundationMIMETypeCache> cache;
46     return cache.get();
47 }
48
49 void AVFoundationMIMETypeCache::setSupportedTypes(const Vector<String>& types)
50 {
51     if (m_cache)
52         return;
53
54     m_cache = HashSet<String, ASCIICaseInsensitiveHash>();
55     for (auto& type : types)
56         m_cache->add(type);
57 }
58
59 const HashSet<String, ASCIICaseInsensitiveHash>& AVFoundationMIMETypeCache::types()
60 {
61     if (!m_cache)
62         loadMIMETypes();
63
64     return *m_cache;
65 }
66
67 bool AVFoundationMIMETypeCache::supportsContentType(const ContentType& contentType)
68 {
69     if (contentType.isEmpty())
70         return false;
71
72     return types().contains(contentType.containerType());
73 }
74
75 bool AVFoundationMIMETypeCache::canDecodeType(const String& mimeType)
76 {
77     if (mimeType.isEmpty())
78         return false;
79
80     if (!isAvailable() || !types().contains(ContentType { mimeType }.containerType()))
81         return false;
82
83 #if ENABLE(VIDEO) && USE(AVFOUNDATION)
84     return [PAL::getAVURLAssetClass() isPlayableExtendedMIMEType:mimeType];
85 #endif
86
87     return false;
88 }
89
90 bool AVFoundationMIMETypeCache::isAvailable() const
91 {
92 #if ENABLE(VIDEO) && USE(AVFOUNDATION)
93 #if PLATFORM(IOSMAC)
94     // FIXME: This should be using AVFoundationLibraryIsAvailable() instead, but doing so causes soft-linking
95     // to subsequently fail on certain symbols. See <rdar://problem/42224780> for more details.
96     return AVFoundationLibrary();
97 #else
98     return AVFoundationLibraryIsAvailable();
99 #endif
100 #else
101     return false;
102 #endif
103 }
104
105 void AVFoundationMIMETypeCache::loadMIMETypes()
106 {
107     m_cache = HashSet<String, ASCIICaseInsensitiveHash>();
108
109 #if ENABLE(VIDEO) && USE(AVFOUNDATION)
110     static std::once_flag onceFlag;
111     std::call_once(onceFlag, [this] {
112         if (!PAL::AVFoundationLibrary())
113             return;
114
115         for (NSString* type in [PAL::getAVURLAssetClass() audiovisualMIMETypes])
116             m_cache->add(type);
117
118         if (m_cacheTypeCallback)
119             m_cacheTypeCallback(copyToVector(*m_cache));
120     });
121 #endif
122 }
123
124 }
125
126 #endif