Changeset 259816 in webkit
- Timestamp:
- Apr 9, 2020, 12:44:21 PM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 35 edited
-
WebCore/ChangeLog (modified) (1 diff)
-
WebCore/Modules/mediarecorder/MediaRecorder.cpp (modified) (3 diffs)
-
WebCore/Modules/mediarecorder/MediaRecorder.h (modified) (4 diffs)
-
WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp (modified) (1 diff)
-
WebCore/Modules/mediarecorder/MediaRecorderProvider.h (modified) (1 diff)
-
WebCore/loader/EmptyClients.cpp (modified) (1 diff)
-
WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (modified) (2 diffs)
-
WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp (modified) (1 diff)
-
WebCore/platform/mediarecorder/MediaRecorderPrivate.h (modified) (3 diffs)
-
WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp (modified) (5 diffs)
-
WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h (modified) (2 diffs)
-
WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp (modified) (2 diffs)
-
WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h (modified) (1 diff)
-
WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp (modified) (4 diffs)
-
WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h (modified) (5 diffs)
-
WebCore/platform/mediastream/MediaStreamPrivate.cpp (modified) (1 diff)
-
WebCore/platform/mediastream/MediaStreamPrivate.h (modified) (1 diff)
-
WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp (modified) (4 diffs)
-
WebCore/platform/mediastream/MediaStreamTrackPrivate.h (modified) (4 diffs)
-
WebCore/platform/mediastream/RealtimeMediaSource.cpp (modified) (4 diffs)
-
WebCore/platform/mediastream/RealtimeMediaSource.h (modified) (5 diffs)
-
WebCore/platform/mediastream/RealtimeOutgoingAudioSource.cpp (modified) (3 diffs)
-
WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h (modified) (3 diffs)
-
WebCore/platform/mediastream/WebAudioSourceProvider.h (modified) (1 diff)
-
WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp (modified) (5 diffs)
-
WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h (modified) (3 diffs)
-
WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm (modified) (2 diffs)
-
WebCore/testing/Internals.cpp (modified) (4 diffs)
-
WebCore/testing/Internals.h (modified) (3 diffs)
-
WebKit/ChangeLog (modified) (1 diff)
-
WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp (modified) (3 diffs)
-
WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp (modified) (5 diffs)
-
WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h (modified) (2 diffs)
-
WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.cpp (modified) (1 diff)
-
WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r259813 r259816 1 2020-04-09 Youenn Fablet <youenn@apple.com> 2 3 Introduce a RealtimeMediaSource observer dedicated to receiving audio samples 4 https://bugs.webkit.org/show_bug.cgi?id=210180 5 6 Reviewed by Eric Carlson. 7 8 RealtimeMediaSource::Observer was called on various threads which was making iterating through them difficult. 9 Observers were copied to a vector for iterating each time and locking was happening for each indivudual observer. 10 11 Instead of doing that, RealtimeMediaSource::Observer no longer gives access to audio samples, all its methods are called from the main thread. 12 AudioSampleObserver is introduced with a single method to receive audio samples. 13 RealtimeMediaSource keeps a set of AudioSampleObserver separated from its existing Observer hashset. 14 These observers can only be added/removed from the main thread while audio sample delivery usually happens from a background thread. 15 We no longer need to copy the audio sample observers in a vector and lock only once when iterating the audio sample observers. 16 17 This change requires to update MediaStreamTrackPrivate and RealtimeMediaSource observers. 18 This includes WebAudio, Audio Renderer and Media Recorder. 19 Each corresponding class is now registering itself as a MediaStreamTrackPrivate::Observer and when needed as a RealtimeMediaSource::Observer. 20 This allows removing the additional copy-in-vector/lock that was happening when iterating over MediaStreamTrackPrivate::Observers for audio samples. 21 22 This change also allows for a consumer to always observe the MediaStreamTrackPrivate but receive audio samples only when needed. 23 We change the AudioTrackPrivateMediaStream implementation so that, if the renderer is muted, not playing, the track is muted or not enabled, 24 it no longer receives audio samples. 25 This is especially useful in the typical case where a video element displays the locally captured stream (including a local audio track) but is muted 26 to prevent feedback loop. 27 For that reason, the player is now setting the muted state of the renderer instead of setting volume to 0. 28 29 Covered by existing test sets. 30 31 * Modules/mediarecorder/MediaRecorder.cpp: 32 (WebCore::MediaRecorder::createMediaRecorderPrivate): 33 * Modules/mediarecorder/MediaRecorder.h: 34 * Modules/mediarecorder/MediaRecorderProvider.cpp: 35 (WebCore::MediaRecorderProvider::createMediaRecorderPrivate): 36 * Modules/mediarecorder/MediaRecorderProvider.h: 37 * loader/EmptyClients.cpp: 38 * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm: 39 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVolume): 40 (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setMuted): 41 * platform/mediarecorder/MediaRecorderPrivate.cpp: 42 (WebCore::MediaRecorderPrivate::selectTracks): 43 * platform/mediarecorder/MediaRecorderPrivate.h: 44 (WebCore::MediaRecorderPrivate::setAudioSource): 45 (WebCore::MediaRecorderPrivate::~MediaRecorderPrivate): 46 * platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp: 47 (WebCore::MediaRecorderPrivateAVFImpl::create): 48 (WebCore::MediaRecorderPrivateAVFImpl::~MediaRecorderPrivateAVFImpl): 49 (WebCore::MediaRecorderPrivateAVFImpl::audioSamplesAvailable): 50 (WebCore::MediaRecorderPrivateAVFImpl::stopRecording): 51 (WebCore::MediaRecorderPrivateAVFImpl::fetchData): 52 * platform/mediarecorder/MediaRecorderPrivateAVFImpl.h: 53 * platform/mediarecorder/MediaRecorderPrivateMock.cpp: 54 (WebCore::MediaRecorderPrivateMock::MediaRecorderPrivateMock): 55 (WebCore::MediaRecorderPrivateMock::~MediaRecorderPrivateMock): 56 (WebCore::MediaRecorderPrivateMock::stopRecording): 57 (WebCore::MediaRecorderPrivateMock::sampleBufferUpdated): 58 (WebCore::MediaRecorderPrivateMock::audioSamplesAvailable): 59 (WebCore::MediaRecorderPrivateMock::generateMockCounterString): 60 (WebCore::MediaRecorderPrivateMock::fetchData): 61 * platform/mediarecorder/MediaRecorderPrivateMock.h: 62 * platform/mediastream/AudioTrackPrivateMediaStream.cpp: 63 (WebCore::AudioTrackPrivateMediaStream::AudioTrackPrivateMediaStream): 64 (WebCore::AudioTrackPrivateMediaStream::clear): 65 (WebCore::AudioTrackPrivateMediaStream::play): 66 (WebCore::AudioTrackPrivateMediaStream::pause): 67 (WebCore::AudioTrackPrivateMediaStream::setMuted): 68 (WebCore::AudioTrackPrivateMediaStream::audioSamplesAvailable): 69 (WebCore::AudioTrackPrivateMediaStream::trackMutedChanged): 70 (WebCore::AudioTrackPrivateMediaStream::trackEnabledChanged): 71 (WebCore::AudioTrackPrivateMediaStream::trackEnded): 72 (WebCore::AudioTrackPrivateMediaStream::updateRenderer): 73 (WebCore::AudioTrackPrivateMediaStream::startRenderer): 74 (WebCore::AudioTrackPrivateMediaStream::stopRenderer): 75 * platform/mediastream/AudioTrackPrivateMediaStream.h: 76 * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp: 77 (WebCore::webkitMediaStreamSrcFinalize): 78 (WebCore::webkitMediaStreamSrcChangeState): 79 (WebCore::webkitMediaStreamSrcSetupSrc): 80 * platform/mediastream/MediaStreamPrivate.cpp: 81 (WebCore::MediaStreamPrivate::forEachTrack): 82 * platform/mediastream/MediaStreamPrivate.h: 83 * platform/mediastream/MediaStreamTrackPrivate.cpp: 84 (WebCore::MediaStreamTrackPrivate::forEachObserver const): 85 (WebCore::MediaStreamTrackPrivate::addObserver): 86 (WebCore::MediaStreamTrackPrivate::removeObserver): 87 (WebCore::MediaStreamTrackPrivate::hasStartedProducingAudioData): 88 * platform/mediastream/MediaStreamTrackPrivate.h: 89 * platform/mediastream/RealtimeMediaSource.cpp: 90 (WebCore::RealtimeMediaSource::addAudioSampleObserver): 91 (WebCore::RealtimeMediaSource::removeAudioSampleObserver): 92 (WebCore::RealtimeMediaSource::addObserver): 93 (WebCore::RealtimeMediaSource::removeObserver): 94 (WebCore::RealtimeMediaSource::forEachObserver const): 95 (WebCore::RealtimeMediaSource::audioSamplesAvailable): 96 * platform/mediastream/RealtimeMediaSource.h: 97 * platform/mediastream/RealtimeOutgoingAudioSource.cpp: 98 (WebCore::RealtimeOutgoingAudioSource::~RealtimeOutgoingAudioSource): 99 (WebCore::RealtimeOutgoingAudioSource::observeSource): 100 (WebCore::RealtimeOutgoingAudioSource::unobserveSource): 101 * platform/mediastream/RealtimeOutgoingAudioSource.h: 102 * platform/mediastream/WebAudioSourceProvider.h: 103 * platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h: 104 * platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm: 105 (WebCore::WebAudioSourceProviderAVFObjC::WebAudioSourceProviderAVFObjC): 106 (WebCore::WebAudioSourceProviderAVFObjC::~WebAudioSourceProviderAVFObjC): 107 (WebCore::WebAudioSourceProviderAVFObjC::trackEnabledChanged): 108 (WebCore::WebAudioSourceProviderAVFObjC::audioSamplesAvailable): 109 * testing/Internals.cpp: 110 (WebCore::Internals::~Internals): 111 (WebCore::createRecorderMockSource): 112 (WebCore::Internals::observeMediaStreamTrack): 113 (WebCore::Internals::videoSampleAvailable): 114 * testing/Internals.h: 115 1 116 2020-04-09 Antti Koivisto <antti@apple.com> 2 117 -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp
r259252 r259816 45 45 WTF_MAKE_ISO_ALLOCATED_IMPL(MediaRecorder); 46 46 47 creatorFunction MediaRecorder::m_customCreator = nullptr;47 MediaRecorder::CreatorFunction MediaRecorder::m_customCreator = nullptr; 48 48 49 49 ExceptionOr<Ref<MediaRecorder>> MediaRecorder::create(Document& document, Ref<MediaStream>&& stream, Options&& options) … … 60 60 } 61 61 62 void MediaRecorder::setCustomPrivateRecorderCreator( creatorFunction creator)62 void MediaRecorder::setCustomPrivateRecorderCreator(CreatorFunction creator) 63 63 { 64 64 m_customCreator = creator; 65 65 } 66 66 67 std::unique_ptr<MediaRecorderPrivate> MediaRecorder::createMediaRecorderPrivate(Document& document, constMediaStreamPrivate& stream)67 std::unique_ptr<MediaRecorderPrivate> MediaRecorder::createMediaRecorderPrivate(Document& document, MediaStreamPrivate& stream) 68 68 { 69 69 if (m_customCreator) 70 return m_customCreator( );70 return m_customCreator(stream); 71 71 72 72 #if PLATFORM(COCOA) … … 228 228 } 229 229 230 void MediaRecorder::audioSamplesAvailable(MediaStreamTrackPrivate& track, const MediaTime& mediaTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)231 {232 m_private->audioSamplesAvailable(track, mediaTime, audioData, description, sampleCount);233 }234 235 230 bool MediaRecorder::virtualHasPendingActivity() const 236 231 { -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorder.h
r259252 r259816 39 39 class MediaRecorderPrivate; 40 40 41 typedef std::unique_ptr<MediaRecorderPrivate>(*creatorFunction)();42 43 41 class MediaRecorder final 44 42 : public ActiveDOMObject … … 63 61 static ExceptionOr<Ref<MediaRecorder>> create(Document&, Ref<MediaStream>&&, Options&& = { }); 64 62 65 WEBCORE_EXPORT static void setCustomPrivateRecorderCreator(creatorFunction); 63 using CreatorFunction = std::unique_ptr<MediaRecorderPrivate>(*)(MediaStreamPrivate&); 64 65 WEBCORE_EXPORT static void setCustomPrivateRecorderCreator(CreatorFunction); 66 66 67 67 RecordingState state() const { return m_state; } … … 79 79 MediaRecorder(Document&, Ref<MediaStream>&&, std::unique_ptr<MediaRecorderPrivate>&&, Options&& = { }); 80 80 81 static std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(Document&, constMediaStreamPrivate&);81 static std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(Document&, MediaStreamPrivate&); 82 82 83 83 Document* document() const; … … 108 108 void trackEnabledChanged(MediaStreamTrackPrivate&) final { }; 109 109 void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) final; 110 void audioSamplesAvailable(MediaStreamTrackPrivate&, const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 111 112 static creatorFunction m_customCreator; 110 111 static CreatorFunction m_customCreator; 113 112 114 113 Options m_options; -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.cpp
r256493 r259816 33 33 namespace WebCore { 34 34 35 std::unique_ptr<MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate( constMediaStreamPrivate& stream)35 std::unique_ptr<MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream) 36 36 { 37 37 return MediaRecorderPrivateAVFImpl::create(stream); -
trunk/Source/WebCore/Modules/mediarecorder/MediaRecorderProvider.h
r254194 r259816 38 38 39 39 #if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA) 40 virtual std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate( constMediaStreamPrivate&);40 virtual std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&); 41 41 #endif 42 42 -
trunk/Source/WebCore/loader/EmptyClients.cpp
r258628 r259816 583 583 private: 584 584 #if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA) 585 std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate( constMediaStreamPrivate&) final { return nullptr; }585 std::unique_ptr<MediaRecorderPrivate> createMediaRecorderPrivate(MediaStreamPrivate&) final { return nullptr; } 586 586 #endif 587 587 }; -
trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm
r258503 r259816 561 561 m_volume = volume; 562 562 for (const auto& track : m_audioTrackMap.values()) 563 track->setVolume(m_ muted ? 0 : m_volume);563 track->setVolume(m_volume); 564 564 } 565 565 … … 572 572 m_muted = muted; 573 573 for (const auto& track : m_audioTrackMap.values()) 574 track->set Volume(m_muted ? 0 : m_volume);574 track->setMuted(m_muted); 575 575 } 576 576 -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp
r256658 r259816 33 33 namespace WebCore { 34 34 35 MediaRecorderPrivate::AudioVideoSelectedTracks MediaRecorderPrivate::selectTracks( constMediaStreamPrivate& stream)35 MediaRecorderPrivate::AudioVideoSelectedTracks MediaRecorderPrivate::selectTracks(MediaStreamPrivate& stream) 36 36 { 37 37 AudioVideoSelectedTracks selectedTracks; -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h
r256658 r259816 28 28 #include <wtf/Forward.h> 29 29 #include "Exception.h" 30 #include "RealtimeMediaSource.h" 30 31 31 32 #if ENABLE(MEDIA_STREAM) … … 44 45 class SharedBuffer; 45 46 46 class MediaRecorderPrivate { 47 class MediaRecorderPrivate : 48 public RealtimeMediaSource::AudioSampleObserver { 47 49 public: 48 virtual ~MediaRecorderPrivate() = default;50 ~MediaRecorderPrivate(); 49 51 50 52 struct AudioVideoSelectedTracks { 51 constMediaStreamTrackPrivate* audioTrack { nullptr };52 constMediaStreamTrackPrivate* videoTrack { nullptr };53 MediaStreamTrackPrivate* audioTrack { nullptr }; 54 MediaStreamTrackPrivate* videoTrack { nullptr }; 53 55 }; 54 WEBCORE_EXPORT static AudioVideoSelectedTracks selectTracks( constMediaStreamPrivate&);56 WEBCORE_EXPORT static AudioVideoSelectedTracks selectTracks(MediaStreamPrivate&); 55 57 56 58 virtual void sampleBufferUpdated(const MediaStreamTrackPrivate&, MediaSample&) = 0; 57 virtual void audioSamplesAvailable(const MediaStreamTrackPrivate&, const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) = 0;58 59 59 virtual void fetchData(CompletionHandler<void(RefPtr<SharedBuffer>&&, const String& mimeType)>&&) = 0; 60 virtual void stopRecording() { }; 60 using FetchDataCallback = CompletionHandler<void(RefPtr<SharedBuffer>&&, const String& mimeType)>; 61 virtual void fetchData(FetchDataCallback&&) = 0; 62 virtual void stopRecording() = 0; 61 63 62 64 using ErrorCallback = Function<void(Optional<Exception>&&)>; … … 64 66 65 67 protected: 68 void setAudioSource(RefPtr<RealtimeMediaSource>&&); 69 70 protected: 66 71 ErrorCallback m_errorCallback; 72 73 private: 74 RefPtr<RealtimeMediaSource> m_audioSource; 67 75 }; 76 77 inline void MediaRecorderPrivate::setAudioSource(RefPtr<RealtimeMediaSource>&& audioSource) 78 { 79 if (m_audioSource) 80 m_audioSource->removeAudioSampleObserver(*this); 81 82 m_audioSource = WTFMove(audioSource); 83 84 if (m_audioSource) 85 m_audioSource->addAudioSampleObserver(*this); 86 } 87 88 inline MediaRecorderPrivate::~MediaRecorderPrivate() 89 { 90 if (m_audioSource) 91 m_audioSource->removeAudioSampleObserver(*this); 92 } 68 93 69 94 } // namespace WebCore -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.cpp
r256658 r259816 37 37 namespace WebCore { 38 38 39 std::unique_ptr<MediaRecorderPrivateAVFImpl> MediaRecorderPrivateAVFImpl::create( constMediaStreamPrivate& stream)39 std::unique_ptr<MediaRecorderPrivateAVFImpl> MediaRecorderPrivateAVFImpl::create(MediaStreamPrivate& stream) 40 40 { 41 41 // FIXME: we will need to implement support for multiple audio/video tracks … … 52 52 if (selectedTracks.audioTrack) 53 53 audioTrackId = selectedTracks.audioTrack->id(); 54 54 55 String videoTrackId; 55 56 if (selectedTracks.videoTrack) 56 57 videoTrackId = selectedTracks.videoTrack->id(); 57 58 58 return makeUnique<MediaRecorderPrivateAVFImpl>(writer.releaseNonNull(), WTFMove(audioTrackId), WTFMove(videoTrackId)); 59 auto recorder = makeUnique<MediaRecorderPrivateAVFImpl>(writer.releaseNonNull(), WTFMove(audioTrackId), WTFMove(videoTrackId)); 60 if (selectedTracks.audioTrack) 61 recorder->setAudioSource(&selectedTracks.audioTrack->source()); 62 return recorder; 59 63 } 60 64 … … 66 70 } 67 71 72 MediaRecorderPrivateAVFImpl::~MediaRecorderPrivateAVFImpl() 73 { 74 setAudioSource(nullptr); 75 } 76 68 77 void MediaRecorderPrivateAVFImpl::sampleBufferUpdated(const MediaStreamTrackPrivate& track, MediaSample& sampleBuffer) 69 78 { … … 73 82 } 74 83 75 void MediaRecorderPrivateAVFImpl::audioSamplesAvailable(const MediaStreamTrackPrivate& track, constWTF::MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount)84 void MediaRecorderPrivateAVFImpl::audioSamplesAvailable(const WTF::MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount) 76 85 { 77 if (track.id() != m_recordedAudioTrackID)78 return;79 86 ASSERT(is<WebAudioBufferList>(data)); 80 87 ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType); … … 84 91 void MediaRecorderPrivateAVFImpl::stopRecording() 85 92 { 93 setAudioSource(nullptr); 86 94 m_writer->stopRecording(); 87 95 } 88 96 89 void MediaRecorderPrivateAVFImpl::fetchData( CompletionHandler<void(RefPtr<SharedBuffer>&&, const String&)>&& completionHandler)97 void MediaRecorderPrivateAVFImpl::fetchData(FetchDataCallback&& completionHandler) 90 98 { 91 99 m_writer->fetchData([completionHandler = WTFMove(completionHandler), mimeType = mimeType()](auto&& buffer) mutable { -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateAVFImpl.h
r256493 r259816 34 34 class MediaStreamPrivate; 35 35 36 class MediaRecorderPrivateAVFImpl final : public MediaRecorderPrivate { 36 class MediaRecorderPrivateAVFImpl final 37 : public MediaRecorderPrivate { 37 38 WTF_MAKE_FAST_ALLOCATED; 38 39 public: 39 static std::unique_ptr<MediaRecorderPrivateAVFImpl> create(const MediaStreamPrivate&); 40 static std::unique_ptr<MediaRecorderPrivateAVFImpl> create(MediaStreamPrivate&); 41 ~MediaRecorderPrivateAVFImpl(); 40 42 41 43 private: … … 44 46 friend std::unique_ptr<MediaRecorderPrivateAVFImpl> std::make_unique<MediaRecorderPrivateAVFImpl>(Ref<MediaRecorderPrivateWriter>&&, String&&, String&&); 45 47 48 // MediaRecorderPrivate 46 49 void sampleBufferUpdated(const MediaStreamTrackPrivate&, MediaSample&) final; 47 void audioSamplesAvailable(const MediaStreamTrackPrivate&, const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 48 void fetchData(CompletionHandler<void(RefPtr<SharedBuffer>&&, const String&)>&&) final; 50 void fetchData(FetchDataCallback&&) final; 51 void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 52 49 53 const String& mimeType(); 50 54 void stopRecording(); 51 55 52 56 Ref<MediaRecorderPrivateWriter> m_writer; 53 57 String m_recordedAudioTrackID; -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.cpp
r254194 r259816 34 34 namespace WebCore { 35 35 36 void MediaRecorderPrivateMock::sampleBufferUpdated(const MediaStreamTrackPrivate& track, MediaSample&)36 MediaRecorderPrivateMock::MediaRecorderPrivateMock(MediaStreamPrivate& stream) 37 37 { 38 generateMockString(track); 38 auto selectedTracks = MediaRecorderPrivate::selectTracks(stream); 39 if (selectedTracks.audioTrack) { 40 m_audioTrackID = selectedTracks.audioTrack->id(); 41 setAudioSource(&selectedTracks.audioTrack->source()); 42 } 43 if (selectedTracks.videoTrack) 44 m_videoTrackID = selectedTracks.videoTrack->id(); 39 45 } 40 46 41 void MediaRecorderPrivateMock::audioSamplesAvailable(const MediaStreamTrackPrivate& track, const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t)47 MediaRecorderPrivateMock::~MediaRecorderPrivateMock() 42 48 { 43 generateMockString(track);49 setAudioSource(nullptr); 44 50 } 45 51 46 void MediaRecorderPrivateMock::generateMockString(const MediaStreamTrackPrivate& track) 52 void MediaRecorderPrivateMock::stopRecording() 53 { 54 setAudioSource(nullptr); 55 } 56 57 void MediaRecorderPrivateMock::sampleBufferUpdated(const MediaStreamTrackPrivate&, MediaSample&) 47 58 { 48 59 auto locker = holdLock(m_bufferLock); 49 if (track.type() == RealtimeMediaSource::Type::Audio) 50 m_buffer.append("Audio Track ID: "); 51 else 52 m_buffer.append("Video Track ID: "); 53 m_buffer.append(track.id()); 60 m_buffer.append("Video Track ID: "); 61 m_buffer.append(m_videoTrackID); 62 generateMockCounterString(); 63 } 64 65 void MediaRecorderPrivateMock::audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) 66 { 67 auto locker = holdLock(m_bufferLock); 68 m_buffer.append("Audio Track ID: "); 69 m_buffer.append(m_audioTrackID); 70 generateMockCounterString(); 71 } 72 73 void MediaRecorderPrivateMock::generateMockCounterString() 74 { 54 75 m_buffer.append(" Counter: "); 55 76 m_buffer.appendNumber(++m_counter); … … 57 78 } 58 79 59 void MediaRecorderPrivateMock::fetchData( CompletionHandler<void(RefPtr<SharedBuffer>&&, const String&)>&& completionHandler)80 void MediaRecorderPrivateMock::fetchData(FetchDataCallback&& completionHandler) 60 81 { 61 82 auto locker = holdLock(m_bufferLock); -
trunk/Source/WebCore/platform/mediarecorder/MediaRecorderPrivateMock.h
r254194 r259816 35 35 class MediaStreamTrackPrivate; 36 36 37 class WEBCORE_EXPORT MediaRecorderPrivateMock final : public MediaRecorderPrivate { 37 class WEBCORE_EXPORT MediaRecorderPrivateMock final 38 : public MediaRecorderPrivate { 39 public: 40 explicit MediaRecorderPrivateMock(MediaStreamPrivate&); 41 ~MediaRecorderPrivateMock(); 42 38 43 private: 44 // MediaRecorderPrivate 39 45 void sampleBufferUpdated(const MediaStreamTrackPrivate&, MediaSample&) final; 40 void audioSamplesAvailable(const MediaStreamTrackPrivate&, const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 41 void fetchData(CompletionHandler<void(RefPtr<SharedBuffer>&&, const String&)>&&) final; 46 void fetchData(FetchDataCallback&&) final; 47 void audioSamplesAvailable(const WTF::MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 48 void stopRecording() final; 49 42 50 const String& mimeType(); 43 44 void generateMockString(const MediaStreamTrackPrivate&); 51 void generateMockCounterString(); 45 52 46 53 mutable Lock m_bufferLock; 47 54 StringBuilder m_buffer; 48 55 unsigned m_counter { 0 }; 56 String m_audioTrackID; 57 String m_videoTrackID; 49 58 }; 50 59 -
trunk/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.cpp
r258840 r259816 36 36 AudioTrackPrivateMediaStream::AudioTrackPrivateMediaStream(MediaStreamTrackPrivate& track) 37 37 : m_streamTrack(track) 38 , m_audioSource(track.source()) 38 39 , m_id(track.id()) 39 40 , m_label(track.label()) 40 , m_timelineOffset(MediaTime::invalidTime())41 41 , m_renderer { AudioMediaStreamTrackRenderer::create() } 42 42 { … … 63 63 64 64 m_isCleared = true; 65 streamTrack().removeObserver(*this);66 67 m_renderer->clear();68 }69 70 void AudioTrackPrivateMediaStream::playInternal()71 {72 ASSERT(isMainThread());73 65 74 66 if (m_isPlaying) 75 return;67 m_audioSource->removeAudioSampleObserver(*this); 76 68 77 m_isPlaying = true; 78 m_autoPlay = false; 79 80 m_renderer->start(); 69 streamTrack().removeObserver(*this); 70 m_renderer->clear(); 81 71 } 82 72 83 73 void AudioTrackPrivateMediaStream::play() 84 74 { 85 playInternal(); 75 m_shouldPlay = true; 76 updateRenderer(); 86 77 } 87 78 88 79 void AudioTrackPrivateMediaStream::pause() 89 80 { 90 ASSERT(isMainThread()); 81 m_shouldPlay = false; 82 updateRenderer(); 83 } 91 84 92 if (!m_isPlaying) 93 return; 94 95 m_isPlaying = false; 96 m_autoPlay = false; 97 98 m_renderer->stop(); 85 void AudioTrackPrivateMediaStream::setMuted(bool muted) 86 { 87 m_muted = muted; 88 updateRenderer(); 99 89 } 100 90 … … 102 92 { 103 93 m_renderer->setVolume(volume); 94 updateRenderer(); 104 95 } 105 96 … … 110 101 111 102 // May get called on a background thread. 112 void AudioTrackPrivateMediaStream::audioSamplesAvailable( MediaStreamTrackPrivate&,const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)103 void AudioTrackPrivateMediaStream::audioSamplesAvailable(const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount) 113 104 { 114 if (!m_isPlaying) {115 m_renderer->stop();116 return;117 }118 119 105 m_renderer->pushSamples(sampleTime, audioData, description, sampleCount); 120 121 if (m_autoPlay && !m_hasStartedAutoplay) {122 m_hasStartedAutoplay = true;123 callOnMainThread([this, protectedThis = makeRef(*this)] {124 if (m_autoPlay)125 playInternal();126 });127 }128 106 } 129 107 130 108 void AudioTrackPrivateMediaStream::trackMutedChanged(MediaStreamTrackPrivate&) 131 109 { 132 updateRenderer MutedState();110 updateRenderer(); 133 111 } 134 112 135 113 void AudioTrackPrivateMediaStream::trackEnabledChanged(MediaStreamTrackPrivate&) 136 114 { 137 updateRendererMutedState(); 138 } 139 140 void AudioTrackPrivateMediaStream::updateRendererMutedState() 141 { 142 if (streamTrack().muted() || streamTrack().ended() || !streamTrack().enabled()) { 143 pause(); 144 return; 145 } 146 play(); 115 updateRenderer(); 147 116 } 148 117 149 118 void AudioTrackPrivateMediaStream::trackEnded(MediaStreamTrackPrivate&) 150 119 { 151 pause(); 120 updateRenderer(); 121 } 122 123 void AudioTrackPrivateMediaStream::updateRenderer() 124 { 125 if (!m_shouldPlay || !volume() || m_muted || streamTrack().muted() || streamTrack().ended() || !streamTrack().enabled()) { 126 stopRenderer(); 127 return; 128 } 129 startRenderer(); 130 } 131 132 void AudioTrackPrivateMediaStream::startRenderer() 133 { 134 ASSERT(isMainThread()); 135 if (m_isPlaying) 136 return; 137 138 m_isPlaying = true; 139 m_audioSource->addAudioSampleObserver(*this); 140 m_renderer->start(); 141 } 142 143 void AudioTrackPrivateMediaStream::stopRenderer() 144 { 145 ASSERT(isMainThread()); 146 if (!m_isPlaying) 147 return; 148 149 m_isPlaying = false; 150 m_audioSource->removeAudioSampleObserver(*this); 151 m_renderer->stop(); 152 152 } 153 153 -
trunk/Source/WebCore/platform/mediastream/AudioTrackPrivateMediaStream.h
r254446 r259816 35 35 class AudioMediaStreamTrackRenderer; 36 36 37 class AudioTrackPrivateMediaStream final : public AudioTrackPrivate, private MediaStreamTrackPrivate::Observer { 37 class AudioTrackPrivateMediaStream final 38 : public AudioTrackPrivate 39 , private MediaStreamTrackPrivate::Observer 40 , private RealtimeMediaSource::AudioSampleObserver { 38 41 WTF_MAKE_NONCOPYABLE(AudioTrackPrivateMediaStream) 39 42 public: … … 48 51 MediaStreamTrackPrivate& streamTrack() { return m_streamTrack.get(); } 49 52 50 MediaTime timelineOffset() const { return m_timelineOffset; }51 void setTimelineOffset(const MediaTime& offset) { m_timelineOffset = offset; }52 53 53 void clear(); 54 54 … … 60 60 float volume() const; 61 61 62 void setMuted(bool muted) { m_muted = muted; }62 void setMuted(bool); 63 63 bool muted() const { return m_muted; } 64 64 … … 78 78 79 79 // MediaStreamTrackPrivate::Observer 80 void audioSamplesAvailable(MediaStreamTrackPrivate&, const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;81 80 void trackEnded(MediaStreamTrackPrivate&) final; 82 81 void trackMutedChanged(MediaStreamTrackPrivate&) final; … … 84 83 void trackSettingsChanged(MediaStreamTrackPrivate&) final { } 85 84 86 void playInternal(); 87 void updateRendererMutedState(); 85 // RealtimeMediaSource::AudioSampleObserver 86 void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 87 88 void startRenderer(); 89 void stopRenderer(); 90 void updateRenderer(); 88 91 89 92 // Main thread writable members 90 93 bool m_isPlaying { false }; 91 bool m_ autoPlay { false };94 bool m_shouldPlay { false }; 92 95 bool m_muted { false }; 93 96 bool m_isCleared { false }; 94 97 95 98 Ref<MediaStreamTrackPrivate> m_streamTrack; 99 Ref<RealtimeMediaSource> m_audioSource; 96 100 AtomString m_id; 97 101 AtomString m_label; 98 102 int m_index { 0 }; 99 MediaTime m_timelineOffset;100 103 101 104 // Audio thread members 102 105 std::unique_ptr<AudioMediaStreamTrackRenderer> m_renderer; 103 bool m_hasStartedAutoplay { false };104 106 }; 105 107 -
trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.cpp
r258201 r259816 122 122 } 123 123 124 void MediaStreamPrivate::forEachTrack(const Function<void(MediaStreamTrackPrivate&)>& callback) 125 { 126 for (auto& track : m_trackSet.values()) 127 callback(*track); 128 } 129 124 130 void MediaStreamPrivate::updateActiveState(NotifyClientOption notifyClientOption) 125 131 { -
trunk/Source/WebCore/platform/mediastream/MediaStreamPrivate.h
r258201 r259816 85 85 bool hasTracks() const { return !m_trackSet.isEmpty(); } 86 86 void forEachTrack(const Function<void(const MediaStreamTrackPrivate&)>&) const; 87 void forEachTrack(const Function<void(MediaStreamTrackPrivate&)>&); 87 88 MediaStreamTrackPrivate* activeVideoTrack() { return m_activeVideoTrack; } 88 89 -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.cpp
r257039 r259816 79 79 } 80 80 81 void MediaStreamTrackPrivate::forEachObserver(const WTF::Function<void(Observer&)>& apply) const 82 { 83 Vector<Observer*> observersCopy; 84 { 85 auto locker = holdLock(m_observersLock); 86 observersCopy = copyToVector(m_observers); 87 } 88 for (auto* observer : observersCopy) { 89 auto locker = holdLock(m_observersLock); 90 // Make sure the observer has not been destroyed. 81 void MediaStreamTrackPrivate::forEachObserver(const Function<void(Observer&)>& apply) const 82 { 83 ASSERT(isMainThread()); 84 for (auto* observer : copyToVector(m_observers)) { 91 85 if (!m_observers.contains(observer)) 92 86 continue; … … 97 91 void MediaStreamTrackPrivate::addObserver(MediaStreamTrackPrivate::Observer& observer) 98 92 { 99 auto locker = holdLock(m_observersLock);93 ASSERT(isMainThread()); 100 94 m_observers.add(&observer); 101 95 } … … 103 97 void MediaStreamTrackPrivate::removeObserver(MediaStreamTrackPrivate::Observer& observer) 104 98 { 105 auto locker = holdLock(m_observersLock);99 ASSERT(isMainThread()); 106 100 m_observers.remove(&observer); 107 101 } … … 262 256 } 263 257 264 // May get called on a background thread. 265 void MediaStreamTrackPrivate::audioSamplesAvailable(const MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount) 266 { 267 if (!m_hasSentStartProducedData) { 268 callOnMainThread([this, weakThis = makeWeakPtr(this)] { 269 if (!weakThis) 270 return; 271 272 if (!m_haveProducedData) { 273 m_haveProducedData = true; 274 updateReadyState(); 275 } 276 m_hasSentStartProducedData = true; 277 }); 278 return; 279 } 280 281 forEachObserver([&](auto& observer) { 282 observer.audioSamplesAvailable(*this, mediaTime, data, description, sampleCount); 283 }); 258 void MediaStreamTrackPrivate::hasStartedProducingAudioData() 259 { 260 if (m_haveProducedData) 261 return; 262 m_haveProducedData = true; 263 updateReadyState(); 284 264 } 285 265 -
trunk/Source/WebCore/platform/mediastream/MediaStreamTrackPrivate.h
r257039 r259816 63 63 virtual void sampleBufferUpdated(MediaStreamTrackPrivate&, MediaSample&) { }; 64 64 virtual void readyStateChanged(MediaStreamTrackPrivate&) { }; 65 66 // May get called on a background thread.67 virtual void audioSamplesAvailable(MediaStreamTrackPrivate&, const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) { };68 65 }; 69 66 … … 101 98 102 99 RealtimeMediaSource& source() { return m_source.get(); } 100 const RealtimeMediaSource& source() const { return m_source.get(); } 103 101 WEBCORE_EXPORT RealtimeMediaSource::Type type() const; 104 102 … … 133 131 MediaStreamTrackPrivate(Ref<const Logger>&&, Ref<RealtimeMediaSource>&&, String&& id); 134 132 135 // RealtimeMediaSource Observer133 // RealtimeMediaSource::Observer 136 134 void sourceStarted() final; 137 135 void sourceStopped() final; … … 140 138 bool preventSourceFromStopping() final; 141 139 void videoSampleAvailable(MediaSample&) final; 142 void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;143 140 void audioUnitWillStart() final; 141 void hasStartedProducingAudioData() final; 144 142 145 143 void updateReadyState(); -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp
r259698 r259816 61 61 } 62 62 63 void RealtimeMediaSource::addAudioSampleObserver(RealtimeMediaSource::AudioSampleObserver& observer) 64 { 65 ASSERT(isMainThread()); 66 auto locker = holdLock(m_audioSampleObserversLock); 67 m_audioSampleObservers.add(&observer); 68 } 69 70 void RealtimeMediaSource::removeAudioSampleObserver(RealtimeMediaSource::AudioSampleObserver& observer) 71 { 72 ASSERT(isMainThread()); 73 auto locker = holdLock(m_audioSampleObserversLock); 74 m_audioSampleObservers.remove(&observer); 75 } 76 63 77 void RealtimeMediaSource::addObserver(RealtimeMediaSource::Observer& observer) 64 78 { 65 auto locker = holdLock(m_observersLock);79 ASSERT(isMainThread()); 66 80 m_observers.add(&observer); 67 81 } … … 69 83 void RealtimeMediaSource::removeObserver(RealtimeMediaSource::Observer& observer) 70 84 { 71 auto locker = holdLock(m_observersLock);85 ASSERT(isMainThread()); 72 86 m_observers.remove(&observer); 73 87 if (m_observers.isEmpty()) … … 117 131 } 118 132 119 void RealtimeMediaSource::forEachObserver(const WTF::Function<void(Observer&)>& apply) const 120 { 121 Vector<Observer*> observersCopy; 122 { 123 auto locker = holdLock(m_observersLock); 124 observersCopy = copyToVector(m_observers); 125 } 126 for (auto* observer : observersCopy) { 127 auto locker = holdLock(m_observersLock); 128 // Make sure the observer has not been destroyed. 133 void RealtimeMediaSource::forEachObserver(const Function<void(Observer&)>& apply) const 134 { 135 ASSERT(isMainThread()); 136 for (auto* observer : copyToVector(m_observers)) { 129 137 if (!m_observers.contains(observer)) 130 138 continue; … … 183 191 void RealtimeMediaSource::audioSamplesAvailable(const MediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames) 184 192 { 185 forEachObserver([&](auto& observer) { 186 observer.audioSamplesAvailable(time, audioData, description, numberOfFrames); 187 }); 193 if (!m_hasSentStartProducedAudioData) { 194 callOnMainThread([this, weakThis = makeWeakPtr(this)] { 195 if (!weakThis) 196 return; 197 if (m_hasSentStartProducedAudioData) 198 return; 199 m_hasSentStartProducedAudioData = true; 200 forEachObserver([&](auto& observer) { 201 observer.hasStartedProducingAudioData(); 202 }); 203 }); 204 } 205 206 auto locker = holdLock(m_audioSampleObserversLock); 207 for (auto* observer : m_audioSampleObservers) 208 observer->audioSamplesAvailable(time, audioData, description, numberOfFrames); 188 209 } 189 210 -
trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h
r258504 r259816 70 70 class WEBCORE_EXPORT RealtimeMediaSource 71 71 : public ThreadSafeRefCounted<RealtimeMediaSource, WTF::DestructionThread::MainRunLoop> 72 , public CanMakeWeakPtr<RealtimeMediaSource >72 , public CanMakeWeakPtr<RealtimeMediaSource, WeakPtrFactoryInitialization::Eager> 73 73 #if !RELEASE_LOG_DISABLED 74 74 , protected LoggerHelper … … 93 93 virtual void videoSampleAvailable(MediaSample&) { } 94 94 95 virtual void hasStartedProducingAudioData() { } 96 }; 97 class AudioSampleObserver { 98 public: 99 virtual ~AudioSampleObserver() = default; 100 95 101 // May be called on a background thread. 96 virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t /*numberOfFrames*/) { }102 virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t /*numberOfFrames*/) = 0; 97 103 }; 98 104 … … 131 137 WEBCORE_EXPORT void addObserver(Observer&); 132 138 WEBCORE_EXPORT void removeObserver(Observer&); 139 140 WEBCORE_EXPORT void addAudioSampleObserver(AudioSampleObserver&); 141 WEBCORE_EXPORT void removeAudioSampleObserver(AudioSampleObserver&); 133 142 134 143 const IntSize size() const; … … 254 263 Type m_type; 255 264 String m_name; 256 mutable RecursiveLock m_observersLock;257 265 HashSet<Observer*> m_observers; 266 267 mutable RecursiveLock m_audioSampleObserversLock; 268 HashSet<AudioSampleObserver*> m_audioSampleObservers; 269 258 270 IntSize m_size; 259 271 IntSize m_intrinsicSize; … … 273 285 bool m_captureDidFailed { false }; 274 286 bool m_isEnded { false }; 287 bool m_hasSentStartProducedAudioData { false }; 275 288 }; 276 289 -
trunk/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.cpp
r254087 r259816 46 46 RealtimeOutgoingAudioSource::~RealtimeOutgoingAudioSource() 47 47 { 48 ASSERT(!m_audioSource->hasObserver(*this));48 ASSERT(!m_audioSource->hasObserver(*this)); 49 49 #if ASSERT_ENABLED 50 50 auto locker = holdLock(m_sinksLock); … … 59 59 ASSERT(!m_audioSource->hasObserver(*this)); 60 60 m_audioSource->addObserver(*this); 61 m_audioSource->source().addAudioSampleObserver(*this); 61 62 initializeConverter(); 62 63 } … … 64 65 void RealtimeOutgoingAudioSource::unobserveSource() 65 66 { 67 m_audioSource->source().removeAudioSampleObserver(*this); 66 68 m_audioSource->removeObserver(*this); 67 69 } -
trunk/Source/WebCore/platform/mediastream/RealtimeOutgoingAudioSource.h
r252987 r259816 56 56 , public webrtc::AudioSourceInterface 57 57 , private MediaStreamTrackPrivate::Observer 58 , private RealtimeMediaSource::AudioSampleObserver 58 59 #if !RELEASE_LOG_DISABLED 59 60 , private LoggerHelper … … 109 110 void sourceMutedChanged(); 110 111 void sourceEnabledChanged(); 111 virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) { };112 112 113 113 virtual bool isReachingBufferedAudioDataHighLimit() { return false; }; … … 119 119 void trackMutedChanged(MediaStreamTrackPrivate&) final { sourceMutedChanged(); } 120 120 void trackEnabledChanged(MediaStreamTrackPrivate&) final { sourceEnabledChanged(); } 121 void audioSamplesAvailable(MediaStreamTrackPrivate&, const MediaTime& mediaTime, const PlatformAudioData& data, const AudioStreamDescription& description, size_t sampleCount) { audioSamplesAvailable(mediaTime, data, description, sampleCount); }122 121 void trackEnded(MediaStreamTrackPrivate&) final { } 123 122 void trackSettingsChanged(MediaStreamTrackPrivate&) final { } -
trunk/Source/WebCore/platform/mediastream/WebAudioSourceProvider.h
r218622 r259816 33 33 namespace WebCore { 34 34 35 class WebAudioSourceProvider : public ThreadSafeRefCounted<WebAudioSourceProvider >, public AudioSourceProvider {35 class WebAudioSourceProvider : public ThreadSafeRefCounted<WebAudioSourceProvider, WTF::DestructionThread::Main>, public AudioSourceProvider { 36 36 }; 37 37 -
trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp
r254116 r259816 107 107 108 108 class WebKitMediaStreamTrackObserver 109 : public MediaStreamTrackPrivate::Observer { 109 : public MediaStreamTrackPrivate::Observer 110 , public RealtimeMediaSource::AudioSampleObserver { 110 111 WTF_MAKE_FAST_ALLOCATED; 111 112 public: … … 132 133 } 133 134 134 void audioSamplesAvailable( MediaStreamTrackPrivate&,const MediaTime&, const PlatformAudioData& audioData, const AudioStreamDescription&, size_t) final135 void audioSamplesAvailable(const MediaTime&, const PlatformAudioData& audioData, const AudioStreamDescription&, size_t) final 135 136 { 136 137 auto audiodata = static_cast<const GStreamerAudioData&>(audioData); … … 376 377 GST_OBJECT_LOCK(self); 377 378 if (self->stream) { 378 for (auto& track : self->stream->tracks()) 379 for (auto& track : self->stream->tracks()) { 380 track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 379 381 track->removeObserver(*self->mediaStreamTrackObserver.get()); 380 382 } 381 383 self->stream->removeObserver(*self->mediaStreamObserver); 382 384 self->stream = nullptr; … … 397 399 GST_OBJECT_LOCK(self); 398 400 if (self->stream) { 399 for (auto& track : self->stream->tracks()) 401 for (auto& track : self->stream->tracks()) { 402 track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 400 403 track->removeObserver(*self->mediaStreamTrackObserver.get()); 401 } else if (self->track) 404 } 405 } else if (self->track) { 406 self->track->source().removeAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 402 407 self->track->removeObserver(*self->mediaStreamTrackObserver.get()); 408 } 403 409 GST_OBJECT_UNLOCK(self); 404 410 } … … 544 550 webkitMediaStreamSrcAddPad(self, pad.get(), pad_template); 545 551 546 if (observe_track) 552 if (observe_track) { 547 553 track->addObserver(*self->mediaStreamTrackObserver.get()); 548 554 track->source().addAudioSampleObserver(*self->mediaStreamTrackObserver.get()); 555 } 549 556 gst_element_sync_state_with_parent(element); 550 557 return TRUE; -
trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.h
r239427 r259816 47 47 class CAAudioStreamDescription; 48 48 49 class WEBCORE_EXPORT WebAudioSourceProviderAVFObjC final : public WebAudioSourceProvider, MediaStreamTrackPrivate::Observer { 49 class WEBCORE_EXPORT WebAudioSourceProviderAVFObjC final 50 : public WebAudioSourceProvider 51 , MediaStreamTrackPrivate::Observer 52 , RealtimeMediaSource::AudioSampleObserver { 50 53 public: 51 54 static Ref<WebAudioSourceProviderAVFObjC> create(MediaStreamTrackPrivate&); … … 63 66 64 67 // MediaStreamTrackPrivate::Observer 65 void audioSamplesAvailable(MediaStreamTrackPrivate&, const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final;66 68 void trackEnded(MediaStreamTrackPrivate&) final { } 67 69 void trackMutedChanged(MediaStreamTrackPrivate&) final { } 68 70 void trackSettingsChanged(MediaStreamTrackPrivate&) final { } 69 void trackEnabledChanged(MediaStreamTrackPrivate&) final { } 71 void trackEnabledChanged(MediaStreamTrackPrivate&) final; 72 73 // RealtimeMediaSource::AudioSampleObserver 74 void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final; 70 75 71 76 size_t m_listBufferSize { 0 }; … … 78 83 AudioSourceProviderClient* m_client { nullptr }; 79 84 MediaStreamTrackPrivate* m_captureSource { nullptr }; 85 Ref<RealtimeMediaSource> m_source; 80 86 Lock m_mutex; 81 87 bool m_connected { false }; 88 bool m_enabled { true }; 82 89 }; 83 90 -
trunk/Source/WebCore/platform/mediastream/mac/WebAudioSourceProviderAVFObjC.mm
r257688 r259816 55 55 WebAudioSourceProviderAVFObjC::WebAudioSourceProviderAVFObjC(MediaStreamTrackPrivate& source) 56 56 : m_captureSource(&source) 57 , m_source(source.source()) 58 , m_enabled(source.enabled()) 57 59 { 60 m_source->addAudioSampleObserver(*this); 58 61 } 59 62 60 63 WebAudioSourceProviderAVFObjC::~WebAudioSourceProviderAVFObjC() 61 64 { 65 m_source->removeAudioSampleObserver(*this); 66 62 67 auto locker = holdLock(m_mutex); 63 68 … … 166 171 } 167 172 173 void WebAudioSourceProviderAVFObjC::trackEnabledChanged(MediaStreamTrackPrivate& track) 174 { 175 m_enabled = track.enabled(); 176 } 177 168 178 // May get called on a background thread. 169 void WebAudioSourceProviderAVFObjC::audioSamplesAvailable( MediaStreamTrackPrivate& track,const MediaTime&, const PlatformAudioData& data, const AudioStreamDescription& description, size_t frameCount)179 void WebAudioSourceProviderAVFObjC::audioSamplesAvailable(const MediaTime&, const PlatformAudioData& data, const AudioStreamDescription& description, size_t frameCount) 170 180 { 171 if (! track.enabled())181 if (!m_enabled || !m_connected) 172 182 return; 173 183 -
trunk/Source/WebCore/testing/Internals.cpp
r259752 r259816 467 467 { 468 468 #if ENABLE(MEDIA_STREAM) 469 if (m_track) 470 m_track->source().removeObserver(*this); 469 if (m_trackSource) { 470 m_trackSource->removeObserver(*this); 471 m_trackSource->removeAudioSampleObserver(*this); 472 } 471 473 #endif 472 474 } … … 1640 1642 } 1641 1643 1642 static std::unique_ptr<MediaRecorderPrivate> createRecorderMockSource( )1643 { 1644 return std::unique_ptr<MediaRecorderPrivateMock>(new MediaRecorderPrivateMock );1644 static std::unique_ptr<MediaRecorderPrivate> createRecorderMockSource(MediaStreamPrivate& stream) 1645 { 1646 return std::unique_ptr<MediaRecorderPrivateMock>(new MediaRecorderPrivateMock(stream)); 1645 1647 } 1646 1648 … … 4926 4928 void Internals::observeMediaStreamTrack(MediaStreamTrack& track) 4927 4929 { 4928 m_track = &track; 4929 m_track->source().addObserver(*this); 4930 m_trackSource = &track.source(); 4931 m_trackSource->addObserver(*this); 4932 m_trackSource->addAudioSampleObserver(*this); 4930 4933 } 4931 4934 … … 4941 4944 return; 4942 4945 4943 auto& videoSettings = m_track ->source().settings();4946 auto& videoSettings = m_trackSource->settings(); 4944 4947 if (!videoSettings.width() || !videoSettings.height()) 4945 4948 return; -
trunk/Source/WebCore/testing/Internals.h
r259575 r259816 124 124 #if ENABLE(MEDIA_STREAM) 125 125 , private RealtimeMediaSource::Observer 126 , private RealtimeMediaSource::AudioSampleObserver 126 127 #endif 127 128 { … … 970 971 ExceptionOr<RenderedDocumentMarker*> markerAt(Node&, const String& markerType, unsigned index); 971 972 973 #if ENABLE(MEDIA_STREAM) 972 974 // RealtimeMediaSource::Observer API 973 #if ENABLE(MEDIA_STREAM)974 975 void videoSampleAvailable(MediaSample&) final; 976 // RealtimeMediaSource::AudioSampleObserver API 975 977 void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t) final { m_trackAudioSampleCount++; } 976 978 … … 978 980 unsigned long m_trackVideoSampleCount { 0 }; 979 981 unsigned long m_trackAudioSampleCount { 0 }; 980 RefPtr< MediaStreamTrack> m_track;982 RefPtr<RealtimeMediaSource> m_trackSource; 981 983 std::unique_ptr<TrackFramePromise> m_nextTrackFramePromise; 982 984 #endif -
trunk/Source/WebKit/ChangeLog
r259814 r259816 1 2020-04-09 Youenn Fablet <youenn@apple.com> 2 3 Introduce a RealtimeMediaSource observer dedicated to receiving audio samples 4 https://bugs.webkit.org/show_bug.cgi?id=210180 5 6 Reviewed by Eric Carlson. 7 8 Update SourceProxy to be an AudioSampleObserver. 9 Update MediaRecorder to only listen for audio samples if GPU remote writer is successfully created. 10 It also stops listening to audio samples as soon as stopping the recording. 11 12 * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp: 13 (WebKit::UserMediaCaptureManagerProxy::SourceProxy::SourceProxy): 14 (WebKit::UserMediaCaptureManagerProxy::SourceProxy::~SourceProxy): 15 * WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp: 16 (WebKit::MediaRecorderPrivate::MediaRecorderPrivate): 17 (WebKit::MediaRecorderPrivate::~MediaRecorderPrivate): 18 (WebKit::MediaRecorderPrivate::audioSamplesAvailable): 19 (WebKit::MediaRecorderPrivate::stopRecording): 20 * WebProcess/GPU/webrtc/MediaRecorderPrivate.h: 21 * WebProcess/GPU/webrtc/MediaRecorderProvider.cpp: 22 (WebKit::MediaRecorderProvider::createMediaRecorderPrivate): 23 * WebProcess/GPU/webrtc/MediaRecorderProvider.h: 24 1 25 2020-04-09 David Kilzer <ddkilzer@apple.com> 2 26 -
trunk/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp
r259775 r259816 51 51 class UserMediaCaptureManagerProxy::SourceProxy 52 52 : public RealtimeMediaSource::Observer 53 , public RealtimeMediaSource::AudioSampleObserver 53 54 , public SharedRingBufferStorage::Client { 54 55 WTF_MAKE_FAST_ALLOCATED; … … 61 62 { 62 63 m_source->addObserver(*this); 64 m_source->addAudioSampleObserver(*this); 63 65 } 64 66 … … 66 68 { 67 69 storage().invalidate(); 70 m_source->removeAudioSampleObserver(*this); 68 71 m_source->removeObserver(*this); 69 72 } -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.cpp
r257606 r259816 44 44 using namespace WebCore; 45 45 46 MediaRecorderPrivate::MediaRecorderPrivate( constMediaStreamPrivate& stream)46 MediaRecorderPrivate::MediaRecorderPrivate(MediaStreamPrivate& stream) 47 47 : m_identifier(MediaRecorderIdentifier::generate()) 48 48 , m_connection(WebProcess::singleton().ensureGPUProcessConnection().connection()) … … 65 65 } 66 66 67 m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, width, height }, [this, weakThis = makeWeakPtr(this) ](auto&& exception) {68 if (!weakThis || !exception)67 m_connection->sendWithAsyncReply(Messages::RemoteMediaRecorderManager::CreateRecorder { m_identifier, !!selectedTracks.audioTrack, width, height }, [this, weakThis = makeWeakPtr(this), audioTrack = makeRefPtr(selectedTracks.audioTrack)](auto&& exception) { 68 if (!weakThis) 69 69 return; 70 m_errorCallback(Exception { exception->code, WTFMove(exception->message) }); 70 if (exception) 71 return m_errorCallback(Exception { exception->code, WTFMove(exception->message) }); 72 if (audioTrack) 73 setAudioSource(&audioTrack->source()); 71 74 }, 0); 72 75 } … … 74 77 MediaRecorderPrivate::~MediaRecorderPrivate() 75 78 { 79 setAudioSource(nullptr); 76 80 m_connection->send(Messages::RemoteMediaRecorderManager::ReleaseRecorder { m_identifier }, 0); 77 81 } … … 89 93 } 90 94 91 void MediaRecorderPrivate::audioSamplesAvailable(const WebCore::MediaStreamTrackPrivate& track, constMediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames)95 void MediaRecorderPrivate::audioSamplesAvailable(const MediaTime& time, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t numberOfFrames) 92 96 { 93 if (track.id() != m_recordedAudioTrackID)94 return;95 96 97 if (m_description != description) { 97 98 ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType); … … 131 132 void MediaRecorderPrivate::stopRecording() 132 133 { 134 setAudioSource(nullptr); 133 135 m_connection->send(Messages::RemoteMediaRecorder::StopRecording { }, m_identifier); 134 136 } -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderPrivate.h
r256493 r259816 45 45 namespace WebKit { 46 46 47 class MediaRecorderPrivate final : public WebCore::MediaRecorderPrivate, public SharedRingBufferStorage::Client, public CanMakeWeakPtr<MediaRecorderPrivate> { 47 class MediaRecorderPrivate final 48 : public WebCore::MediaRecorderPrivate 49 , public SharedRingBufferStorage::Client 50 , public CanMakeWeakPtr<MediaRecorderPrivate> { 48 51 WTF_MAKE_FAST_ALLOCATED; 49 52 public: 50 explicit MediaRecorderPrivate( constWebCore::MediaStreamPrivate&);53 explicit MediaRecorderPrivate(WebCore::MediaStreamPrivate&); 51 54 ~MediaRecorderPrivate(); 52 55 … … 54 57 // WebCore::MediaRecorderPrivate 55 58 void sampleBufferUpdated(const WebCore::MediaStreamTrackPrivate&, WebCore::MediaSample&) final; 56 void audioSamplesAvailable(const WebCore::MediaStreamTrackPrivate&, const WTF::MediaTime&, const WebCore::PlatformAudioData&, const WebCore::AudioStreamDescription&, size_t) final;57 59 void fetchData(CompletionHandler<void(RefPtr<WebCore::SharedBuffer>&&, const String& mimeType)>&&) final; 58 60 void stopRecording() final; 61 void audioSamplesAvailable(const WTF::MediaTime&, const WebCore::PlatformAudioData&, const WebCore::AudioStreamDescription&, size_t) final; 59 62 60 63 // SharedRingBufferStorage::Client -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.cpp
r257542 r259816 35 35 using namespace WebCore; 36 36 37 std::unique_ptr<WebCore::MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate( constMediaStreamPrivate& stream)37 std::unique_ptr<WebCore::MediaRecorderPrivate> MediaRecorderProvider::createMediaRecorderPrivate(MediaStreamPrivate& stream) 38 38 { 39 39 #if ENABLE(GPU_PROCESS) -
trunk/Source/WebKit/WebProcess/GPU/webrtc/MediaRecorderProvider.h
r254194 r259816 36 36 private: 37 37 #if ENABLE(MEDIA_STREAM) && PLATFORM(COCOA) 38 std::unique_ptr<WebCore::MediaRecorderPrivate> createMediaRecorderPrivate( constWebCore::MediaStreamPrivate&) final;38 std::unique_ptr<WebCore::MediaRecorderPrivate> createMediaRecorderPrivate(WebCore::MediaStreamPrivate&) final; 39 39 #endif 40 40 };
Note:
See TracChangeset
for help on using the changeset viewer.