⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 169074 in webkit


Ignore:
Timestamp:
May 19, 2014, 3:04:29 PM (12 years ago)
Author:
matthew_hanson@apple.com
Message:

Merge r168974.

Location:
branches/safari-538.34-branch/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-538.34-branch/Source/WebCore/ChangeLog

    r169072 r169074  
     12014-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
    1512014-05-19  Matthew Hanson  <matthew_hanson@apple.com>
    252
  • branches/safari-538.34-branch/Source/WebCore/Modules/mediasource/SourceBuffer.cpp

    r168790 r169074  
    108108    , m_removeTimer(this, &SourceBuffer::removeTimerFired)
    109109{
    110     ASSERT(m_private);
    111110    ASSERT(m_source);
    112111
    … …  
    475474    // 1. Loop Top: If the input buffer is empty, then jump to the need more data step below.
    476475    if (!m_pendingAppendData.size()) {
    477         sourceBufferPrivateAppendComplete(m_private.get(), AppendSucceeded);
     476        sourceBufferPrivateAppendComplete(&m_private.get(), AppendSucceeded);
    478477        return;
    479478    }
  • branches/safari-538.34-branch/Source/WebCore/Modules/mediasource/SourceBuffer.h

    r168790 r169074  
    157157    void removeCodedFrames(const MediaTime& start, const MediaTime& end);
    158158
    159     RefPtr<SourceBufferPrivate> m_private;
     159    Ref<SourceBufferPrivate> m_private;
    160160    MediaSource* m_source;
    161161    GenericEventQueue m_asyncEventQueue;
  • branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaSourcePrivateAVFObjC.mm

    r168367 r169074  
    8686
    8787    pos = m_sourceBuffers.find(buffer);
     88    m_sourceBuffers[pos]->clearMediaSource();
    8889    m_sourceBuffers.remove(pos);
    8990}
    … …  
    158159#endif
    159160
    160 static bool MediaSourcePrivateAVFObjCHasAudio(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer)
    161 {
    162     RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer;
     161static bool MediaSourcePrivateAVFObjCHasAudio(SourceBufferPrivateAVFObjC* sourceBuffer)
     162{
    163163    return sourceBuffer->hasAudio();
    164164}
    … …  
    169169}
    170170
    171 static bool MediaSourcePrivateAVFObjCHasVideo(PassRefPtr<SourceBufferPrivateAVFObjC> prpSourceBuffer)
    172 {
    173     RefPtr<SourceBufferPrivateAVFObjC> sourceBuffer = prpSourceBuffer;
     171static bool MediaSourcePrivateAVFObjCHasVideo(SourceBufferPrivateAVFObjC* sourceBuffer)
     172{
    174173    return sourceBuffer->hasVideo();
    175174}
  • branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.h

    r168794 r169074  
    3737#include <wtf/RetainPtr.h>
    3838#include <wtf/Vector.h>
     39#include <wtf/WeakPtr.h>
    3940#include <wtf/text/AtomicString.h>
    4041
    … …  
    114115    void destroyRenderers();
    115116
     117    WeakPtr<SourceBufferPrivateAVFObjC> createWeakPtr() { return m_weakFactory.createWeakPtr(); }
     118
    116119    Vector<RefPtr<VideoTrackPrivateMediaSourceAVFObjC>> m_videoTracks;
    117120    Vector<RefPtr<AudioTrackPrivateMediaSourceAVFObjC>> m_audioTracks;
     121
     122    WeakPtrFactory<SourceBufferPrivateAVFObjC> m_weakFactory;
    118123
    119124    RetainPtr<AVStreamDataParser> m_parser;
  • branches/safari-538.34-branch/Source/WebCore/platform/graphics/avfoundation/objc/SourceBufferPrivateAVFObjC.mm

    r168794 r169074  
    154154
    155155@interface WebAVStreamDataParserListener : NSObject {
    156     WebCore::SourceBufferPrivateAVFObjC* _parent;
     156    WeakPtr<WebCore::SourceBufferPrivateAVFObjC> _parent;
    157157    AVStreamDataParser* _parser;
    158158}
    159 - (id)initWithParser:(AVStreamDataParser*)parser parent:(WebCore::SourceBufferPrivateAVFObjC*)parent;
     159- (id)initWithParser:(AVStreamDataParser*)parser parent:(WeakPtr<WebCore::SourceBufferPrivateAVFObjC>)parent;
    160160@end
    161161
    162162@implementation WebAVStreamDataParserListener
    163 - (id)initWithParser:(AVStreamDataParser*)parser parent:(WebCore::SourceBufferPrivateAVFObjC*)parent
     163- (id)initWithParser:(AVStreamDataParser*)parser parent:(WeakPtr<WebCore::SourceBufferPrivateAVFObjC>)parent
    164164{
    165165    self = [super init];
    … …  
    183183{
    184184    [_parser setDelegate:nil];
    185     _parent = nullptr;
    186185    _parser = nullptr;
    187186}
    … …  
    193192#endif
    194193    ASSERT(streamDataParser == _parser);
    195     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    196     if (!strongParent)
    197         return;
     194    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    198195
    199196    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());
    202200    });
    203201}
    … …  
    210208#endif
    211209    ASSERT(streamDataParser == _parser);
    212     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    213     if (!strongParent)
    214         return;
     210    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    215211
    216212    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());
    219216    });
    220217}
    … …  
    226223#endif
    227224    ASSERT(streamDataParser == _parser);
    228     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    229     if (!strongParent)
    230         return;
     225    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    231226
    232227    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());
    235231    });
    236232}
    … …  
    242238#endif
    243239    ASSERT(streamDataParser == _parser);
    244     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    245     if (!strongParent)
    246         return;
     240    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    247241
    248242    RetainPtr<CMSampleBufferRef> strongSample = sample;
    249243    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);
    252247    });
    253248}
    … …  
    259254#endif
    260255    ASSERT(streamDataParser == _parser);
    261     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    262     if (!strongParent)
    263         return;
     256    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    264257
    265258    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);
    268262    });
    269263}
    … …  
    275269#endif
    276270    ASSERT(streamDataParser == _parser);
    277     RefPtr<WebCore::SourceBufferPrivateAVFObjC> strongParent = _parent;
    278     if (!strongParent)
    279         return;
     271    RetainPtr<WebAVStreamDataParserListener> strongSelf = self;
    280272
    281273    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);
    284277    });
    285278}
    … …  
    387380
    388381SourceBufferPrivateAVFObjC::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()]))
    391385    , m_mediaSource(parent)
    392386    , m_client(0)
    … …  
    399393SourceBufferPrivateAVFObjC::~SourceBufferPrivateAVFObjC()
    400394{
     395    ASSERT(!m_client);
    401396    destroyParser();
    402397    destroyRenderers();
    … …  
    470465            LOG(Media, "SourceBufferPrivateAVFObjC::processCodedFrame(%p) - size change detected: {width=%lf, height=%lf", formatSize.width(), formatSize.height());
    471466            m_cachedSize = formatSize;
    472             m_mediaSource->player()->sizeChanged();
     467            if (m_mediaSource)
     468                m_mediaSource->player()->sizeChanged();
    473469        }
    474470    }
    … …  
    488484void SourceBufferPrivateAVFObjC::didProvideContentKeyRequestInitializationDataForTrackID(NSData* initData, int trackID)
    489485{
     486    if (!m_mediaSource)
     487        return;
     488
    490489    UNUSED_PARAM(trackID);
    491490#if ENABLE(ENCRYPTED_MEDIA_V2)
    … …  
    520519
    521520    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;
    523524
    524525    m_parsingSucceeded = true;
    525526
    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();
    531534        });
    532535    });
Note: See TracChangeset for help on using the changeset viewer.