Changeset 247211 in webkit


Ignore:
Timestamp:
Jul 8, 2019 10:46:27 AM (5 years ago)
Author:
youenn@apple.com
Message:

MediaStreamTrackPrivate should always call readyStateChanged on the main thread
https://bugs.webkit.org/show_bug.cgi?id=199538
<rdar://problem/52709106>

Reviewed by Eric Carlson.

MediaStreamTrackPrivate is sometimes calling readyStateChanged in a
background thread inside its audioSamplesAvailable method.
Instead of doing that, we hop to the main thread to call readyStateChanged.
Once the call is made in the main thread, MediaStreamTrackPrivate will
send the audio samples to its observers.

To make mock audio source closer to real capture audio sources,
audioSamplesAvailable is called on a background thread.
RealtimeMediaSource is updated to always be destroyed in the main
run loop since it is WebKit2 only.

Covered by existing tests and making sure the mock audio source calls
the audioSamplesAvailable method on a background thread.

  • platform/mediastream/MediaStreamTrackPrivate.cpp:

(WebCore::MediaStreamTrackPrivate::videoSampleAvailable):
(WebCore::MediaStreamTrackPrivate::audioSamplesAvailable):

  • platform/mediastream/MediaStreamTrackPrivate.h:
  • platform/mediastream/RealtimeMediaSource.cpp:

(WebCore::RealtimeMediaSource::scheduleDeferredTask):
scheduleDeferredTask may be called from a background thread.
It is thus safer to ref the source instead of creating a weak pointer.

  • platform/mediastream/RealtimeMediaSource.h:
  • platform/mediastream/mac/MockRealtimeAudioSourceMac.mm:

(WebCore::MockRealtimeAudioSourceMac::MockRealtimeAudioSourceMac):
(WebCore::MockRealtimeAudioSourceMac::emitSampleBuffers):
(WebCore::MockRealtimeAudioSourceMac::reconfigure):
(WebCore::MockRealtimeAudioSourceMac::render):
(WebCore::MockRealtimeAudioSourceMac::settingsDidChange):

  • platform/mock/MockRealtimeAudioSource.cpp:

(WebCore::MockRealtimeAudioSource::MockRealtimeAudioSource):
(WebCore::MockRealtimeAudioSource::tick):

  • platform/mock/MockRealtimeAudioSource.h:
Location:
trunk/Source/WebCore
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r247208 r247211  
     12019-07-08  Youenn Fablet  <youenn@apple.com>
     2
     3        MediaStreamTrackPrivate should always call readyStateChanged on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=199538
     5        <rdar://problem/52709106>
     6
     7        Reviewed by Eric Carlson.
     8
     9        MediaStreamTrackPrivate is sometimes calling readyStateChanged in a
     10        background thread inside its audioSamplesAvailable method.
     11        Instead of doing that, we hop to the main thread to call readyStateChanged.
     12        Once the call is made in the main thread, MediaStreamTrackPrivate will
     13        send the audio samples to its observers.
     14
     15        To make mock audio source closer to real capture audio sources,
     16        audioSamplesAvailable is called on a background thread.
     17        RealtimeMediaSource is updated to always be destroyed in the main
     18        run loop since it is WebKit2 only.
     19
     20        Covered by existing tests and making sure the mock audio source calls
     21        the audioSamplesAvailable method on a background thread.
     22
     23        * platform/mediastream/MediaStreamTrackPrivate.cpp:
     24        (WebCore::MediaStreamTrackPrivate::videoSampleAvailable):
     25        (WebCore::MediaStreamTrackPrivate::audioSamplesAvailable):
     26        * platform/mediastream/MediaStreamTrackPrivate.h:
     27        * platform/mediastream/RealtimeMediaSource.cpp:
     28        (WebCore::RealtimeMediaSource::scheduleDeferredTask):
     29        scheduleDeferredTask may be called from a background thread.
     30        It is thus safer to ref the source instead of creating a weak pointer.
     31        * platform/mediastream/RealtimeMediaSource.h:
     32        * platform/mediastream/mac/MockRealtimeAudioSourceMac.mm:
     33        (WebCore::MockRealtimeAudioSourceMac::MockRealtimeAudioSourceMac):
     34        (WebCore::MockRealtimeAudioSourceMac::emitSampleBuffers):
     35        (WebCore::MockRealtimeAudioSourceMac::reconfigure):
     36        (WebCore::MockRealtimeAudioSourceMac::render):
     37        (WebCore::MockRealtimeAudioSourceMac::settingsDidChange):
     38        * platform/mock/MockRealtimeAudioSource.cpp:
     39        (WebCore::MockRealtimeAudioSource::MockRealtimeAudioSource):
     40        (WebCore::MockRealtimeAudioSource::tick):
     41        * platform/mock/MockRealtimeAudioSource.h:
     42
    1432019-07-08  Youenn Fablet  <youenn@apple.com>
    244
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp

    r246644 r247211  
    243243void MediaStreamTrackPrivate::videoSampleAvailable(MediaSample& mediaSample)
    244244{
     245    ASSERT(isMainThread());
    245246    if (!m_haveProducedData) {
    246247        m_haveProducedData = true;
     
    260261void MediaStreamTrackPrivate::audioSamplesAvailable(const MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount)
    261262{
    262     if (!m_haveProducedData) {
    263         m_haveProducedData = true;
    264         updateReadyState();
     263    if (!m_hasSentStartProducedData) {
     264        callOnMainThread([this, protectedThis = makeRef(*this)] {
     265            if (!m_haveProducedData) {
     266                m_haveProducedData = true;
     267                updateReadyState();
     268            }
     269            m_hasSentStartProducedData = true;
     270        });
     271        return;
    265272    }
    266273
     
    269276    });
    270277}
    271 
    272278
    273279void MediaStreamTrackPrivate::updateReadyState()
  • trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h

    r246436 r247211  
    4242
    4343class MediaStreamTrackPrivate final
    44     : public RefCounted<MediaStreamTrackPrivate>
     44    : public ThreadSafeRefCounted<MediaStreamTrackPrivate, WTF::DestructionThread::Main>
    4545    , public RealtimeMediaSource::Observer
    4646#if !RELEASE_LOG_DISABLED
     
    152152    bool m_isEnded { false };
    153153    bool m_haveProducedData { false };
     154    bool m_hasSentStartProducedData { false };
    154155    HintValue m_contentHint { HintValue::Empty };
    155156    RefPtr<WebAudioSourceProvider> m_audioSourceProvider;
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r243899 r247211  
    10361036}
    10371037
    1038 void RealtimeMediaSource::scheduleDeferredTask(WTF::Function<void()>&& function)
     1038void RealtimeMediaSource::scheduleDeferredTask(Function<void()>&& function)
    10391039{
    10401040    ASSERT(function);
    1041     callOnMainThread([weakThis = makeWeakPtr(*this), function = WTFMove(function)] {
    1042         if (!weakThis)
    1043             return;
    1044 
     1041    callOnMainThread([protectedThis = makeRef(*this), function = WTFMove(function)] {
    10451042        function();
    10461043    });
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h

    r246644 r247211  
    6868
    6969class WEBCORE_EXPORT RealtimeMediaSource
    70     : public ThreadSafeRefCounted<RealtimeMediaSource>
     70    : public ThreadSafeRefCounted<RealtimeMediaSource, WTF::DestructionThread::MainRunLoop>
    7171    , public CanMakeWeakPtr<RealtimeMediaSource>
    7272#if !RELEASE_LOG_DISABLED
  • trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeAudioSourceMac.mm

    r236877 r247211  
    107107    : MockRealtimeAudioSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))
    108108{
     109    ASSERT(isMainThread());
    109110}
    110111
    111112void MockRealtimeAudioSourceMac::emitSampleBuffers(uint32_t frameCount)
    112113{
     114    ASSERT(!isMainThread());
    113115    ASSERT(m_formatDescription);
    114116
     
    121123void MockRealtimeAudioSourceMac::reconfigure()
    122124{
     125    ASSERT(!isMainThread());
    123126    m_maximiumFrameCount = WTF::roundUpToPowerOfTwo(renderInterval().seconds() * sampleRate() * 2);
    124127    ASSERT(m_maximiumFrameCount);
     
    141144void MockRealtimeAudioSourceMac::render(Seconds delta)
    142145{
     146    ASSERT(!isMainThread());
    143147    if (!m_audioBufferList)
    144148        reconfigure();
     
    169173{
    170174    if (settings.contains(RealtimeMediaSourceSettings::Flag::SampleRate)) {
    171         m_formatDescription = nullptr;
    172         m_audioBufferList = nullptr;
     175        m_workQueue->dispatch([this, protectedThis = makeRef(*this)] {
     176            m_formatDescription = nullptr;
     177            m_audioBufferList = nullptr;
    173178
    174         auto rate = sampleRate();
    175         size_t sampleCount = 2 * rate;
     179            auto rate = sampleRate();
     180            size_t sampleCount = 2 * rate;
    176181
    177         m_bipBopBuffer.grow(sampleCount);
    178         m_bipBopBuffer.fill(0);
     182            m_bipBopBuffer.grow(sampleCount);
     183            m_bipBopBuffer.fill(0);
    179184
    180         size_t bipBopSampleCount = ceil(BipBopDuration * rate);
    181         size_t bipStart = 0;
    182         size_t bopStart = rate;
     185            size_t bipBopSampleCount = ceil(BipBopDuration * rate);
     186            size_t bipStart = 0;
     187            size_t bopStart = rate;
    183188
    184         addHum(BipBopVolume, BipFrequency, rate, 0, m_bipBopBuffer.data() + bipStart, bipBopSampleCount);
    185         addHum(BipBopVolume, BopFrequency, rate, 0, m_bipBopBuffer.data() + bopStart, bipBopSampleCount);
     189            addHum(BipBopVolume, BipFrequency, rate, 0, m_bipBopBuffer.data() + bipStart, bipBopSampleCount);
     190            addHum(BipBopVolume, BopFrequency, rate, 0, m_bipBopBuffer.data() + bopStart, bipBopSampleCount);
     191        });
    186192    }
    187193
  • trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.cpp

    r239427 r247211  
    6363MockRealtimeAudioSource::MockRealtimeAudioSource(String&& deviceID, String&& name, String&& hashSalt)
    6464    : RealtimeMediaSource(RealtimeMediaSource::Type::Audio, WTFMove(name), WTFMove(deviceID), WTFMove(hashSalt))
     65    , m_workQueue(WorkQueue::create("MockRealtimeAudioSource Render Queue"))
    6566    , m_timer(RunLoop::current(), this, &MockRealtimeAudioSource::tick)
    6667{
     
    152153    Seconds delta = now - m_lastRenderTime;
    153154    m_lastRenderTime = now;
    154     render(delta);
     155
     156    m_workQueue->dispatch([this, delta, protectedThis = makeRef(*this)] {
     157        render(delta);
     158    });
    155159}
    156160
  • trunk/Source/WebCore/platform/mock/MockRealtimeAudioSource.h

    r239840 r247211  
    3737#include "RealtimeMediaSourceFactory.h"
    3838#include <wtf/RunLoop.h>
     39#include <wtf/WorkQueue.h>
    3940
    4041namespace WebCore {
     
    4243class MockRealtimeAudioSource : public RealtimeMediaSource {
    4344public:
    44 
    4545    static CaptureSourceOrError create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints*);
    46 
    4746    virtual ~MockRealtimeAudioSource();
    4847
     
    5049    MockRealtimeAudioSource(String&& deviceID, String&& name, String&& hashSalt);
    5150
    52     void startProducingData() final;
    53     void stopProducingData() final;
    54 
    55     virtual void render(Seconds) { }
     51    virtual void render(Seconds) = 0;
    5652    void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override;
    5753
     
    6258    const RealtimeMediaSourceSettings& settings() final;
    6359
    64     void tick();
     60    void startProducingData() final;
     61    void stopProducingData() final;
    6562
    6663    bool isCaptureSource() const final { return true; }
     
    6966    void delaySamples(Seconds) final;
    7067
     68    void tick();
     69
     70protected:
     71    Ref<WorkQueue> m_workQueue;
     72
     73private:
    7174    Optional<RealtimeMediaSourceCapabilities> m_capabilities;
    7275    Optional<RealtimeMediaSourceSettings> m_currentSettings;
Note: See TracChangeset for help on using the changeset viewer.