Changeset 169074 in webkit
- Timestamp:
- May 19, 2014, 3:04:29 PM (12 years ago)
- Location:
- branches/safari-538.34-branch/Source/WebCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
Modules/mediasource/SourceBuffer.cpp (modified) (2 diffs)
-
Modules/mediasource/SourceBuffer.h (modified) (1 diff)
-
platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm (modified) (3 diffs)
-
platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h (modified) (2 diffs)
-
platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/safari-538.34-branch/Source/WebCore/ChangeLog
r169072 r169074 1 2014-05-19 Matthew Hanson <matthew_hanson@apple.com> 2 3 Merge r168974. 4 5 2014-05-16 Jer Noble <jer.noble@apple.com> 6 7 [MSE] Crash at WebCore::SourceBuffer::~SourceBuffer + 110 8 https://bugs.webkit.org/show_bug.cgi?id=132973 9 10 Reviewed by Eric Carlson. 11 12 Change SourceBuffer::m_private into a Ref<>, and add an assertion to 13 SourceBufferPrivateAVFObjC's destructor if its client has not been cleared. 14 15 Eliminate unnecessary churn in MediaSourcePrivateAVFObjC by having the predicate 16 functor take bare pointers, rather than a PassRefPtr. 17 18 The underlying problem seems to be in WebAVStreamDataParserListener. RefPtrs were 19 being created off the main thread to a non-thread safe ref counted class. In some 20 situations, this would result in double decrementing the ref, which would cause an 21 early destruction of the underlying object. Instead replace these RefPtr strong 22 pointers with explicit weak ones. Ensure the parser and its delegate are not freed 23 before the append operation completes by passing strong pointers into the async 24 append operation lambda. 25 26 There were a few places where we weren't null checking m_mediaSource before using it, 27 and at least one place where we weren't clearing m_mediaSource. 28 29 * Modules/mediasource/SourceBuffer.cpp: 30 (WebCore::SourceBuffer::SourceBuffer): Use Ref instead of RefPtr. 31 (WebCore::SourceBuffer::appendBufferTimerFired): Ditto. 32 * Modules/mediasource/SourceBuffer.h: 33 * platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm: 34 (WebCore::MediaSourcePrivateAVFObjCHasAudio): Take a bare pointer, instead of a PassRefPtr. 35 (WebCore::MediaSourcePrivateAVFObjCHasVideo): Ditto. 36 * platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm: 37 (WebCore::MediaSourcePrivateAVFObjC::removeSourceBuffer): Clear the back pointer when removing a buffer. 38 * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h: 39 * platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm: 40 (-[WebAVStreamDataParserListener initWithParser:parent:WebCore::]): Use WeakPtr instead of RefPtr. 41 (-[WebAVStreamDataParserListener invalidate]): Ditto. 42 (-[WebAVStreamDataParserListener streamDataParser:didParseStreamDataAsAsset:]): Ditto. 43 (-[WebAVStreamDataParserListener streamDataParser:didParseStreamDataAsAsset:withDiscontinuity:]): Ditto. 44 (-[WebAVStreamDataParserListener streamDataParser:didFailToParseStreamDataWithError:]): Ditto. 45 (-[WebAVStreamDataParserListener streamDataParser:didProvideMediaData:forTrackID:mediaType:flags:]): Ditto. 46 (-[WebAVStreamDataParserListener streamDataParser:didReachEndOfTrackWithTrackID:mediaType:]): Ditto. 47 (-[WebAVStreamDataParserListener streamDataParser:didProvideContentKeyRequestInitializationData:forTrackID:]): Ditto. 48 (WebCore::SourceBufferPrivateAVFObjC::~SourceBufferPrivateAVFObjC): 49 (WebCore::SourceBufferPrivateAVFObjC::append): Ditto. 50 1 51 2014-05-19 Matthew Hanson <matthew_hanson@apple.com> 2 52 -
branches/safari-538.34-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp
r168790 r169074 108 108 , m_removeTimer(this, &SourceBuffer::removeTimerFired) 109 109 { 110 ASSERT(m_private);111 110 ASSERT(m_source); 112 111 … … 475 474 // 1. Loop Top: If the input buffer is empty, then jump to the need more data step below. 476 475 if (!m_pendingAppendData.size()) { 477 sourceBufferPrivateAppendComplete( m_private.get(), AppendSucceeded);476 sourceBufferPrivateAppendComplete(&m_private.get(), AppendSucceeded); 478 477 return; 479 478 } -
branches/safari-538.34-branch/Source/WebCore/Modules/mediasource/SourceBuffer.h
r168790 r169074 157 157 void removeCodedFrames(const MediaTime& start, const MediaTime& end); 158 158 159 Ref Ptr<SourceBufferPrivate> m_private;159 Ref<SourceBufferPrivate> m_private; 160 160 MediaSource* m_source; 161 161 GenericEventQueue m_asyncEventQueue; -
branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm
r168367 r169074 86 86 87 87 pos = m_sourceBuffers.find(buffer); 88 m_sourceBuffers[pos]->clearMediaSource(); 88 89 m_sourceBuffers.remove(pos); 89 90 } … … 158 159 #endif 159 160 160 static bool MediaSourcePrivateAVFObjCHasAudio(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer) 161 { 162 RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer; 161 static bool MediaSourcePrivateAVFObjCHasAudio(SourceBufferPrivateAVFObjC* sourceBuffer) 162 { 163 163 return sourceBuffer->hasAudio(); 164 164 } … … 169 169 } 170 170 171 static bool MediaSourcePrivateAVFObjCHasVideo(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer) 172 { 173 RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer; 171 static bool MediaSourcePrivateAVFObjCHasVideo(SourceBufferPrivateAVFObjC* sourceBuffer) 172 { 174 173 return sourceBuffer->hasVideo(); 175 174 } -
branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h
r168794 r169074 37 37 #include <wtf/RetainPtr.h> 38 38 #include <wtf/Vector.h> 39 #include <wtf/WeakPtr.h> 39 40 #include <wtf/text/AtomicString.h> 40 41 … … 114 115 void destroyRenderers(); 115 116 117 WeakPtr<SourceBufferPrivateAVFObjC> createWeakPtr() { return m_weakFactory.createWeakPtr(); } 118 116 119 Vector<RefPtr<VideoTrackPrivateMediaSourceAVFObjC>> m_videoTracks; 117 120 Vector<RefPtr<AudioTrackPrivateMediaSourceAVFObjC>> m_audioTracks; 121 122 WeakPtrFactory<SourceBufferPrivateAVFObjC> m_weakFactory; 118 123 119 124 RetainPtr<AVStreamDataParser> m_parser; -
branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm
r168794 r169074 154 154 155 155 @interface WebAVStreamDataParserListener : NSObject { 156 We bCore::SourceBufferPrivateAVFObjC*_parent;156 WeakPtr<WebCore::SourceBufferPrivateAVFObjC> _parent; 157 157 AVStreamDataParser* _parser; 158 158 } 159 - (id)initWithParser:(AVStreamDataParser*)parser parent:(We bCore::SourceBufferPrivateAVFObjC*)parent;159 - (id)initWithParser:(AVStreamDataParser*)parser parent:(WeakPtr<WebCore::SourceBufferPrivateAVFObjC>)parent; 160 160 @end 161 161 162 162 @implementation WebAVStreamDataParserListener 163 - (id)initWithParser:(AVStreamDataParser*)parser parent:(We bCore::SourceBufferPrivateAVFObjC*)parent163 - (id)initWithParser:(AVStreamDataParser*)parser parent:(WeakPtr<WebCore::SourceBufferPrivateAVFObjC>)parent 164 164 { 165 165 self = [super init]; … … 183 183 { 184 184 [_parser setDelegate:nil]; 185 _parent = nullptr;186 185 _parser = nullptr; 187 186 } … … 193 192 #endif 194 193 ASSERT(streamDataParser == _parser); 195 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 196 if (!strongParent) 197 return; 194 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 198 195 199 196 RetainPtr<AVAsset*> strongAsset = asset; 200 callOnMainThread([strongParent, strongAsset] { 201 strongParent->didParseStreamDataAsAsset(strongAsset.get()); 197 callOnMainThread([strongSelf, strongAsset] { 198 if (strongSelf->_parent) 199 strongSelf->_parent->didParseStreamDataAsAsset(strongAsset.get()); 202 200 }); 203 201 } … … 210 208 #endif 211 209 ASSERT(streamDataParser == _parser); 212 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 213 if (!strongParent) 214 return; 210 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 215 211 216 212 RetainPtr<AVAsset*> strongAsset = asset; 217 callOnMainThread([strongParent, strongAsset] { 218 strongParent->didParseStreamDataAsAsset(strongAsset.get()); 213 callOnMainThread([strongSelf, strongAsset] { 214 if (strongSelf->_parent) 215 strongSelf->_parent->didParseStreamDataAsAsset(strongAsset.get()); 219 216 }); 220 217 } … … 226 223 #endif 227 224 ASSERT(streamDataParser == _parser); 228 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 229 if (!strongParent) 230 return; 225 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 231 226 232 227 RetainPtr<NSError> strongError = error; 233 callOnMainThread([strongParent, strongError] { 234 strongParent->didFailToParseStreamDataWithError(strongError.get()); 228 callOnMainThread([strongSelf, strongError] { 229 if (strongSelf->_parent) 230 strongSelf->_parent->didFailToParseStreamDataWithError(strongError.get()); 235 231 }); 236 232 } … … 242 238 #endif 243 239 ASSERT(streamDataParser == _parser); 244 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 245 if (!strongParent) 246 return; 240 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 247 241 248 242 RetainPtr<CMSampleBufferRef> strongSample = sample; 249 243 String mediaType = nsMediaType; 250 callOnMainThread([strongParent, strongSample, trackID, mediaType, flags] { 251 strongParent->didProvideMediaDataForTrackID(trackID, strongSample.get(), mediaType, flags); 244 callOnMainThread([strongSelf, strongSample, trackID, mediaType, flags] { 245 if (strongSelf->_parent) 246 strongSelf->_parent->didProvideMediaDataForTrackID(trackID, strongSample.get(), mediaType, flags); 252 247 }); 253 248 } … … 259 254 #endif 260 255 ASSERT(streamDataParser == _parser); 261 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 262 if (!strongParent) 263 return; 256 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 264 257 265 258 String mediaType = nsMediaType; 266 callOnMainThread([strongParent, trackID, mediaType] { 267 strongParent->didReachEndOfTrackWithTrackID(trackID, mediaType); 259 callOnMainThread([strongSelf, trackID, mediaType] { 260 if (strongSelf->_parent) 261 strongSelf->_parent->didReachEndOfTrackWithTrackID(trackID, mediaType); 268 262 }); 269 263 } … … 275 269 #endif 276 270 ASSERT(streamDataParser == _parser); 277 RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent; 278 if (!strongParent) 279 return; 271 RetainPtr<WebAVStreamDataParserListener> strongSelf = self; 280 272 281 273 RetainPtr<NSData> strongData = initData; 282 callOnMainThread([strongParent, strongData, trackID] { 283 strongParent->didProvideContentKeyRequestInitializationDataForTrackID(strongData.get(), trackID); 274 callOnMainThread([strongSelf, strongData, trackID] { 275 if (strongSelf->_parent) 276 strongSelf->_parent->didProvideContentKeyRequestInitializationDataForTrackID(strongData.get(), trackID); 284 277 }); 285 278 } … … 387 380 388 381 SourceBufferPrivateAVFObjC::SourceBufferPrivateAVFObjC(MediaSourcePrivateAVFObjC* parent) 389 : m_parser(adoptNS([[getAVStreamDataParserClass() alloc] init])) 390 , m_delegate(adoptNS([[WebAVStreamDataParserListener alloc] initWithParser:m_parser.get() parent:this])) 382 : m_weakFactory(this) 383 , m_parser(adoptNS([[getAVStreamDataParserClass() alloc] init])) 384 , m_delegate(adoptNS([[WebAVStreamDataParserListener alloc] initWithParser:m_parser.get() parent:createWeakPtr()])) 391 385 , m_mediaSource(parent) 392 386 , m_client(0) … … 399 393 SourceBufferPrivateAVFObjC::~SourceBufferPrivateAVFObjC() 400 394 { 395 ASSERT(!m_client); 401 396 destroyParser(); 402 397 destroyRenderers(); … … 470 465 LOG(Media, "SourceBufferPrivateAVFObjC::processCodedFrame(%p) - size change detected: {width=%lf, height=%lf", formatSize.width(), formatSize.height()); 471 466 m_cachedSize = formatSize; 472 m_mediaSource->player()->sizeChanged(); 467 if (m_mediaSource) 468 m_mediaSource->player()->sizeChanged(); 473 469 } 474 470 } … … 488 484 void SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID(NSData* initData, int trackID) 489 485 { 486 if (!m_mediaSource) 487 return; 488 490 489 UNUSED_PARAM(trackID); 491 490 #if ENABLE(ENCRYPTED_MEDIA_V2) … … 520 519 521 520 RetainPtr<NSData> nsData = adoptNS([[NSData alloc] initWithBytes:data length:length]); 522 RefPtr<SourceBufferPrivateAVFObjC> strongThis = this; 521 WeakPtr<SourceBufferPrivateAVFObjC> weakThis = createWeakPtr(); 522 RetainPtr<AVStreamDataParser> parser = m_parser; 523 RetainPtr<WebAVStreamDataParserListener> delegate = m_delegate; 523 524 524 525 m_parsingSucceeded = true; 525 526 526 dispatch_async(globalDataParserQueue(), [nsData, strongThis] { 527 [strongThis->m_parser appendStreamData:nsData.get()]; 528 529 callOnMainThread([strongThis] { 530 strongThis->appendCompleted(); 527 dispatch_async(globalDataParserQueue(), [nsData, weakThis, parser, delegate] { 528 529 [parser appendStreamData:nsData.get()]; 530 531 callOnMainThread([weakThis] { 532 if (weakThis) 533 weakThis->appendCompleted(); 531 534 }); 532 535 });
Note:
See TracChangeset
for help on using the changeset viewer.