Changeset 225813 in webkit
- Timestamp:
- Dec 12, 2017 3:12:20 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r225812 r225813 1 2017-12-12 Jer Noble <jer.noble@apple.com> 2 3 [EME] Support FPS-over-HLS in the Modern EME API 4 https://bugs.webkit.org/show_bug.cgi?id=180707 5 6 Reviewed by Eric Carlson. 7 8 Add support for the "skd" initDataType, where the initData is the URI provided in the 9 EXT-X-KEY tag in a HLS manifest: 10 11 * platform/graphics/avfoundation/CDMFairPlayStreaming.cpp: 12 (WebCore::CDMPrivateFairPlayStreaming::sinfName): 13 (WebCore::CDMPrivateFairPlayStreaming::skdName): 14 (WebCore::extractSinfData): 15 (WebCore::CDMPrivateFairPlayStreaming::sanitizeSkd): 16 (WebCore::CDMPrivateFairPlayStreaming::extractKeyIDsSkd): 17 (WebCore::validInitDataTypes): 18 (WebCore::CDMFactory::platformRegisterFactories): 19 (WebCore::CDMPrivateFairPlayStreaming::supportsInitDataType const): 20 (WebCore::CDMPrivateFairPlayStreaming::supportsConfiguration const): 21 (WebCore::CDMPrivateFairPlayStreaming::supportsInitData const): 22 (WebCore::sinfName): Deleted. 23 24 Add support for creating a AVContentKeyRequest from a skd key URI rather than from 25 initialization data, and for extracting keyIDs from the AVContentKeyRequest identifier. 26 27 * platform/graphics/avfoundation/CDMFairPlayStreaming.h: 28 * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h: 29 * platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm: 30 (WebCore::CDMInstanceFairPlayStreamingAVFObjC::keyIDs): 31 (WebCore::CDMInstanceFairPlayStreamingAVFObjC::requestLicense): 32 (WebCore::CDMInstanceFairPlayStreamingAVFObjC::updateLicense): 33 (WebCore::CDMInstanceFairPlayStreamingAVFObjC::didProvideRequest): 34 35 Add support for AVContentKeySession to MediaPlayerPrivateAVFoundationObjC, and for emitting 36 initializationData messages when encountering a loading request for a "skd" URI. 37 38 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h: 39 * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm: 40 (WebCore::MediaPlayerPrivateAVFoundationObjC::shouldWaitForLoadingOfResource): 41 (WebCore::MediaPlayerPrivateAVFoundationObjC::cdmInstanceAttached): 42 (WebCore::MediaPlayerPrivateAVFoundationObjC::cdmInstanceDetached): 43 (WebCore::MediaPlayerPrivateAVFoundationObjC::attemptToDecryptWithInstance): 44 1 45 2017-12-12 Antoine Quint <graouts@apple.com> 2 46 -
trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.cpp
r225766 r225813 63 63 } 64 64 65 static const String&sinfName()66 { 67 static NeverDestroyed< String> sinf { MAKE_STATIC_STRING_IMPL("sinf") };65 const AtomicString& CDMPrivateFairPlayStreaming::sinfName() 66 { 67 static NeverDestroyed<AtomicString> sinf { MAKE_STATIC_STRING_IMPL("sinf") }; 68 68 return sinf; 69 } 70 71 const AtomicString& CDMPrivateFairPlayStreaming::skdName() 72 { 73 static NeverDestroyed<AtomicString> skd { MAKE_STATIC_STRING_IMPL("skd") }; 74 return skd; 69 75 } 70 76 … … 85 91 86 92 RefPtr<JSON::Array> sinfArray; 87 if (!object->getArray( sinfName(), sinfArray))93 if (!object->getArray(CDMPrivateFairPlayStreaming::sinfName(), sinfArray)) 88 94 return { }; 89 95 … … 175 181 } 176 182 183 RefPtr<SharedBuffer> CDMPrivateFairPlayStreaming::sanitizeSkd(const SharedBuffer& buffer) 184 { 185 UNUSED_PARAM(buffer); 186 notImplemented(); 187 return buffer.copy(); 188 } 189 190 Vector<Ref<SharedBuffer>> CDMPrivateFairPlayStreaming::extractKeyIDsSkd(const SharedBuffer& buffer) 191 { 192 // In the 'skd' scheme, the init data is the key ID. 193 Vector<Ref<SharedBuffer>> keyIDs; 194 keyIDs.append(buffer.copy()); 195 return keyIDs; 196 } 197 198 static const HashSet<AtomicString>& validInitDataTypes() 199 { 200 static NeverDestroyed<HashSet<AtomicString>> validTypes = HashSet<AtomicString>({ CDMPrivateFairPlayStreaming::sinfName(), CDMPrivateFairPlayStreaming::skdName() }); 201 return validTypes; 202 } 203 177 204 void CDMFactory::platformRegisterFactories(Vector<CDMFactory*>& factories) 178 205 { … … 180 207 factories.append(&CDMFactoryFairPlayStreaming::singleton()); 181 208 182 InitDataRegistry::shared().registerInitDataType(sinfName(), { CDMPrivateFairPlayStreaming::sanitizeSinf, CDMPrivateFairPlayStreaming::extractKeyIDsSinf }); 209 InitDataRegistry::shared().registerInitDataType(CDMPrivateFairPlayStreaming::sinfName(), { CDMPrivateFairPlayStreaming::sanitizeSinf, CDMPrivateFairPlayStreaming::extractKeyIDsSinf }); 210 InitDataRegistry::shared().registerInitDataType(CDMPrivateFairPlayStreaming::skdName(), { CDMPrivateFairPlayStreaming::sanitizeSkd, CDMPrivateFairPlayStreaming::extractKeyIDsSkd }); 183 211 } 184 212 … … 212 240 bool CDMPrivateFairPlayStreaming::supportsInitDataType(const AtomicString& initDataType) const 213 241 { 214 return initDataType == sinfName();242 return validInitDataTypes().contains(initDataType); 215 243 } 216 244 217 245 bool CDMPrivateFairPlayStreaming::supportsConfiguration(const CDMKeySystemConfiguration& configuration) const 218 246 { 219 if (! configuration.initDataTypes.contains(sinfName()))247 if (!WTF::anyOf(configuration.initDataTypes, [] (auto& initDataType) { return validInitDataTypes().contains(initDataType); })) 220 248 return false; 221 249 … … 332 360 return false; 333 361 334 return WTF::anyOf(extractSchemeAndKeyIdFromSinf(initData), [](auto& result) { 335 return validFairPlayStreamingSchemes().contains(result.first); 336 }); 362 if (initDataType == sinfName()) { 363 return WTF::anyOf(extractSchemeAndKeyIdFromSinf(initData), [](auto& result) { 364 return validFairPlayStreamingSchemes().contains(result.first); 365 }); 366 } 367 368 if (initDataType == skdName()) 369 return true; 370 371 ASSERT_NOT_REACHED(); 372 return false; 337 373 } 338 374 -
trunk/Source/WebCore/platform/graphics/avfoundation/CDMFairPlayStreaming.h
r225637 r225813 66 66 std::optional<String> sanitizeSessionId(const String&) const override; 67 67 68 static const AtomicString& sinfName(); 68 69 static Vector<Ref<SharedBuffer>> extractKeyIDsSinf(const SharedBuffer&); 69 70 static RefPtr<SharedBuffer> sanitizeSinf(const SharedBuffer&); 71 72 static const AtomicString& skdName(); 73 static Vector<Ref<SharedBuffer>> extractKeyIDsSkd(const SharedBuffer&); 74 static RefPtr<SharedBuffer> sanitizeSkd(const SharedBuffer&); 70 75 }; 71 76 -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.h
r225802 r225813 82 82 bool isLicenseTypeSupported(LicenseType) const; 83 83 84 Vector<Ref<SharedBuffer>> keyIDs(); 85 84 86 WeakPtrFactory<CDMInstanceFairPlayStreamingAVFObjC> m_weakPtrFactory; 85 87 RefPtr<SharedBuffer> m_serverCertificate; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm
r225802 r225813 226 226 } 227 227 228 void CDMInstanceFairPlayStreamingAVFObjC::requestLicense(LicenseType licenseType, const AtomicString&, Ref<SharedBuffer>&& initData, LicenseCallback callback) 228 Vector<Ref<SharedBuffer>> CDMInstanceFairPlayStreamingAVFObjC::keyIDs() 229 { 230 // FIXME(rdar://problem/35597141): use the future AVContentKeyRequest keyID property, rather than parsing it out of the init 231 // data, to get the keyID. 232 if ([m_request.get().identifier isKindOfClass:[NSString class]]) 233 return Vector<Ref<SharedBuffer>>::from(SharedBuffer::create([(NSString *)m_request.get().identifier dataUsingEncoding:NSUTF8StringEncoding])); 234 if ([m_request.get().identifier isKindOfClass:[NSData class]]) 235 return Vector<Ref<SharedBuffer>>::from(SharedBuffer::create((NSData *)m_request.get().identifier)); 236 if (m_request.get().initializationData) 237 return CDMPrivateFairPlayStreaming::extractKeyIDsSinf(SharedBuffer::create(m_request.get().initializationData)); 238 return { }; 239 } 240 241 void CDMInstanceFairPlayStreamingAVFObjC::requestLicense(LicenseType licenseType, const AtomicString& initDataType, Ref<SharedBuffer>&& initData, LicenseCallback callback) 229 242 { 230 243 if (!isLicenseTypeSupported(licenseType)) { … … 238 251 } 239 252 253 RetainPtr<NSString> identifier; 254 RetainPtr<NSData> initializationData; 255 256 if (initDataType == CDMPrivateFairPlayStreaming::sinfName()) 257 initializationData = initData->createNSData(); 258 else if (initDataType == CDMPrivateFairPlayStreaming::skdName()) 259 identifier = adoptNS([[NSString alloc] initWithData:initData->createNSData().get() encoding:NSUTF8StringEncoding]); 260 else { 261 callback(SharedBuffer::create(), emptyString(), false, Failed); 262 return; 263 } 264 240 265 m_requestLicenseCallback = WTFMove(callback); 241 242 [m_session processContentKeyRequestWithIdentifier:nil initializationData:initData->createNSData().get() options:nil]; 266 [m_session processContentKeyRequestWithIdentifier:identifier.get() initializationData:initializationData.get() options:nil]; 243 267 } 244 268 … … 277 301 return; 278 302 } 279 // FIXME(rdar://problem/35597141): use the future AVContentKeyRequest keyID property, rather than parsing it out of the init 280 // data, to get the keyID. 281 Vector<Ref<SharedBuffer>> keyIDs = CDMPrivateFairPlayStreaming::extractKeyIDsSinf(SharedBuffer::create(m_request.get().initializationData)); 303 Vector<Ref<SharedBuffer>> keyIDs = this->keyIDs(); 282 304 if (keyIDs.isEmpty()) { 283 305 callback(false, std::nullopt, std::nullopt, std::nullopt, Failed); … … 401 423 402 424 RetainPtr<NSData> appIdentifier = m_serverCertificate ? m_serverCertificate->createNSData() : nullptr; 403 Vector<Ref<SharedBuffer>> keyIDs = CDMPrivateFairPlayStreaming::extractKeyIDsSinf(SharedBuffer::create(request.initializationData)); 425 Vector<Ref<SharedBuffer>> keyIDs = this->keyIDs(); 426 404 427 if (keyIDs.isEmpty()) { 405 428 m_requestLicenseCallback(SharedBuffer::create(), m_sessionId, false, Failed); -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
r225638 r225813 64 64 class AudioSourceProviderAVFObjC; 65 65 class AudioTrackPrivateAVFObjC; 66 class CDMInstanceFairPlayStreamingAVFObjC; 66 67 class CDMSessionAVFoundationObjC; 67 68 class InbandMetadataTextTrackPrivateAVF; … … 154 155 #endif 155 156 157 #if ENABLE(ENCRYPTED_MEDIA) 158 void cdmInstanceAttached(CDMInstance&) final; 159 void cdmInstanceDetached(CDMInstance&) final; 160 void attemptToDecryptWithInstance(CDMInstance&) final; 161 #endif 162 156 163 WeakPtr<MediaPlayerPrivateAVFoundationObjC> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); } 157 164 … … 397 404 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) 398 405 WeakPtr<CDMSessionAVFoundationObjC> m_session; 406 #endif 407 #if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION) 408 RefPtr<CDMInstanceFairPlayStreamingAVFObjC> m_cdmInstance; 399 409 #endif 400 410 -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
r225696 r225813 35 35 #import "AudioTrackPrivateAVFObjC.h" 36 36 #import "AuthenticationChallenge.h" 37 #import "CDMInstanceFairPlayStreamingAVFObjC.h" 37 38 #import "CDMSessionAVFoundationObjC.h" 38 39 #import "Cookie.h" … … 55 56 #import "SecurityOrigin.h" 56 57 #import "SerializedPlatformRepresentationMac.h" 58 #import "SharedBuffer.h" 57 59 #import "TextEncoding.h" 58 60 #import "TextTrackRepresentation.h" … … 1767 1769 String keyURI = [[[avRequest request] URL] absoluteString]; 1768 1770 1771 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) || ENABLE(ENCRYPTED_MEDIA) 1772 if (scheme == "skd") { 1769 1773 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) 1770 if (scheme == "skd") {1771 1774 // Create an initData with the following layout: 1772 1775 // [4 bytes: keyURI size], [keyURI size bytes: keyURI] … … 1783 1786 if (!player()->keyNeeded(initData.get())) 1784 1787 return false; 1785 1788 #endif 1786 1789 m_keyURIToRequestMap.set(keyURI, avRequest); 1790 #if ENABLE(ENCRYPTED_MEDIA) && HAVE(AVCONTENTKEYSESSION) 1791 if (m_cdmInstance) 1792 return false; 1793 1794 RetainPtr<NSData> keyURIData = [keyURI dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 1795 auto keyURIBuffer = SharedBuffer::create(keyURIData.get()); 1796 player()->initializationDataEncountered(ASCIILiteral("skd"), keyURIBuffer->tryCreateArrayBuffer()); 1797 #endif 1787 1798 return true; 1788 1799 } 1789 1800 1801 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) 1790 1802 if (scheme == "clearkey") { 1791 1803 String keyID = [[[avRequest request] URL] resourceSpecifier]; … … 1807 1819 return true; 1808 1820 } 1821 #endif 1809 1822 #endif 1810 1823 … … 2476 2489 } 2477 2490 2491 #endif 2492 2493 #if ENABLE(ENCRYPTED_MEDIA) 2494 void MediaPlayerPrivateAVFoundationObjC::cdmInstanceAttached(CDMInstance& instance) 2495 { 2496 #if HAVE(AVCONTENTKEYSESSION) 2497 if (!is<CDMInstanceFairPlayStreamingAVFObjC>(instance)) 2498 return; 2499 2500 auto& fpsInstance = downcast<CDMInstanceFairPlayStreamingAVFObjC>(instance); 2501 if (&fpsInstance == m_cdmInstance) 2502 return; 2503 2504 if (m_cdmInstance) 2505 cdmInstanceDetached(*m_cdmInstance); 2506 2507 m_cdmInstance = &fpsInstance; 2508 [m_cdmInstance->contentKeySession() addContentKeyRecipient:m_avAsset.get()]; 2509 #else 2510 UNUSED_PARAM(instance); 2511 #endif 2512 } 2513 2514 void MediaPlayerPrivateAVFoundationObjC::cdmInstanceDetached(CDMInstance& instance) 2515 { 2516 #if HAVE(AVCONTENTKEYSESSION) 2517 ASSERT_UNUSED(instance, m_cdmInstance && m_cdmInstance == &instance); 2518 [m_cdmInstance->contentKeySession() removeContentKeyRecipient:m_avAsset.get()]; 2519 m_cdmInstance = nullptr; 2520 #else 2521 UNUSED_PARAM(instance); 2522 #endif 2523 } 2524 2525 void MediaPlayerPrivateAVFoundationObjC::attemptToDecryptWithInstance(CDMInstance&) 2526 { 2527 auto keyURIToRequestMap = WTFMove(m_keyURIToRequestMap); 2528 for (auto& request : keyURIToRequestMap.values()) 2529 [request finishLoading]; 2530 } 2478 2531 #endif 2479 2532
Note: See TracChangeset
for help on using the changeset viewer.