Changeset 261908 in webkit


Ignore:
Timestamp:
May 20, 2020 12:54:05 AM (4 years ago)
Author:
youenn@apple.com
Message:

Allow calling VideoSampleObserver::videoSampleAvailable from a background thread
https://bugs.webkit.org/show_bug.cgi?id=212024

Reviewed by Eric Carlson.

Allow RealtimeMediaSource::videoSampleAvailable to be called on a background thread, typically the capture thread.
Make WebRTC remote sources and mock capture sources do that.

RealtimeMediaSource is then updating its intrinsic size from the generation thread while updating its size in the main thread.
The size() getter can be called from both threads.

Existing consumers do the following:

  • media player will hop to the main thread.
  • media recorder will do processing from the background thread.
  • WebRTC sender will do processing from the background thread, except when sending black frames where this will still be done on the main thread.

This is ok as we ensure either we send black frames on the main thread (and we do not observe the source) or we observe the source to send.

Follow-ups will migrate the real capture sources as well as migrating media player processing out of the main thread.
Covered by existing tests.

  • platform/MediaSample.h:
  • platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:

(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::MediaPlayerPrivateMediaStreamAVFObjC):
(WebCore::MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable):

  • platform/mediastream/RealtimeMediaSource.cpp:

(WebCore::RealtimeMediaSource::videoSampleAvailable):
(WebCore::RealtimeMediaSource::setIntrinsicSize):

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

(WebCore::MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac):
(WebCore::MockRealtimeVideoSourceMac::updateSampleBuffer):

  • platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.h:
  • platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:

(WebCore::RealtimeIncomingVideoSourceCocoa::OnFrame):
(WebCore::RealtimeIncomingVideoSourceCocoa::processNewSample): Deleted.

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r261907 r261908  
     12020-05-20  Youenn Fablet  <youenn@apple.com>
     2
     3        Allow calling VideoSampleObserver::videoSampleAvailable from a background thread
     4        https://bugs.webkit.org/show_bug.cgi?id=212024
     5
     6        Reviewed by Eric Carlson.
     7
     8        Allow RealtimeMediaSource::videoSampleAvailable to be called on a background thread, typically the capture thread.
     9        Make WebRTC remote sources and mock capture sources do that.
     10
     11        RealtimeMediaSource is then updating its intrinsic size from the generation thread while updating its size in the main thread.
     12        The size() getter can be called from both threads.
     13
     14        Existing consumers do the following:
     15        - media player will hop to the main thread.
     16        - media recorder will do processing from the background thread.
     17        - WebRTC sender will do processing from the background thread, except when sending black frames where this will still be done on the main thread.
     18        This is ok as we ensure either we send black frames on the main thread (and we do not observe the source) or we observe the source to send.
     19
     20        Follow-ups will migrate the real capture sources as well as migrating media player processing out of the main thread.
     21        Covered by existing tests.
     22
     23        * platform/MediaSample.h:
     24        * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
     25        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::MediaPlayerPrivateMediaStreamAVFObjC):
     26        (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable):
     27        * platform/mediastream/RealtimeMediaSource.cpp:
     28        (WebCore::RealtimeMediaSource::videoSampleAvailable):
     29        (WebCore::RealtimeMediaSource::setIntrinsicSize):
     30        * platform/mediastream/RealtimeMediaSource.h:
     31        * platform/mediastream/mac/MockRealtimeVideoSourceMac.h:
     32        * platform/mediastream/mac/MockRealtimeVideoSourceMac.mm:
     33        (WebCore::MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac):
     34        (WebCore::MockRealtimeVideoSourceMac::updateSampleBuffer):
     35        * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.h:
     36        * platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm:
     37        (WebCore::RealtimeIncomingVideoSourceCocoa::OnFrame):
     38        (WebCore::RealtimeIncomingVideoSourceCocoa::processNewSample): Deleted.
     39
    1402020-05-20  Oriol Brufau  <obrufau@igalia.com>
    241
  • trunk/Source/WebCore/platform/MediaSample.h

    r261893 r261908  
    3131#include <wtf/EnumTraits.h>
    3232#include <wtf/MediaTime.h>
    33 #include <wtf/RefCounted.h>
     33#include <wtf/ThreadSafeRefCounted.h>
    3434#include <wtf/text/AtomString.h>
    3535
     
    5555};
    5656
    57 class MediaSample : public RefCounted<MediaSample> {
     57class MediaSample : public ThreadSafeRefCounted<MediaSample> {
    5858public:
    5959    virtual ~MediaSample() = default;
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h

    r261893 r261908  
    140140    MediaTime calculateTimelineOffset(const MediaSample&, double);
    141141   
    142     void enqueueVideoSample(MediaSample&);
    143142    void enqueueCorrectedVideoSample(MediaSample&);
    144143    void requestNotificationWhenReadyForVideoData();
  • trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm

    r261893 r261908  
    142142{
    143143    INFO_LOG(LOGIDENTIFIER);
     144    // MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable expects a weak pointer to be created in the constructor.
    144145    m_boundsChangeListener = adoptNS([[WebRootSampleBufferBoundsChangeListener alloc] initWithCallback:[this, weakThis = makeWeakPtr(this)] {
    145146        if (!weakThis)
     
    282283}
    283284
    284 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample(MediaSample& sample)
    285 {
     285void MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable(MediaSample& sample)
     286{
     287    if (!isMainThread()) {
     288        callOnMainThread([weakThis = makeWeakPtr(this), sample = makeRef(sample)]() mutable {
     289            if (weakThis)
     290                weakThis->videoSampleAvailable(sample.get());
     291        });
     292        return;
     293    }
     294
     295    if (!m_activeVideoTrack)
     296        return;
     297
    286298    if (!m_imagePainter.mediaSample || m_displayMode != PausedImage) {
    287299        m_imagePainter.mediaSample = &sample;
     
    734746{
    735747    updateTracks();
    736 }
    737 
    738 void MediaPlayerPrivateMediaStreamAVFObjC::videoSampleAvailable(MediaSample& mediaSample)
    739 {
    740     if (streamTime().toDouble() < 0)
    741         return;
    742 
    743     enqueueVideoSample(mediaSample);
    744748}
    745749
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp

    r261893 r261908  
    188188void RealtimeMediaSource::videoSampleAvailable(MediaSample& mediaSample)
    189189{
    190     // FIXME: Migrate RealtimeMediaSource clients to non main thread processing.
    191     ASSERT(isMainThread());
    192190#if !RELEASE_LOG_DISABLED
    193191    ++m_frameCount;
     
    967965    m_intrinsicSize = size;
    968966
    969     if (currentSize != this->size())
    970         notifySettingsDidChangeObservers({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
     967    if (currentSize != this->size()) {
     968        scheduleDeferredTask([this] {
     969            notifySettingsDidChangeObservers({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height });
     970        });
     971    }
    971972}
    972973
  • trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h

    r261893 r261908  
    103103        virtual ~VideoSampleObserver() = default;
    104104
    105         virtual void videoSampleAvailable(MediaSample&) { }
     105        // May be called on a background thread.
     106        virtual void videoSampleAvailable(MediaSample&) = 0;
    106107    };
    107108
     
    279280    HashSet<VideoSampleObserver*> m_videoSampleObservers;
    280281
     282    // Set on the main thread from constraints.
    281283    IntSize m_size;
     284    // Set on sample generation thread.
    282285    IntSize m_intrinsicSize;
    283286    double m_frameRate { 30 };
  • trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h

    r261893 r261908  
    3535#include "MockRealtimeVideoSource.h"
    3636#include "PixelBufferConformerCV.h"
     37#include <wtf/WorkQueue.h>
    3738
    3839typedef struct __CVBuffer *CVBufferRef;
     
    6162    std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession;
    6263    IntSize m_presetSize;
     64    Ref<WorkQueue> m_workQueue;
    6365};
    6466
  • trunk/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm

    r261893 r261908  
    7979MockRealtimeVideoSourceMac::MockRealtimeVideoSourceMac(String&& deviceID, String&& name, String&& hashSalt)
    8080    : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))
     81    , m_workQueue(WorkQueue::create("MockRealtimeVideoSource Render Queue", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive))
    8182{
    8283}
     
    9697        return;
    9798
    98     dispatchMediaSampleToObservers(*sampleBuffer);
     99    m_workQueue->dispatch([this, protectedThis = makeRef(*this), sampleBuffer = WTFMove(sampleBuffer)]() mutable {
     100        dispatchMediaSampleToObservers(*sampleBuffer);
     101    });
    99102}
    100103
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.h

    r261893 r261908  
    4444private:
    4545    RealtimeIncomingVideoSourceCocoa(rtc::scoped_refptr<webrtc::VideoTrackInterface>&&, String&&);
    46     void processNewSample(CMSampleBufferRef, unsigned, unsigned, MediaSample::VideoRotation);
    4746    RetainPtr<CVPixelBufferRef> pixelBufferFromVideoFrame(const webrtc::VideoFrame&);
    4847    CVPixelBufferPoolRef pixelBufferPool(size_t width, size_t height);
  • trunk/Source/WebCore/platform/mediastream/mac/RealtimeIncomingVideoSourceCocoa.mm

    r261893 r261908  
    194194    }
    195195
    196     callOnMainThread([protectedThis = makeRef(*this), sample = WTFMove(sample), width, height, rotation] {
    197         protectedThis->processNewSample(sample.get(), width, height, rotation);
    198     });
    199 }
    200 
    201 void RealtimeIncomingVideoSourceCocoa::processNewSample(CMSampleBufferRef sample, unsigned width, unsigned height, MediaSample::VideoRotation rotation)
    202 {
    203     auto size = this->size();
    204     if (WTF::safeCast<int>(width) != size.width() || WTF::safeCast<int>(height) != size.height())
    205         setIntrinsicSize(IntSize(width, height));
    206 
    207     videoSampleAvailable(MediaSampleAVFObjC::create(sample, rotation));
     196    setIntrinsicSize(IntSize(width, height));
     197    videoSampleAvailable(MediaSampleAVFObjC::create(sample.get(), rotation));
    208198}
    209199
Note: See TracChangeset for help on using the changeset viewer.