<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[178472] branches/safari-600.5-branch/Source/WebCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/178472">178472</a></dd>
<dt>Author</dt> <dd>dburkart@apple.com</dd>
<dt>Date</dt> <dd>2015-01-14 18:40:11 -0800 (Wed, 14 Jan 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/175000">r175000</a>. <rdar://problem/19424156></pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari6005branchSourceWebCoreChangeLog">branches/safari-600.5-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcCDMSessionMediaSourceAVFObjCh">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcCDMSessionMediaSourceAVFObjCmm">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcSourceBufferPrivateAVFObjCh">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h</a></li>
<li><a href="#branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcSourceBufferPrivateAVFObjCmm">branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari6005branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/ChangeLog (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/ChangeLog        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/ChangeLog        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -1,5 +1,60 @@
</span><span class="cx"> 2015-01-14 Dana Burkart <dburkart@apple.com>
</span><span class="cx">
</span><ins>+ Merged r175000. <rdar://problem/19424156>
+
+ 2014-10-21 Jer Noble <jer.noble@apple.com>
+
+ [EME][Mac] Update to match new AVStreamSession API and requirements.
+ https://bugs.webkit.org/show_bug.cgi?id=137923
+
+ Reviewed by Eric Carlson.
+
+ The session identifier has moved from AVStreamDataParser to -[AVStreamSession contentProtectionSessionIdentifier]
+ and the property is no longer KVObservable. A new notification key has been added in place of KVO.
+
+ Additionally, the requirements for using AVStreamDataParser with AVStreamSession have changed. It is now
+ required that AVStreamDataParsers be added to an AVStreamSession before the
+ -streamSession:didProvideContentKeyRequestInitializationData:forTrackID delegate method is called. A
+ -streamParserWillProvideContentKeyRequestInitializationData:forTrackID delegate has been added, and
+ an AVStreamSession must be created and the AVStreamDataParser added to it during the scope of that delegate
+ method.
+
+ To facilitate this, the MediaPlayerPrivateMediaSourceAVFObjC object will lazily create and own a AVStreamSession
+ object when requested. The SourceBufferPrivateAVFObjC object will listen for the -willProvide delegate call
+ and will add its AVStreamDataParser to that AVStreamSession when called.
+
+ The CDMSessionMediaSourceAVFObjC object is no longer responsible for creating the AVStreamSession, and because
+ the session identifier has moved from many AVStreamDataParsers to a single AVStreamSession, the
+ CDMSessionMediaSourceAVFObjCObserver class can become much simpler, as it only has to observe a single object.
+
+ * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h:
+ * platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm:
+ (-[CDMSessionMediaSourceAVFObjCObserver dealloc]): Deleted.
+ (-[CDMSessionMediaSourceAVFObjCObserver beginObserving:]): Deleted.
+ (-[CDMSessionMediaSourceAVFObjCObserver stopObserving:]): Deleted.
+ (-[CDMSessionMediaSourceAVFObjCObserver invalidate]): Deleted.
+ (-[CDMSessionMediaSourceAVFObjCObserver observeValueForKeyPath:ofObject:change:context:]): Deleted.
+ (-[CDMSessionMediaSourceAVFObjCObserver contentProtectionSessionIdentifierChanged:]): Added.
+ (WebCore::CDMSessionMediaSourceAVFObjC::~CDMSessionMediaSourceAVFObjC): Call setStreamSession(nullptr).
+ (WebCore::CDMSessionMediaSourceAVFObjC::releaseKeys): The sessionId is now a value in the dictionary, not the key.
+ (WebCore::CDMSessionMediaSourceAVFObjC::update): No longer create an AVStreamSession.
+ (WebCore::CDMSessionMediaSourceAVFObjC::setStreamSession): Add and remove observers as appropriate.
+ (WebCore::CDMSessionMediaSourceAVFObjC::addSourceBuffer): No longer add or remove parsers from AVStreamSessions.
+ (WebCore::CDMSessionMediaSourceAVFObjC::removeSourceBuffer): Ditto.
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h:
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::hasStreamSession): Simple getter.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::streamSession): Lazy initializing getter.
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession): Call setStreamSession().
+ * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h:
+ * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm:
+ (-[WebAVStreamDataParserListener streamParserWillProvideContentKeyRequestInitializationData:forTrackID:]): Synchronously pass to SourceBufferPrivateAVFObjC.
+ (WebCore::SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID): Add the parser to an AVStreamSession.
+ (WebCore::SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID): Check the trackId.
+ * platform/mac/SoftLinking.h:
+
+2015-01-14 Dana Burkart <dburkart@apple.com>
+
</ins><span class="cx"> Merged r174823. <rdar://problem/19424155>
</span><span class="cx">
</span><span class="cx"> 2014-10-16 Jer Noble <jer.noble@apple.com>
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcCDMSessionMediaSourceAVFObjCh"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.h        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx"> virtual void layerDidReceiveError(AVSampleBufferDisplayLayer *, NSError *);
</span><span class="cx"> virtual void rendererDidReceiveError(AVSampleBufferAudioRenderer *, NSError *);
</span><span class="cx">
</span><ins>+ void setStreamSession(AVStreamSession *);
+
</ins><span class="cx"> void addSourceBuffer(SourceBufferPrivateAVFObjC*);
</span><span class="cx"> void removeSourceBuffer(SourceBufferPrivateAVFObjC*);
</span><span class="cx">
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcCDMSessionMediaSourceAVFObjCmm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/CDMSessionMediaSourceAVFObjC.mm        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -43,27 +43,27 @@
</span><span class="cx"> SOFT_LINK_FRAMEWORK_OPTIONAL(AVFoundation)
</span><span class="cx"> SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser);
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamSession);
</span><ins>+SOFT_LINK_CONSTANT_MAY_FAIL(AVFoundation, AVStreamSessionContentProtectionSessionIdentifierChangedNotification, NSString *);
</ins><span class="cx">
</span><span class="cx"> @interface AVStreamDataParser : NSObject
</span><span class="cx"> - (void)processContentKeyResponseData:(NSData *)contentKeyResponseData forTrackID:(CMPersistentTrackID)trackID;
</span><span class="cx"> - (void)processContentKeyResponseError:(NSError *)error forTrackID:(CMPersistentTrackID)trackID;
</span><span class="cx"> - (void)renewExpiringContentKeyResponseDataForTrackID:(CMPersistentTrackID)trackID;
</span><span class="cx"> - (NSData *)streamingContentKeyRequestDataForApp:(NSData *)appIdentifier contentIdentifier:(NSData *)contentIdentifier trackID:(CMPersistentTrackID)trackID options:(NSDictionary *)options error:(NSError **)outError;
</span><del>-- (NSData *)sessionIdentifier;
</del><span class="cx"> @end
</span><span class="cx">
</span><span class="cx"> @interface AVStreamSession : NSObject
</span><del>-- (instancetype)initWithAppIdentifier:(NSData *)appIdentifier storageDirectoryAtURL:(NSURL *)storageURL error:(NSError **)outError;
</del><ins>+- (BOOL)setStorageDirectoryAtURL:(NSURL *)storageURL appIdentifier:(NSData *)appIdentifier error:(NSError **)outError;
</ins><span class="cx"> - (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
</span><span class="cx"> - (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
</span><span class="cx"> - (void)expire;
</span><ins>+- (NSData *)contentProtectionSessionIdentifier;
</ins><span class="cx"> + (NSArray *)pendingExpiredSessionReportsWithAppIdentifier:(NSData *)appIdentifier;
</span><span class="cx"> + (void)removePendingExpiredSessionReports:(NSArray *)expiredSessionReports withAppIdentifier:(NSData *)appIdentifier;
</span><span class="cx"> @end
</span><span class="cx">
</span><span class="cx"> @interface CDMSessionMediaSourceAVFObjCObserver : NSObject {
</span><span class="cx"> WebCore::CDMSessionMediaSourceAVFObjC *m_parent;
</span><del>- HashSet<RetainPtr<AVStreamDataParser>> m_parsers;
</del><span class="cx"> }
</span><span class="cx"> @end
</span><span class="cx">
</span><span class="lines">@@ -75,55 +75,20 @@
</span><span class="cx"> return self;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-- (void)dealloc
</del><ins>+- (void)contentProtectionSessionIdentifierChanged:(NSNotification *)notification
</ins><span class="cx"> {
</span><del>- [self invalidate];
- [super dealloc];
-}
</del><ins>+ AVStreamSession* streamSession = (AVStreamSession*)[notification object];
</ins><span class="cx">
</span><del>-- (void)beginObserving:(AVStreamDataParser *)parser
-{
- ASSERT(!m_parsers.contains(parser));
- m_parsers.add(parser);
- [parser addObserver:self forKeyPath:@"sessionIdentifier" options:(NSKeyValueObservingOptionNew|NSKeyValueObservingOptionInitial) context:nullptr];
-}
</del><ins>+ NSData* identifier = [streamSession contentProtectionSessionIdentifier];
+ RetainPtr<NSString> sessionIdentifierString = identifier ? adoptNS([[NSString alloc] initWithData:identifier encoding:NSUTF8StringEncoding]) : nil;
</ins><span class="cx">
</span><del>-- (void)stopObserving:(AVStreamDataParser *)parser
-{
- ASSERT(m_parsers.contains(parser));
- m_parsers.remove(parser);
- [parser removeObserver:self forKeyPath:@"sessionIdentifier" context:nullptr];
</del><ins>+ if (m_parent)
+ m_parent->setSessionId(sessionIdentifierString.get());
</ins><span class="cx"> }
</span><del>-
-- (void)invalidate
-{
- m_parent = nullptr;
- for (auto& parser : m_parsers)
- [parser removeObserver:self forKeyPath:@"sessionIdentifier" context:nullptr];
- m_parsers.clear();
-}
-
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void*)context
-{
- UNUSED_PARAM(object);
- UNUSED_PARAM(change);
- UNUSED_PARAM(context);
-
- if ([keyPath isEqual:@"sessionIdentifier"]) {
- NSData* identifier = [change valueForKey:NSKeyValueChangeNewKey];
- if ([identifier isKindOfClass:[NSNull class]])
- return;
-
- RetainPtr<NSString> sessionIdentifierString = adoptNS([[NSString alloc] initWithData:identifier encoding:(NSUTF8StringEncoding)]);
- if (m_parent)
- m_parent->setSessionId(sessionIdentifierString.get());
- return;
- }
-
- ASSERT_NOT_REACHED();
-}
</del><span class="cx"> @end
</span><span class="cx">
</span><ins>+static const NSString *PlaybackSessionIdKey = @"PlaybackSessionID";
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><span class="cx"> CDMSessionMediaSourceAVFObjC::CDMSessionMediaSourceAVFObjC()
</span><span class="lines">@@ -138,12 +103,9 @@
</span><span class="cx"> for (auto& sourceBuffer : m_sourceBuffers) {
</span><span class="cx"> if (m_streamSession)
</span><span class="cx"> [m_streamSession removeStreamDataParser:sourceBuffer->parser()];
</span><del>-
- [sourceBuffer->parser() removeObserver:m_dataParserObserver.get() forKeyPath:@"sessionIdentifier" context:nullptr];
</del><span class="cx"> }
</span><span class="cx">
</span><del>- m_streamSession = nil;
- [m_dataParserObserver invalidate];
</del><ins>+ setStreamSession(nullptr);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PassRefPtr<Uint8Array> CDMSessionMediaSourceAVFObjC::generateKeyRequest(const String& mimeType, Uint8Array* initData, String& destinationURL, unsigned short& errorCode, unsigned long& systemCode)
</span><span class="lines">@@ -181,7 +143,12 @@
</span><span class="cx"> NSArray* expiredSessions = [getAVStreamSessionClass() pendingExpiredSessionReportsWithAppIdentifier:certificateData.get()];
</span><span class="cx"> for (NSData* expiredSessionData in expiredSessions) {
</span><span class="cx"> NSDictionary *expiredSession = [NSPropertyListSerialization propertyListWithData:expiredSessionData options:kCFPropertyListImmutable format:nullptr error:nullptr];
</span><del>- if ([expiredSession objectForKey:m_sessionId]) {
</del><ins>+ NSString *playbackSessionIdValue = (NSString *)[expiredSession objectForKey:PlaybackSessionIdKey];
+ if (![playbackSessionIdValue isKindOfClass:[NSString class]])
+ continue;
+
+ if (m_sessionId == String(playbackSessionIdValue)) {
+ LOG(Media, "CDMSessionMediaSourceAVFObjC::releaseKeys(%p) - found session, sending expiration message");
</ins><span class="cx"> m_expiredSession = expiredSessionData;
</span><span class="cx"> m_client->sendMessage(Uint8Array::create(static_cast<const uint8_t*>([m_expiredSession bytes]), [m_expiredSession length]).get(), emptyString());
</span><span class="cx"> break;
</span><span class="lines">@@ -235,6 +202,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (isEqual(key, "acknowledged")) {
</span><ins>+ LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - acknowleding secure stop message", this);
+
</ins><span class="cx"> if (!m_expiredSession) {
</span><span class="cx"> errorCode = MediaPlayer::InvalidPlayerState;
</span><span class="cx"> return false;
</span><span class="lines">@@ -243,6 +212,7 @@
</span><span class="cx"> RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
</span><span class="cx"> [getAVStreamSessionClass() removePendingExpiredSessionReports:@[m_expiredSession.get()] withAppIdentifier:certificateData.get()];
</span><span class="cx"> m_expiredSession = nullptr;
</span><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RefPtr<SourceBufferPrivateAVFObjC> protectedSourceBuffer;
</span><span class="lines">@@ -255,8 +225,8 @@
</span><span class="cx">
</span><span class="cx"> if (shouldGenerateKeyRequest) {
</span><span class="cx"> RetainPtr<NSData> certificateData = adoptNS([[NSData alloc] initWithBytes:m_certificate->data() length:m_certificate->length()]);
</span><del>- if (getAVStreamSessionClass() && [getAVStreamSessionClass() instancesRespondToSelector:@selector(initWithAppIdentifier:storageDirectoryAtURL:error:)]) {
- m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] initWithAppIdentifier:certificateData.get() storageDirectoryAtURL:[NSURL fileURLWithPath:sessionStorageDirectory()] error:nil]);
</del><ins>+ if (m_streamSession && [m_streamSession respondsToSelector:@selector(setStorageDirectoryAtURL:storageURL:appIdentifier:error:)]) {
+ [m_streamSession setStorageDirectoryAtURL:[NSURL fileURLWithPath:sessionStorageDirectory()] appIdentifier:certificateData.get() error:nil];
</ins><span class="cx"> for (auto& sourceBuffer : m_sourceBuffers)
</span><span class="cx"> [m_streamSession addStreamDataParser:sourceBuffer->parser()];
</span><span class="cx"> LOG(Media, "CDMSessionMediaSourceAVFObjC::update(%p) - created stream session %p", this, m_streamSession.get());
</span><span class="lines">@@ -273,7 +243,7 @@
</span><span class="cx"> NSError* error = nil;
</span><span class="cx"> RetainPtr<NSData> request = [protectedSourceBuffer->parser() streamingContentKeyRequestDataForApp:certificateData.get() contentIdentifier:initData.get() trackID:protectedSourceBuffer->protectedTrackID() options:nil error:&error];
</span><span class="cx">
</span><del>- if (![protectedSourceBuffer->parser() respondsToSelector:@selector(sessionIdentifier)])
</del><ins>+ if (![protectedSourceBuffer->parser() respondsToSelector:@selector(contentProtectionSessionIdentifier)])
</ins><span class="cx"> m_sessionId = createCanonicalUUIDString();
</span><span class="cx">
</span><span class="cx"> if (error) {
</span><span class="lines">@@ -314,6 +284,24 @@
</span><span class="cx"> m_client->sendError(CDMSessionClient::MediaKeyErrorDomain, abs([error code]));
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void CDMSessionMediaSourceAVFObjC::setStreamSession(AVStreamSession *streamSession)
+{
+ if (m_streamSession && canLoadAVStreamSessionContentProtectionSessionIdentifierChangedNotification())
+ [[NSNotificationCenter defaultCenter] removeObserver:m_dataParserObserver.get() name:getAVStreamSessionContentProtectionSessionIdentifierChangedNotification() object:m_streamSession.get()];
+
+ m_streamSession = streamSession;
+
+ if (!m_streamSession)
+ return;
+
+ if (canLoadAVStreamSessionContentProtectionSessionIdentifierChangedNotification())
+ [[NSNotificationCenter defaultCenter] addObserver:m_dataParserObserver.get() selector:@selector(contentProtectionSessionIdentifierChanged:) name:getAVStreamSessionContentProtectionSessionIdentifierChangedNotification() object:m_streamSession.get()];
+
+ NSData* identifier = [streamSession contentProtectionSessionIdentifier];
+ RetainPtr<NSString> sessionIdentifierString = identifier ? adoptNS([[NSString alloc] initWithData:identifier encoding:(NSUTF8StringEncoding)]) : nil;
+ setSessionId(sessionIdentifierString.get());
+}
+
</ins><span class="cx"> void CDMSessionMediaSourceAVFObjC::addSourceBuffer(SourceBufferPrivateAVFObjC* sourceBuffer)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(!m_sourceBuffers.contains(sourceBuffer));
</span><span class="lines">@@ -321,11 +309,6 @@
</span><span class="cx">
</span><span class="cx"> m_sourceBuffers.append(sourceBuffer);
</span><span class="cx"> sourceBuffer->registerForErrorNotifications(this);
</span><del>-
- if (m_streamSession)
- [m_streamSession addStreamDataParser:sourceBuffer->parser()];
-
- [m_dataParserObserver beginObserving:sourceBuffer->parser()];
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void CDMSessionMediaSourceAVFObjC::removeSourceBuffer(SourceBufferPrivateAVFObjC* sourceBuffer)
</span><span class="lines">@@ -338,8 +321,6 @@
</span><span class="cx">
</span><span class="cx"> sourceBuffer->unregisterForErrorNotifications(this);
</span><span class="cx"> m_sourceBuffers.remove(m_sourceBuffers.find(sourceBuffer));
</span><del>-
- [m_dataParserObserver stopObserving:sourceBuffer->parser()];
</del><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PassRefPtr<Uint8Array> CDMSessionMediaSourceAVFObjC::generateKeyReleaseMessage(unsigned short& errorCode, unsigned long& systemCode)
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCh"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.h        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> OBJC_CLASS AVSampleBufferAudioRenderer;
</span><span class="cx"> OBJC_CLASS AVSampleBufferDisplayLayer;
</span><span class="cx"> OBJC_CLASS AVSampleBufferRenderSynchronizer;
</span><ins>+OBJC_CLASS AVStreamSession;
</ins><span class="cx">
</span><span class="cx"> typedef struct OpaqueCMTimebase* CMTimebaseRef;
</span><span class="cx">
</span><span class="lines">@@ -83,6 +84,8 @@
</span><span class="cx"> void characteristicsChanged();
</span><span class="cx">
</span><span class="cx"> #if ENABLE(ENCRYPTED_MEDIA_V2)
</span><ins>+ bool hasStreamSession() { return m_streamSession; }
+ AVStreamSession *streamSession();
</ins><span class="cx"> virtual void setCDMSession(CDMSession*) override;
</span><span class="cx"> void keyNeeded(Uint8Array*);
</span><span class="cx"> #endif
</span><span class="lines">@@ -191,6 +194,7 @@
</span><span class="cx"> RetainPtr<AVSampleBufferRenderSynchronizer> m_synchronizer;
</span><span class="cx"> RetainPtr<id> m_timeJumpedObserver;
</span><span class="cx"> RetainPtr<id> m_durationObserver;
</span><ins>+ RetainPtr<AVStreamSession> m_streamSession;
</ins><span class="cx"> Timer<MediaPlayerPrivateMediaSourceAVFObjC> m_seekTimer;
</span><span class="cx"> CDMSessionMediaSourceAVFObjC* m_session;
</span><span class="cx"> MediaPlayer::NetworkState m_networkState;
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcMediaPlayerPrivateMediaSourceAVFObjCmm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferDisplayLayer)
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVSampleBufferRenderSynchronizer)
</span><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamDataParser)
</span><ins>+SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVStreamSession);
</ins><span class="cx"> SOFT_LINK_CLASS_OPTIONAL(AVFoundation, AVVideoPerformanceMetrics)
</span><span class="cx">
</span><span class="cx"> typedef struct opaqueCMNotificationCenter *CMNotificationCenterRef;
</span><span class="lines">@@ -654,6 +655,13 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(ENCRYPTED_MEDIA_V2)
</span><ins>+AVStreamSession* MediaPlayerPrivateMediaSourceAVFObjC::streamSession()
+{
+ if (!m_streamSession)
+ m_streamSession = adoptNS([[getAVStreamSessionClass() alloc] init]);
+ return m_streamSession.get();
+}
+
</ins><span class="cx"> void MediaPlayerPrivateMediaSourceAVFObjC::setCDMSession(CDMSession* session)
</span><span class="cx"> {
</span><span class="cx"> if (m_session) {
</span><span class="lines">@@ -665,6 +673,7 @@
</span><span class="cx"> m_session = toCDMSessionMediaSourceAVFObjC(session);
</span><span class="cx">
</span><span class="cx"> if (m_session) {
</span><ins>+ m_session->setStreamSession(m_streamSession.get());
</ins><span class="cx"> for (auto& sourceBuffer : m_mediaSourcePrivate->sourceBuffers())
</span><span class="cx"> m_session->addSourceBuffer(sourceBuffer.get());
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcSourceBufferPrivateAVFObjCh"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx"> void didFailToParseStreamDataWithError(NSError*);
</span><span class="cx"> void didProvideMediaDataForTrackID(int trackID, CMSampleBufferRef, const String& mediaType, unsigned flags);
</span><span class="cx"> void didReachEndOfTrackWithTrackID(int trackID, const String& mediaType);
</span><ins>+ void willProvideContentKeyRequestInitializationDataForTrackID(int trackID);
</ins><span class="cx"> void didProvideContentKeyRequestInitializationDataForTrackID(NSData*, int trackID);
</span><span class="cx">
</span><span class="cx"> bool processCodedFrame(int trackID, CMSampleBufferRef, const String& mediaType);
</span></span></pre></div>
<a id="branchessafari6005branchSourceWebCoreplatformgraphicsavfoundationobjcSourceBufferPrivateAVFObjCmm"></a>
<div class="modfile"><h4>Modified: branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm (178471 => 178472)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm        2015-01-15 02:16:06 UTC (rev 178471)
+++ branches/safari-600.5-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm        2015-01-15 02:40:11 UTC (rev 178472)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx">
</span><span class="cx"> #if ENABLE(MEDIA_SOURCE) && USE(AVFOUNDATION)
</span><span class="cx">
</span><ins>+#import "BlockExceptions.h"
</ins><span class="cx"> #import "ExceptionCodePlaceholder.h"
</span><span class="cx"> #import "Logging.h"
</span><span class="cx"> #import "MediaDescription.h"
</span><span class="lines">@@ -62,6 +63,7 @@
</span><span class="cx"> SOFT_LINK_CLASS(AVFoundation, AVStreamDataParser)
</span><span class="cx"> SOFT_LINK_CLASS(AVFoundation, AVSampleBufferAudioRenderer)
</span><span class="cx"> SOFT_LINK_CLASS(AVFoundation, AVSampleBufferDisplayLayer)
</span><ins>+SOFT_LINK_CLASS(AVFoundation, AVStreamSession)
</ins><span class="cx">
</span><span class="cx"> SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVMediaTypeVideo, NSString *)
</span><span class="cx"> SOFT_LINK_POINTER_OPTIONAL(AVFoundation, AVMediaTypeAudio, NSString *)
</span><span class="lines">@@ -115,6 +117,14 @@
</span><span class="cx"> #define AVMediaCharacteristicLegible getAVMediaCharacteristicLegible()
</span><span class="cx">
</span><span class="cx"> #pragma mark -
</span><ins>+#pragma mark AVStreamSession
+
+@interface AVStreamSession : NSObject
+- (void)addStreamDataParser:(AVStreamDataParser *)streamDataParser;
+- (void)removeStreamDataParser:(AVStreamDataParser *)streamDataParser;
+@end
+
+#pragma mark -
</ins><span class="cx"> #pragma mark AVStreamDataParser
</span><span class="cx">
</span><span class="cx"> @interface AVStreamDataParser : NSObject
</span><span class="lines">@@ -268,6 +278,27 @@
</span><span class="cx"> });
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+- (void)streamParserWillProvideContentKeyRequestInitializationData:(AVStreamDataParser *)streamDataParser forTrackID:(CMPersistentTrackID)trackID
+{
+#if ASSERT_DISABLED
+ UNUSED_PARAM(streamDataParser);
+#endif
+ ASSERT(streamDataParser == _parser);
+
+ if (isMainThread()) {
+ _parent->willProvideContentKeyRequestInitializationDataForTrackID(trackID);
+ return;
+ }
+
+ // We must call synchronously to the main thread, as the AVStreamSession must be associated
+ // with the streamDataParser before the delegate method returns.
+ RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
+ dispatch_sync(dispatch_get_main_queue(), [strongSelf, trackID]() {
+ if (strongSelf->_parent)
+ strongSelf->_parent->willProvideContentKeyRequestInitializationDataForTrackID(trackID);
+ });
+}
+
</ins><span class="cx"> - (void)streamDataParser:(AVStreamDataParser *)streamDataParser didProvideContentKeyRequestInitializationData:(NSData *)initData forTrackID:(CMPersistentTrackID)trackID
</span><span class="cx"> {
</span><span class="cx"> #if ASSERT_DISABLED
</span><span class="lines">@@ -658,6 +689,25 @@
</span><span class="cx"> notImplemented();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID(int trackID)
+{
+ if (!m_mediaSource)
+ return;
+
+ ASSERT(m_parser);
+
+#if ENABLE(ENCRYPTED_MEDIA_V2)
+ LOG(MediaSource, "SourceBufferPrivateAVFObjC::willProvideContentKeyRequestInitializationDataForTrackID(%p) - track:%d", this, trackID);
+ m_protectedTrackID = trackID;
+
+ BEGIN_BLOCK_OBJC_EXCEPTIONS;
+ [m_mediaSource->player()->streamSession() addStreamDataParser:m_parser.get()];
+ END_BLOCK_OBJC_EXCEPTIONS;
+#else
+ UNUSED_PARAM(trackID);
+#endif
+}
+
</ins><span class="cx"> void SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID(NSData* initData, int trackID)
</span><span class="cx"> {
</span><span class="cx"> if (!m_mediaSource)
</span><span class="lines">@@ -733,6 +783,9 @@
</span><span class="cx">
</span><span class="cx"> void SourceBufferPrivateAVFObjC::destroyParser()
</span><span class="cx"> {
</span><ins>+ if (m_mediaSource->player()->hasStreamSession())
+ [m_mediaSource->player()->streamSession() removeStreamDataParser:m_parser.get()];
+
</ins><span class="cx"> [m_delegate invalidate];
</span><span class="cx"> m_delegate = nullptr;
</span><span class="cx"> m_parser = nullptr;
</span></span></pre>
</div>
</div>
</body>
</html>